Pulled serialized bean browser out of defunct clazz module. Now available in Services tab.
authorJesse Glick <jglick@netbeans.org>
Fri, 17 Sep 2010 18:36:33 -0400
changeset 16379dc1e33f80199
parent 16378 63fab4918bb9
child 16380 9731dbe287cd
Pulled serialized bean browser out of defunct clazz module. Now available in Services tab.
apisupport.beanbrowser/manifest.mf
apisupport.beanbrowser/nbproject/project.properties
apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/Bundle.properties
apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/SerParser.java
apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/SerStructureNode.java
apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/SerialBrowserTopNode.java
apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/ser.gif
apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/serAlone.gif
     1.1 --- a/apisupport.beanbrowser/manifest.mf	Fri Sep 17 17:10:30 2010 -0400
     1.2 +++ b/apisupport.beanbrowser/manifest.mf	Fri Sep 17 18:36:33 2010 -0400
     1.3 @@ -3,5 +3,5 @@
     1.4  OpenIDE-Module-Layer: org/netbeans/modules/apisupport/beanbrowser/layer.xml
     1.5  OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/apisupport/beanbrowser/Bundle.properties
     1.6  OpenIDE-Module-Requires: org.netbeans.api.javahelp.Help
     1.7 -OpenIDE-Module-Specification-Version: 1.8
     1.8 +OpenIDE-Module-Specification-Version: 1.9
     1.9  
     2.1 --- a/apisupport.beanbrowser/nbproject/project.properties	Fri Sep 17 17:10:30 2010 -0400
     2.2 +++ b/apisupport.beanbrowser/nbproject/project.properties	Fri Sep 17 18:36:33 2010 -0400
     2.3 @@ -1,3 +1,3 @@
     2.4  javac.compilerargs=-Xlint -Xlint:-serial
     2.5 -javac.source=1.5
     2.6 +javac.source=1.6
     2.7  javahelp.hs=beanbrowser-hs.xml
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/Bundle.properties	Fri Sep 17 18:36:33 2010 -0400
     3.3 @@ -0,0 +1,44 @@
     3.4 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.5 +#
     3.6 +# Copyright 2010 Oracle and/or its affiliates. All rights reserved.
     3.7 +#
     3.8 +# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     3.9 +# Other names may be trademarks of their respective owners.
    3.10 +#
    3.11 +# The contents of this file are subject to the terms of either the GNU
    3.12 +# General Public License Version 2 only ("GPL") or the Common
    3.13 +# Development and Distribution License("CDDL") (collectively, the
    3.14 +# "License"). You may not use this file except in compliance with the
    3.15 +# License. You can obtain a copy of the License at
    3.16 +# http://www.netbeans.org/cddl-gplv2.html
    3.17 +# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.18 +# specific language governing permissions and limitations under the
    3.19 +# License.  When distributing the software, include this License Header
    3.20 +# Notice in each file and include the License file at
    3.21 +# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    3.22 +# particular file as subject to the "Classpath" exception as provided
    3.23 +# by Oracle in the GPL Version 2 section of the License file that
    3.24 +# accompanied this code. If applicable, add the following below the
    3.25 +# License Header, with the fields enclosed by brackets [] replaced by
    3.26 +# your own identifying information:
    3.27 +# "Portions Copyrighted [year] [name of copyright owner]"
    3.28 +#
    3.29 +# If you wish your version of this file to be governed by only the CDDL
    3.30 +# or only the GPL Version 2, indicate your decision by adding
    3.31 +# "[Contributor] elects to include this software in this distribution
    3.32 +# under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.33 +# single choice of license, a recipient has the option to distribute
    3.34 +# your version of this file under either the CDDL, the GPL Version 2 or
    3.35 +# to extend the choice of license to its licensees as provided above.
    3.36 +# However, if you add GPL Version 2 code and therefore, elected the GPL
    3.37 +# Version 2 license, then the option applies only if the new code is
    3.38 +# made subject to such option by the copyright holder.
    3.39 +#
    3.40 +# Contributor(s):
    3.41 +#
    3.42 +# Portions Copyrighted 2010 Sun Microsystems, Inc.
    3.43 +
    3.44 +# SerStructureNode
    3.45 +LBL_ser_stream=Serialized stream
    3.46 +# {0} - class name
    3.47 +LBL_instance_of=instance of {0}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/SerParser.java	Fri Sep 17 18:36:33 2010 -0400
     4.3 @@ -0,0 +1,576 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     4.8 + *
     4.9 + * The contents of this file are subject to the terms of either the GNU
    4.10 + * General Public License Version 2 only ("GPL") or the Common
    4.11 + * Development and Distribution License("CDDL") (collectively, the
    4.12 + * "License"). You may not use this file except in compliance with the
    4.13 + * License. You can obtain a copy of the License at
    4.14 + * http://www.netbeans.org/cddl-gplv2.html
    4.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.16 + * specific language governing permissions and limitations under the
    4.17 + * License.  When distributing the software, include this License Header
    4.18 + * Notice in each file and include the License file at
    4.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    4.20 + * particular file as subject to the "Classpath" exception as provided
    4.21 + * by Sun in the GPL Version 2 section of the License file that
    4.22 + * accompanied this code. If applicable, add the following below the
    4.23 + * License Header, with the fields enclosed by brackets [] replaced by
    4.24 + * your own identifying information:
    4.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    4.26 + *
    4.27 + * Contributor(s):
    4.28 + *
    4.29 + * The Original Software is NetBeans. The Initial Developer of the Original
    4.30 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
    4.31 + * Microsystems, Inc. All Rights Reserved.
    4.32 + *
    4.33 + * If you wish your version of this file to be governed by only the CDDL
    4.34 + * or only the GPL Version 2, indicate your decision by adding
    4.35 + * "[Contributor] elects to include this software in this distribution
    4.36 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.37 + * single choice of license, a recipient has the option to distribute
    4.38 + * your version of this file under either the CDDL, the GPL Version 2 or
    4.39 + * to extend the choice of license to its licensees as provided above.
    4.40 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    4.41 + * Version 2 license, then the option applies only if the new code is
    4.42 + * made subject to such option by the copyright holder.
    4.43 + */
    4.44 +
    4.45 +package org.netbeans.modules.apisupport.beanbrowser.ser;
    4.46 +
    4.47 +import java.io.*;
    4.48 +import java.util.*;
    4.49 +import org.openide.util.NotImplementedException;
    4.50 +
    4.51 +/** Parser for Java serialization files.
    4.52 + * Does no classloading or per-class semantics, simply parses the
    4.53 + * raw serialization structure.
    4.54 + * @author Jesse Glick
    4.55 + */
    4.56 +public final class SerParser implements ObjectStreamConstants {
    4.57 +    
    4.58 +    private static final boolean DEBUG = Boolean.getBoolean("org.netbeans.modules.clazz.SerParser.DEBUG"); // NOI18N
    4.59 +    
    4.60 +    private final InputStream is;
    4.61 +    private int seq = 0;
    4.62 +    private final List refs = new ArrayList(100); // List<Object>
    4.63 +    
    4.64 +    public SerParser(InputStream is) {
    4.65 +        this.is = is;
    4.66 +    }
    4.67 +    
    4.68 +    private int makeRef(Object o) {
    4.69 +        refs.add(o);
    4.70 +        int i = seq;
    4.71 +        seq++;
    4.72 +        if (DEBUG) System.err.println("makeRef[" + i + "]=" + o); // NOI18N
    4.73 +        return i;
    4.74 +    }
    4.75 +    
    4.76 +    private Object getRef(int i) throws CorruptException {
    4.77 +        int idx = i - baseWireHandle;
    4.78 +        if (idx < 0 || idx >= seq) throw new CorruptException("Invalid reference: " + i); // NOI18N
    4.79 +        Object o = refs.get(idx);
    4.80 +        if (o == null) throw new CorruptException("Invalid reference: " + i); // NOI18N
    4.81 +        return o;
    4.82 +    }
    4.83 +    
    4.84 +    public Stream parse(String label) throws IOException, CorruptException {
    4.85 +        Stream s = new Stream(label);
    4.86 +        s.magic = readShort();
    4.87 +        s.version = readShort();
    4.88 +        if (s.magic != STREAM_MAGIC || s.version != STREAM_VERSION) {
    4.89 +           throw new CorruptException("stream version mismatch: " + hexify(s.magic) + " != " + hexify(STREAM_MAGIC) + " or " + hexify(s.version) + " != " +  hexify(STREAM_VERSION)); // NOI18N
    4.90 +        }
    4.91 +        s.contents = new ArrayList(10);
    4.92 +        while (peek() != -1) {
    4.93 +            s.contents.add(readContent());
    4.94 +        }
    4.95 +        if (DEBUG) System.err.println("parsed: " + s); // NOI18N
    4.96 +        return s;
    4.97 +    }
    4.98 +    
    4.99 +    public static final class CorruptException extends IOException {
   4.100 +        public CorruptException() {
   4.101 +        }
   4.102 +        public CorruptException(String m) {
   4.103 +            super(m);
   4.104 +        }
   4.105 +    }
   4.106 +    
   4.107 +    private int pushback = -1;
   4.108 +    private int rb() throws IOException {
   4.109 +        if (pushback != -1) {
   4.110 +            int c = pushback;
   4.111 +            pushback = -1;
   4.112 +            return c;
   4.113 +        }
   4.114 +        int c = is.read();
   4.115 +        if (DEBUG) System.err.println("read: " + Integer.toHexString(c)); // NOI18N
   4.116 +        if (c == -1) {
   4.117 +            throw new EOFException();
   4.118 +        } else {
   4.119 +            return c;
   4.120 +        }
   4.121 +    }
   4.122 +    private int peek() throws IOException {
   4.123 +        if (pushback != -1) throw new IllegalStateException("can only peek once"); // NOI18N
   4.124 +        pushback = is.read();
   4.125 +        if (DEBUG) System.err.println("read: " + Integer.toHexString(pushback)); // NOI18N
   4.126 +        return pushback;
   4.127 +    }
   4.128 +    
   4.129 +    static String hexify(byte b) {
   4.130 +        int i = b;
   4.131 +        if (i < 0) i += 256;
   4.132 +        String s = Integer.toHexString(i).toUpperCase(Locale.US);
   4.133 +        return "0x" + pad(s, 2); // NOI18N
   4.134 +    }
   4.135 +    static String hexify(short s) {
   4.136 +        int i = s;
   4.137 +        if (i < 0) i += 65536;
   4.138 +        String st = Integer.toHexString(i).toUpperCase(Locale.US);
   4.139 +        return "0x" + pad(st, 4); // NOI18N
   4.140 +    }
   4.141 +    static String hexify(int i) {
   4.142 +        String s = Integer.toHexString(i).toUpperCase(Locale.US);
   4.143 +        return "0x" + pad(s, 4); // NOI18N
   4.144 +    }
   4.145 +    static String hexify(long l) {
   4.146 +        String s1 = Integer.toHexString((int)((l & 0xFFFFFFFF00000000L) << 32)).toUpperCase(Locale.US);
   4.147 +        String s2 = Integer.toHexString((int)(l & 0x00000000FFFFFFFFL)).toUpperCase(Locale.US);
   4.148 +        return "0x" + pad(s1, 4) + pad(s2, 4); // NOI18N
   4.149 +    }
   4.150 +    static String hexify(byte[] b) {
   4.151 +        StringBuffer buf = new StringBuffer(2 + b.length * 2);
   4.152 +        buf.append("0x"); // NOI18N
   4.153 +        for (int i = 0; i < b.length; i++) {
   4.154 +            int x = b[i];
   4.155 +            if (x < 0) x += 256;
   4.156 +            buf.append(pad(Integer.toHexString(x).toUpperCase(Locale.US), 2));
   4.157 +        }
   4.158 +        return buf.toString();
   4.159 +    }
   4.160 +    private static String pad(String s, int size) {
   4.161 +        int i = s.length();
   4.162 +        if (i == size) {
   4.163 +            return s;
   4.164 +        } else {
   4.165 +            StringBuffer b = new StringBuffer(size);
   4.166 +            for (int k = 0; k < size - i; k++) {
   4.167 +                b.append('0'); // NOI18N
   4.168 +            }
   4.169 +            b.append(s);
   4.170 +            return b.toString();
   4.171 +        }
   4.172 +    }
   4.173 +    
   4.174 +    private long readLong() throws IOException {
   4.175 +        long x1 = rb();
   4.176 +        long x2 = rb();
   4.177 +        long x3 = rb();
   4.178 +        long x4 = rb();
   4.179 +        long x5 = rb();
   4.180 +        long x6 = rb();
   4.181 +        long x7 = rb();
   4.182 +        long x8 = rb();
   4.183 +        long l = (x1 << 56) + (x2 << 48) + (x3 << 40) + (x4 << 32) + (x5 << 24) + (x6 << 16) + (x7 << 8) + x8;
   4.184 +        if (DEBUG) System.err.println("readLong: " + l); // NOI18N
   4.185 +        return l;
   4.186 +    }
   4.187 +    
   4.188 +    private int readInt() throws IOException {
   4.189 +        int x1 = rb();
   4.190 +        int x2 = rb();
   4.191 +        int x3 = rb();
   4.192 +        int x4 = rb();
   4.193 +        int i = (x1 << 24) + (x2 << 16) + (x3 << 8) + x4;
   4.194 +        if (DEBUG) System.err.println("readInt: " + i); // NOI18N
   4.195 +        return i;
   4.196 +    }
   4.197 +    
   4.198 +    private short readShort() throws IOException {
   4.199 +        int x1 = rb();
   4.200 +        int x2 = rb();
   4.201 +        short s = (short)((x1 << 8) + x2);
   4.202 +        //System.err.println("x1=" + hexify(x1) + " x2=" + hexify(x2) + " s=" + hexify(s));
   4.203 +        //if (DEBUG) System.err.println("x1=" + x1 + " x2=" + x2 + " s=" + s);
   4.204 +        if (DEBUG) System.err.println("readShort: " + s); // NOI18N
   4.205 +        return s;
   4.206 +    }
   4.207 +    
   4.208 +    private byte readByte() throws IOException {
   4.209 +        return (byte)rb();
   4.210 +    }
   4.211 +    
   4.212 +    private String readUTF() throws IOException {
   4.213 +        short len = readShort();
   4.214 +        if (len < 0) throw new NotImplementedException();//XXX
   4.215 +        byte[] buf = new byte[len];
   4.216 +        for (int i = 0; i < len; i++) {
   4.217 +            buf[i] = readByte();
   4.218 +        }
   4.219 +        String s = new String(buf, "UTF-8"); // NOI18N
   4.220 +        if (DEBUG) System.err.println("readUTF: " + s); // NOI18N
   4.221 +        return s;
   4.222 +    }
   4.223 +    
   4.224 +    private String readLongUTF() throws IOException {
   4.225 +        long len = readLong();
   4.226 +        if (len < 0) throw new NotImplementedException();//XXX
   4.227 +        if (len > Integer.MAX_VALUE) throw new NotImplementedException();// XXX
   4.228 +        int ilen = (int)len;
   4.229 +        byte[] buf = new byte[ilen];
   4.230 +        for (int i = 0; i < ilen; i++) {
   4.231 +            buf[i] = readByte();
   4.232 +        }
   4.233 +        String s = new String(buf, "UTF-8"); // NOI18N
   4.234 +        if (DEBUG) System.err.println("readUTF: " + s); // NOI18N
   4.235 +        return s;
   4.236 +    }
   4.237 +    
   4.238 +    // See "Rules of the Grammar" in Java Object Serialization Specification
   4.239 +    // for explanation of all these objects.
   4.240 +    
   4.241 +    public static final class Stream /*extends Thing*/ {
   4.242 +        final String label;
   4.243 +        public Stream(String label) {
   4.244 +            this.label = label;
   4.245 +        }
   4.246 +        public short magic;
   4.247 +        public short version;
   4.248 +        public List contents; // List<Object>
   4.249 +
   4.250 +        public String toString() {
   4.251 +            return "Stream[" + label + ":" + contents + "]"; // NOI18N
   4.252 +        }
   4.253 +    }
   4.254 +    
   4.255 +    public static final Object NULL = "null"; // NOI18N
   4.256 +    
   4.257 +    private Object readContent() throws IOException {
   4.258 +        byte tc = readByte();
   4.259 +        switch (tc) {
   4.260 +        case TC_OBJECT:
   4.261 +            return readNewObject();
   4.262 +        case TC_CLASS:
   4.263 +            return readNewClass();
   4.264 +        case TC_ARRAY:
   4.265 +            return readNewArray();
   4.266 +        case TC_CLASSDESC:
   4.267 +            return readNewClassDesc();
   4.268 +        case TC_PROXYCLASSDESC:
   4.269 +            // XXX too complicated:
   4.270 +            throw new NotImplementedException("TC_PROXYCLASSDESC"); // NOI18N
   4.271 +            //return readNewProxyClassDesc();
   4.272 +        case TC_STRING:
   4.273 +            return readNewString();
   4.274 +        case TC_LONGSTRING:
   4.275 +            // XXX later
   4.276 +            throw new NotImplementedException("TC_LONGSTRING"); // NOI18N
   4.277 +            //return readNewLongString();
   4.278 +        case TC_REFERENCE:
   4.279 +            return readReference();
   4.280 +        case TC_NULL:
   4.281 +            return NULL;
   4.282 +        case TC_EXCEPTION:
   4.283 +            // XXX what is this??
   4.284 +            throw new NotImplementedException("TC_EXCEPTION"); // NOI18N
   4.285 +        case TC_RESET:
   4.286 +            // XXX what is this??
   4.287 +            throw new NotImplementedException("TC_RESET"); // NOI18N
   4.288 +        case TC_BLOCKDATA:
   4.289 +            return readBlockData();
   4.290 +        case TC_BLOCKDATALONG:
   4.291 +            return readBlockDataLong();
   4.292 +        default:
   4.293 +            throw new CorruptException("Unknown typecode: " + hexify(tc)); // NOI18N
   4.294 +        }
   4.295 +    }
   4.296 +    
   4.297 +    public static final class ObjectWrapper {
   4.298 +        public ClassDesc classdesc;
   4.299 +        public List data; // List<NameValue|Object>
   4.300 +        public String toString() {
   4.301 +            return "Object[class=" + classdesc.name + ",data=" + data + "]"; // NOI18N
   4.302 +        }
   4.303 +    }
   4.304 +    
   4.305 +    public static final class NameValue {
   4.306 +        public NameValue(FieldDesc name, Object value) {
   4.307 +            this.name = name;
   4.308 +            this.value = value;
   4.309 +        }
   4.310 +        public final FieldDesc name;
   4.311 +        public final Object value;
   4.312 +        public String toString() {
   4.313 +            return name.toString() + "=" + value.toString(); // NOI18N
   4.314 +        }
   4.315 +    }
   4.316 +    
   4.317 +    public static final class ClassDesc {
   4.318 +        public String name;
   4.319 +        public long svuid;
   4.320 +        public boolean writeMethod;
   4.321 +        public boolean blockData;
   4.322 +        public boolean serializable;
   4.323 +        public boolean externalizable;
   4.324 +        public List fields; // List<FieldDesc>
   4.325 +        public List annotation; // List<Object>
   4.326 +        public ClassDesc superclass;
   4.327 +        public String toString() {
   4.328 +            return "Class[name=" + name + "]"; // NOI18N
   4.329 +        }
   4.330 +    }
   4.331 +    
   4.332 +    private ObjectWrapper readNewObject() throws IOException {
   4.333 +        ObjectWrapper ow = new ObjectWrapper();
   4.334 +        ow.classdesc = readClassDesc();
   4.335 +        makeRef(ow);
   4.336 +        ow.data = new ArrayList (10);
   4.337 +        LinkedList hier = new LinkedList();
   4.338 +        for (ClassDesc cd = ow.classdesc; cd != null; cd = cd.superclass) {
   4.339 +            hier.addFirst(cd);
   4.340 +        }
   4.341 +        Iterator it = hier.iterator();
   4.342 +        while (it.hasNext()) {
   4.343 +            ClassDesc cd = (ClassDesc)it.next();
   4.344 +            if (cd.serializable) {
   4.345 +                ow.data.addAll(readNoWrClass(cd));
   4.346 +                if (cd.writeMethod) {
   4.347 +                    ow.data.addAll(readContents());
   4.348 +                }
   4.349 +            } else {
   4.350 +                if (cd.blockData) {
   4.351 +                    ow.data.addAll(readContents());
   4.352 +                } else {
   4.353 +                    // Old externalization. If this is not object content,
   4.354 +                    // the stream could now become corrupted. Oh well.
   4.355 +                    ow.data.add(readContent());
   4.356 +                }
   4.357 +            }
   4.358 +        }
   4.359 +        if (DEBUG) System.err.println("readNewObject: " + ow); // NOI18N
   4.360 +        return ow;
   4.361 +    }
   4.362 +    
   4.363 +    private ClassDesc readClassDesc() throws IOException {
   4.364 +        Object o = readContent();
   4.365 +        if (o instanceof ClassDesc) {
   4.366 +            return (ClassDesc)o;
   4.367 +        } else if (o == NULL) {
   4.368 +            return null;
   4.369 +        } else {
   4.370 +            throw new CorruptException("Expected class desc, got: " + o); // NOI18N
   4.371 +        }
   4.372 +    }
   4.373 +    
   4.374 +    private ClassDesc readNewClass() throws IOException {
   4.375 +        ClassDesc cd = readClassDesc();
   4.376 +        makeRef(cd);
   4.377 +        return cd;
   4.378 +    }
   4.379 +    
   4.380 +    private ClassDesc readNewClassDesc() throws IOException {
   4.381 +        ClassDesc cd = new ClassDesc();
   4.382 +        cd.name = readUTF();
   4.383 +        if (! cd.name.startsWith("[") && // NOI18N
   4.384 +                ! (cd.name.length() == 1 && "BSIJFDCZ".indexOf(cd.name) != -1) && // NOI18N
   4.385 +                ! cd.name.endsWith(";")) { // NOI18N
   4.386 +            // Canonicalize. It seems class names read normally need this; those
   4.387 +            // read as part of an array do not. ??
   4.388 +            cd.name = "L" + cd.name + ";"; // NOI18N
   4.389 +        }
   4.390 +        cd.svuid = readLong();
   4.391 +        makeRef(cd);
   4.392 +        byte cdf = readByte();
   4.393 +        cd.writeMethod = (cdf & SC_WRITE_METHOD) != 0;
   4.394 +        cd.blockData = (cdf & SC_BLOCK_DATA) != 0;
   4.395 +        cd.serializable = (cdf & SC_SERIALIZABLE) != 0;
   4.396 +        cd.externalizable = (cdf & SC_EXTERNALIZABLE) != 0;
   4.397 +        short count = readShort();
   4.398 +        cd.fields = new ArrayList(count);
   4.399 +        for (int i = 0; i < count; i++) {
   4.400 +            cd.fields.add(readFieldDesc());
   4.401 +        }
   4.402 +        cd.annotation = readContents();
   4.403 +        cd.superclass = readClassDesc();
   4.404 +        if (DEBUG) System.err.println("readNewClassDesc: " + cd); // NOI18N
   4.405 +        return cd;
   4.406 +    }
   4.407 +    
   4.408 +    public static class FieldDesc {
   4.409 +        public String name;
   4.410 +        public String type;
   4.411 +        public String toString() {
   4.412 +            return "Field[name=" + name + ",type=" + type + "]"; // NOI18N
   4.413 +        }
   4.414 +    }
   4.415 +    public static final class ObjFieldDesc extends FieldDesc {
   4.416 +        public boolean array;
   4.417 +        public String toString() {
   4.418 +            return "Field[name=" + name + ",type=" + type + (array ? "[]" : "") + "]"; // NOI18N
   4.419 +        }
   4.420 +    }
   4.421 +    
   4.422 +    private FieldDesc readFieldDesc() throws IOException {
   4.423 +        char tc = (char)readByte();
   4.424 +        FieldDesc fd;
   4.425 +        switch (tc) {
   4.426 +        case 'B':
   4.427 +        case 'C':
   4.428 +        case 'D':
   4.429 +        case 'F':
   4.430 +        case 'I':
   4.431 +        case 'J':
   4.432 +        case 'S':
   4.433 +        case 'Z':
   4.434 +            fd = new FieldDesc();
   4.435 +            fd.type = new String(new char[] {tc});
   4.436 +            break;
   4.437 +        case '[':
   4.438 +            fd = new ObjFieldDesc();
   4.439 +            ((ObjFieldDesc)fd).array = true;
   4.440 +            break;
   4.441 +        case 'L':
   4.442 +            fd = new ObjFieldDesc();
   4.443 +            ((ObjFieldDesc)fd).array = false;
   4.444 +            break;
   4.445 +        default:
   4.446 +            throw new CorruptException("Strange field type: " + tc); // NOI18N
   4.447 +        }
   4.448 +        fd.name = readUTF();
   4.449 +        if (fd instanceof ObjFieldDesc) {
   4.450 +            String clazz = (String)readContent();
   4.451 +            /*
   4.452 +            if (((ObjFieldDesc)fd).array) {
   4.453 +                if (! clazz.startsWith("[")) throw new CorruptException("Field type: " + clazz); // NOI18N
   4.454 +                clazz = clazz.substring(1, clazz.length());
   4.455 +            }
   4.456 +            if (! (clazz.startsWith("L") && clazz.endsWith(";"))) throw new CorruptException("Field type: " + clazz); // NOI18N
   4.457 +            fd.type = clazz.substring(1, clazz.length() - 1).replace('/', '.'); // NOI18N
   4.458 +             */
   4.459 +            fd.type = clazz;
   4.460 +        }
   4.461 +        if (DEBUG) System.err.println("readFieldDesc: " + fd); // NOI18N
   4.462 +        return fd;
   4.463 +    }
   4.464 +    
   4.465 +    private List readContents() throws IOException {
   4.466 +        List l = new ArrayList(10);
   4.467 +        while (peek() != TC_ENDBLOCKDATA) {
   4.468 +            l.add(readContent());
   4.469 +        }
   4.470 +        if (readByte() != TC_ENDBLOCKDATA) throw new IllegalStateException();
   4.471 +        if (DEBUG) System.err.println("readContents: " + l); // NOI18N
   4.472 +        return l;
   4.473 +    }
   4.474 +    
   4.475 +    public static final class ArrayWrapper {
   4.476 +        public ClassDesc classdesc;
   4.477 +        public List values;
   4.478 +        public String toString() {
   4.479 +            return classdesc.name + "{" + values + "}"; // NOI18N
   4.480 +        }
   4.481 +    }
   4.482 +    
   4.483 +    private ArrayWrapper readNewArray() throws IOException {
   4.484 +        ArrayWrapper aw = new ArrayWrapper();
   4.485 +        aw.classdesc = readClassDesc();
   4.486 +        makeRef(aw);
   4.487 +        int size = readInt();
   4.488 +        if (size < 0) throw new NotImplementedException();
   4.489 +        aw.values = new ArrayList(size);
   4.490 +        for (int i = 0; i < size; i++) {
   4.491 +            if (aw.classdesc.name.equals("[B")) { // NOI18N
   4.492 +                aw.values.add(new Byte(readByte()));
   4.493 +            } else if (aw.classdesc.name.equals("[S")) { // NOI18N
   4.494 +                aw.values.add(new Short(readShort()));
   4.495 +            } else if (aw.classdesc.name.equals("[I")) { // NOI18N
   4.496 +                aw.values.add(new Integer(readInt()));
   4.497 +            } else if (aw.classdesc.name.equals("[J")) { // NOI18N
   4.498 +                aw.values.add(new Long(readLong()));
   4.499 +            } else if (aw.classdesc.name.equals("[F")) { // NOI18N
   4.500 +                aw.values.add(new Float(Float.intBitsToFloat(readInt())));
   4.501 +            } else if (aw.classdesc.name.equals("[D")) { // NOI18N
   4.502 +                aw.values.add(new Double(Double.longBitsToDouble(readLong())));
   4.503 +            } else if (aw.classdesc.name.equals("[C")) { // NOI18N
   4.504 +                aw.values.add(new Character((char)readShort()));
   4.505 +            } else if (aw.classdesc.name.equals("[Z")) { // NOI18N
   4.506 +                aw.values.add(readByte() == 1 ? Boolean.TRUE : Boolean.FALSE);
   4.507 +            } else {
   4.508 +                aw.values.add(readContent());
   4.509 +            }
   4.510 +        }
   4.511 +        if (DEBUG) System.err.println("readNewArray: " + aw); // NOI18N
   4.512 +        return aw;
   4.513 +    }
   4.514 +    
   4.515 +    private String readNewString() throws IOException {
   4.516 +        String s = readUTF();
   4.517 +        makeRef(s);
   4.518 +        return s;
   4.519 +    }
   4.520 +    
   4.521 +    private Object readReference() throws IOException {
   4.522 +        int i = readInt();
   4.523 +        Object r = getRef(i);
   4.524 +        if (DEBUG) System.err.println("readReference: " + r); // NOI18N
   4.525 +        return r;
   4.526 +    }
   4.527 +    
   4.528 +    private byte[] readBlockData() throws IOException {
   4.529 +        int size = readByte();
   4.530 +        if (size < 0) size += 256;
   4.531 +        byte[] b = new byte[size];
   4.532 +        for (int i = 0; i < size; i++) {
   4.533 +            b[i] = readByte();
   4.534 +        }
   4.535 +        if (DEBUG) System.err.println("readBlockData: " + size + " bytes"); // NOI18N
   4.536 +        return b;
   4.537 +    }
   4.538 +    
   4.539 +    private byte[] readBlockDataLong() throws IOException {
   4.540 +        int size = readInt();
   4.541 +        if (size < 0) throw new NotImplementedException();
   4.542 +        byte[] b = new byte[size];
   4.543 +        for (int i = 0; i < size; i++) {
   4.544 +            b[i] = readByte();
   4.545 +        }
   4.546 +        if (DEBUG) System.err.println("readBlockDataLong: " + size + " bytes"); // NOI18N
   4.547 +        return b;
   4.548 +    }
   4.549 +    
   4.550 +    private List/*<NameValue>*/ readNoWrClass(ClassDesc cd) throws IOException {
   4.551 +        List fields = cd.fields;
   4.552 +        List values = new ArrayList(fields.size());
   4.553 +        for (int i = 0; i < fields.size(); i++) {
   4.554 +            FieldDesc fd = (FieldDesc)fields.get(i);
   4.555 +            if (fd.type.equals("B")) { // NOI18N
   4.556 +                values.add(new NameValue(fd, new Byte(readByte())));
   4.557 +            } else if (fd.type.equals("S")) { // NOI18N
   4.558 +                values.add(new NameValue(fd, new Short(readShort())));
   4.559 +            } else if (fd.type.equals("I")) { // NOI18N
   4.560 +                values.add(new NameValue(fd, new Integer(readInt())));
   4.561 +            } else if (fd.type.equals("J")) { // NOI18N
   4.562 +                values.add(new NameValue(fd, new Long(readLong())));
   4.563 +            } else if (fd.type.equals("F")) { // NOI18N
   4.564 +                values.add(new NameValue(fd, new Float(Float.intBitsToFloat(readInt()))));
   4.565 +            } else if (fd.type.equals("D")) { // NOI18N
   4.566 +                values.add(new NameValue(fd, new Double(Double.longBitsToDouble(readLong()))));
   4.567 +            } else if (fd.type.equals("C")) { // NOI18N
   4.568 +                values.add(new NameValue(fd, new Character((char)readShort())));
   4.569 +            } else if (fd.type.equals("Z")) { // NOI18N
   4.570 +                values.add(new NameValue(fd, readByte() == 1 ? Boolean.TRUE : Boolean.FALSE));
   4.571 +            } else {
   4.572 +                values.add(new NameValue(fd, readContent()));
   4.573 +            }
   4.574 +        }
   4.575 +        if (DEBUG) System.err.println("readNoWrClass: " + values); // NOI18N
   4.576 +        return values;
   4.577 +    }
   4.578 +
   4.579 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/SerStructureNode.java	Fri Sep 17 18:36:33 2010 -0400
     5.3 @@ -0,0 +1,228 @@
     5.4 +/*
     5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 + *
     5.7 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     5.8 + *
     5.9 + * The contents of this file are subject to the terms of either the GNU
    5.10 + * General Public License Version 2 only ("GPL") or the Common
    5.11 + * Development and Distribution License("CDDL") (collectively, the
    5.12 + * "License"). You may not use this file except in compliance with the
    5.13 + * License. You can obtain a copy of the License at
    5.14 + * http://www.netbeans.org/cddl-gplv2.html
    5.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    5.16 + * specific language governing permissions and limitations under the
    5.17 + * License.  When distributing the software, include this License Header
    5.18 + * Notice in each file and include the License file at
    5.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    5.20 + * particular file as subject to the "Classpath" exception as provided
    5.21 + * by Sun in the GPL Version 2 section of the License file that
    5.22 + * accompanied this code. If applicable, add the following below the
    5.23 + * License Header, with the fields enclosed by brackets [] replaced by
    5.24 + * your own identifying information:
    5.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    5.26 + *
    5.27 + * Contributor(s):
    5.28 + *
    5.29 + * The Original Software is NetBeans. The Initial Developer of the Original
    5.30 + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
    5.31 + * Microsystems, Inc. All Rights Reserved.
    5.32 + *
    5.33 + * If you wish your version of this file to be governed by only the CDDL
    5.34 + * or only the GPL Version 2, indicate your decision by adding
    5.35 + * "[Contributor] elects to include this software in this distribution
    5.36 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    5.37 + * single choice of license, a recipient has the option to distribute
    5.38 + * your version of this file under either the CDDL, the GPL Version 2 or
    5.39 + * to extend the choice of license to its licensees as provided above.
    5.40 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    5.41 + * Version 2 license, then the option applies only if the new code is
    5.42 + * made subject to such option by the copyright holder.
    5.43 + */
    5.44 +
    5.45 +package org.netbeans.modules.apisupport.beanbrowser.ser;
    5.46 +
    5.47 +import java.io.*;
    5.48 +import java.util.*;
    5.49 +
    5.50 +import org.openide.*;
    5.51 +import org.openide.nodes.*;
    5.52 +import org.openide.util.NbBundle;
    5.53 +
    5.54 +/** Nodes representing pieces of a serialized file structurally.
    5.55 + * @author Jesse Glick
    5.56 + */
    5.57 +public abstract class SerStructureNode {
    5.58 +
    5.59 +    private SerStructureNode() {/* do not instantiate me */}
    5.60 +
    5.61 +    public static final class StreamNode extends AbstractNode {
    5.62 +        public StreamNode(SerParser.Stream s) {
    5.63 +            super(new GeneralChildren(s.contents));
    5.64 +            setName(s.label);
    5.65 +            setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
    5.66 +        }
    5.67 +    }
    5.68 +    
    5.69 +    private static class GeneralChildren extends Children.Keys {
    5.70 +        private final List things;
    5.71 +        public GeneralChildren(List things) {
    5.72 +            this.things = things;
    5.73 +        }
    5.74 +        protected void addNotify() {
    5.75 +            super.addNotify();
    5.76 +            setKeys(things);
    5.77 +        }
    5.78 +        protected void removeNotify() {
    5.79 +            setKeys(Collections.EMPTY_SET);
    5.80 +            super.removeNotify();
    5.81 +        }
    5.82 +        protected Node[] createNodes(Object key) {
    5.83 +            return new Node[] {createNode(key)};
    5.84 +        }
    5.85 +        protected Node createNode(Object key) {
    5.86 +            if (key instanceof SerParser.NameValue) {
    5.87 +                SerParser.NameValue nv = (SerParser.NameValue)key;
    5.88 +                Node n = createNode(nv.value);
    5.89 +                n.setName(prettify(nv.name.type) + " " + nv.name.name + " = " + n.getName()); // NOI18N
    5.90 +                return n;
    5.91 +            } else if (key instanceof SerParser.ObjectWrapper) {
    5.92 +                SerParser.ObjectWrapper ow = (SerParser.ObjectWrapper)key;
    5.93 +                String name = prettify(ow.classdesc.name);
    5.94 +                Children ch;
    5.95 +                if (name.equals("org.openide.util.io.NbMarshalledObject")) { // NOI18N
    5.96 +                    // This is special!
    5.97 +                    ch = new NbMarshalledObjectChildren(ow);
    5.98 +                } else {
    5.99 +                    ch = new GeneralChildren(ow.data);
   5.100 +                }
   5.101 +                AbstractNode n = new AbstractNode(ch);
   5.102 +                n.setName(NbBundle.getMessage(SerStructureNode.class, "LBL_instance_of", name));
   5.103 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.104 +                return n;
   5.105 +            } else if (key instanceof SerParser.ArrayWrapper) {
   5.106 +                SerParser.ArrayWrapper aw = (SerParser.ArrayWrapper)key;
   5.107 +                AbstractNode n = new AbstractNode(new GeneralChildren(aw.values));
   5.108 +                if (! aw.classdesc.name.startsWith("[")) throw new IllegalStateException("Strange array name: " + aw.classdesc.name); // NOI18N
   5.109 +                n.setName(prettify(aw.classdesc.name.substring(1, aw.classdesc.name.length())) + "[" + aw.values.size() + "]"); // NOI18N
   5.110 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.111 +                return n;
   5.112 +            } else if (key instanceof byte[]) {
   5.113 +                // Block data.
   5.114 +                AbstractNode n = new AbstractNode(Children.LEAF);
   5.115 +                n.setName(SerParser.hexify((byte[])key));
   5.116 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.117 +                return n;
   5.118 +            } else if (key instanceof SerParser.ClassDesc) {
   5.119 +                AbstractNode n = new AbstractNode(Children.LEAF);
   5.120 +                n.setName("class " + prettify(((SerParser.ClassDesc)key).name)); // NOI18N
   5.121 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.122 +                return n;
   5.123 +            } else if (key == SerParser.NULL) {
   5.124 +                AbstractNode n = new AbstractNode(Children.LEAF);
   5.125 +                n.setName("null"); // NOI18N
   5.126 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.127 +                return n;
   5.128 +            } else if (key instanceof String) {
   5.129 +                AbstractNode n = new AbstractNode(Children.LEAF);
   5.130 +                n.setName("\"" + (String)key + "\""); // NOI18N
   5.131 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.132 +                return n;
   5.133 +            } else if ((key instanceof Boolean) || (key instanceof Character) ||
   5.134 +                       (key instanceof Byte) || (key instanceof Short) ||
   5.135 +                       (key instanceof Integer) || (key instanceof Long) ||
   5.136 +                       (key instanceof Float) || (key instanceof Double)) {
   5.137 +                AbstractNode n = new AbstractNode(Children.LEAF);
   5.138 +                n.setName(key.toString());
   5.139 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.140 +                return n;
   5.141 +            } else {
   5.142 +                // ????
   5.143 +                AbstractNode n = new AbstractNode(Children.LEAF);
   5.144 +                n.setName("What is this? " + key + " [" + key.getClass().getName() + "]"); // NOI18N
   5.145 +                n.setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/serAlone"); // NOI18N
   5.146 +                return n;
   5.147 +            }
   5.148 +        }
   5.149 +    }
   5.150 +    
   5.151 +    private static String prettify(String type) {
   5.152 +        if (type.equals("B")) { // NOI18N
   5.153 +            return "byte"; // NOI18N
   5.154 +        } else if (type.equals("S")) { // NOI18N
   5.155 +            return "short"; // NOI18N
   5.156 +        } else if (type.equals("I")) { // NOI18N
   5.157 +            return "int"; // NOI18N
   5.158 +        } else if (type.equals("J")) { // NOI18N
   5.159 +            return "long"; // NOI18N
   5.160 +        } else if (type.equals("F")) { // NOI18N
   5.161 +            return "float"; // NOI18N
   5.162 +        } else if (type.equals("D")) { // NOI18N
   5.163 +            return "double"; // NOI18N
   5.164 +        } else if (type.equals("C")) { // NOI18N
   5.165 +            return "char"; // NOI18N
   5.166 +        } else if (type.equals("Z")) { // NOI18N
   5.167 +            return "boolean"; // NOI18N
   5.168 +        } else if (type.startsWith("L") && type.endsWith(";")) { // NOI18N
   5.169 +            String fqn = type.substring(1, type.length() - 1).replace('/', '.').replace('$', '.'); // NOI18N
   5.170 +            if (fqn.startsWith("java.lang.")) { // NOI18N
   5.171 +                fqn = fqn.substring(10, fqn.length());
   5.172 +            }
   5.173 +            return fqn;
   5.174 +        } else if (type.startsWith("[")) { // NOI18N
   5.175 +            return prettify(type.substring(1, type.length())) + "[]"; // NOI18N
   5.176 +        } else {
   5.177 +            // Should not happen.
   5.178 +            return "ILLEGAL<" + type + ">"; // NOI18N
   5.179 +        }
   5.180 +    }
   5.181 +    
   5.182 +    private static final class NbMarshalledObjectChildren extends Children.Keys {
   5.183 +        private final SerParser.ObjectWrapper ow;
   5.184 +        public NbMarshalledObjectChildren(SerParser.ObjectWrapper ow) {
   5.185 +            this.ow = ow;
   5.186 +        }
   5.187 +        protected void addNotify() {
   5.188 +            super.addNotify();
   5.189 +            setKeys(Collections.singleton(Boolean.TRUE));
   5.190 +        }
   5.191 +        protected void removeNotify() {
   5.192 +            setKeys(Collections.EMPTY_SET);
   5.193 +            super.removeNotify();
   5.194 +        }
   5.195 +        protected Node[] createNodes(Object key) {
   5.196 +            List pairs = ow.data;
   5.197 +            Iterator it = pairs.iterator();
   5.198 +            while (it.hasNext()) {
   5.199 +                Object pair = (Object)it.next();
   5.200 +                if (pair instanceof SerParser.NameValue) {
   5.201 +                    SerParser.NameValue nv = (SerParser.NameValue)pair;
   5.202 +                    if (nv.name.name.equals("objBytes") && nv.name.type.equals("[B")) { // NOI18N
   5.203 +                        SerParser.ArrayWrapper aw = (SerParser.ArrayWrapper)nv.value;
   5.204 +                        List vals = aw.values;
   5.205 +                        byte[] b = new byte[vals.size()];
   5.206 +                        for (int i = 0; i < b.length; i++) {
   5.207 +                            b[i] = ((Byte)vals.get(i)).byteValue();
   5.208 +                        }
   5.209 +                        InputStream is = new ByteArrayInputStream(b);
   5.210 +                        try {
   5.211 +                            SerParser.Stream stream = new SerParser(is).parse(NbBundle.getMessage(SerStructureNode.class, "LBL_ser_stream"));
   5.212 +                            return new Node[] {new SerStructureNode.StreamNode(stream)};
   5.213 +                        } catch (SerParser.CorruptException spce) {
   5.214 +                            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, spce);
   5.215 +                            return new Node[] {};
   5.216 +                        } catch (IOException ioe) {
   5.217 +                            ErrorManager.getDefault().notify(ioe);
   5.218 +                            return new Node[] {};
   5.219 +                        } catch (RuntimeException re) {
   5.220 +                            ErrorManager.getDefault().notify(re);
   5.221 +                            return new Node[] {};
   5.222 +                        }
   5.223 +                    }
   5.224 +                }
   5.225 +            }
   5.226 +            // Improper ser state.
   5.227 +            return new Node[] {};
   5.228 +        }
   5.229 +    }
   5.230 +    
   5.231 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/SerialBrowserTopNode.java	Fri Sep 17 18:36:33 2010 -0400
     6.3 @@ -0,0 +1,169 @@
     6.4 +/*
     6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 + *
     6.7 + * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
     6.8 + *
     6.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    6.10 + * Other names may be trademarks of their respective owners.
    6.11 + *
    6.12 + * The contents of this file are subject to the terms of either the GNU
    6.13 + * General Public License Version 2 only ("GPL") or the Common
    6.14 + * Development and Distribution License("CDDL") (collectively, the
    6.15 + * "License"). You may not use this file except in compliance with the
    6.16 + * License. You can obtain a copy of the License at
    6.17 + * http://www.netbeans.org/cddl-gplv2.html
    6.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    6.19 + * specific language governing permissions and limitations under the
    6.20 + * License.  When distributing the software, include this License Header
    6.21 + * Notice in each file and include the License file at
    6.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    6.23 + * particular file as subject to the "Classpath" exception as provided
    6.24 + * by Oracle in the GPL Version 2 section of the License file that
    6.25 + * accompanied this code. If applicable, add the following below the
    6.26 + * License Header, with the fields enclosed by brackets [] replaced by
    6.27 + * your own identifying information:
    6.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    6.29 + *
    6.30 + * If you wish your version of this file to be governed by only the CDDL
    6.31 + * or only the GPL Version 2, indicate your decision by adding
    6.32 + * "[Contributor] elects to include this software in this distribution
    6.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    6.34 + * single choice of license, a recipient has the option to distribute
    6.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    6.36 + * to extend the choice of license to its licensees as provided above.
    6.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    6.38 + * Version 2 license, then the option applies only if the new code is
    6.39 + * made subject to such option by the copyright holder.
    6.40 + *
    6.41 + * Contributor(s):
    6.42 + *
    6.43 + * Portions Copyrighted 2010 Sun Microsystems, Inc.
    6.44 + */
    6.45 +
    6.46 +package org.netbeans.modules.apisupport.beanbrowser.ser;
    6.47 +
    6.48 +import java.awt.event.ActionEvent;
    6.49 +import java.io.ByteArrayInputStream;
    6.50 +import java.io.File;
    6.51 +import java.io.FileInputStream;
    6.52 +import java.io.IOException;
    6.53 +import java.io.InputStream;
    6.54 +import java.math.BigInteger;
    6.55 +import java.util.ArrayList;
    6.56 +import java.util.List;
    6.57 +import java.util.Observable;
    6.58 +import java.util.Observer;
    6.59 +import javax.swing.AbstractAction;
    6.60 +import javax.swing.Action;
    6.61 +import javax.swing.JFileChooser;
    6.62 +import javax.swing.filechooser.FileNameExtensionFilter;
    6.63 +import org.netbeans.api.core.ide.ServicesTabNodeRegistration;
    6.64 +import org.netbeans.modules.apisupport.beanbrowser.ser.SerParser.Stream;
    6.65 +import org.openide.DialogDisplayer;
    6.66 +import org.openide.NotifyDescriptor;
    6.67 +import org.openide.nodes.AbstractNode;
    6.68 +import org.openide.nodes.ChildFactory;
    6.69 +import org.openide.nodes.Children;
    6.70 +import org.openide.nodes.Node;
    6.71 +import org.openide.windows.WindowManager;
    6.72 +
    6.73 +@ServicesTabNodeRegistration(name="ser", displayName="Serialized Beans", iconResource="org/netbeans/modules/apisupport/beanbrowser/ser/ser.gif", position=2015)
    6.74 +public class SerialBrowserTopNode extends AbstractNode {
    6.75 +
    6.76 +    private static final class Model extends Observable {
    6.77 +        final List<SerParser.Stream> streams = new ArrayList<SerParser.Stream>();
    6.78 +        void add(SerParser.Stream stream) {
    6.79 +            streams.add(stream);
    6.80 +            setChanged();
    6.81 +            notifyObservers();
    6.82 +        }
    6.83 +    }
    6.84 +
    6.85 +    private final Model model;
    6.86 +
    6.87 +    public SerialBrowserTopNode() {
    6.88 +        this(new Model());
    6.89 +    }
    6.90 +    private SerialBrowserTopNode(Model model) {
    6.91 +        super(Children.create(new Ch(model), false));
    6.92 +        this.model = model;
    6.93 +        setIconBase("org/netbeans/modules/apisupport/beanbrowser/ser/ser"); // NOI18N
    6.94 +        setName("ser");
    6.95 +        setDisplayName("Serialized Beans");
    6.96 +    }
    6.97 +
    6.98 +    private void add(InputStream is, String label) throws IOException {
    6.99 +        try {
   6.100 +            model.add(new SerParser(is).parse(label));
   6.101 +        } finally {
   6.102 +            is.close();
   6.103 +        }
   6.104 +    }
   6.105 +
   6.106 +    public @Override Action[] getActions(boolean context) {
   6.107 +        return new Action[] {
   6.108 +            new AbstractAction("Parse File") {
   6.109 +                public @Override void actionPerformed(ActionEvent e) {
   6.110 +                    JFileChooser c = new JFileChooser();
   6.111 +                    c.setFileFilter(new FileNameExtensionFilter("Serialized files", "ser"));
   6.112 +                    if (c.showOpenDialog(WindowManager.getDefault().getMainWindow()) == JFileChooser.APPROVE_OPTION) {
   6.113 +                        File f = c.getSelectedFile();
   6.114 +                        try {
   6.115 +                            add(new FileInputStream(f), f.getName());
   6.116 +                        } catch (IOException x) {
   6.117 +                            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(x.toString(), NotifyDescriptor.ERROR_MESSAGE));
   6.118 +                        }
   6.119 +                    }
   6.120 +                }
   6.121 +            },
   6.122 +            new AbstractAction("Parse Hex String") {
   6.123 +                public @Override void actionPerformed(ActionEvent e) {
   6.124 +                    NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine("Serial data as hex bytes (spaces OK):", "Enter Serialized Text");
   6.125 +                    if (DialogDisplayer.getDefault().notify(input) == NotifyDescriptor.OK_OPTION) {
   6.126 +                        try {
   6.127 +                            String text = input.getInputText().replaceAll("\\s+", "");
   6.128 +                            InputStream is = new ByteArrayInputStream(new BigInteger(text, 16).toByteArray());
   6.129 +                            is.read(); // discard initial zero sign byte
   6.130 +                            add(is, text.substring(0, Math.min(20, text.length())) + "…");
   6.131 +                        } catch (IOException x) {
   6.132 +                            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(x.toString(), NotifyDescriptor.ERROR_MESSAGE));
   6.133 +                        }
   6.134 +                    }
   6.135 +                }
   6.136 +            },
   6.137 +        };
   6.138 +    }
   6.139 +
   6.140 +    private static final class Ch extends ChildFactory.Detachable<SerParser.Stream> implements Observer {
   6.141 +
   6.142 +        private final Model model;
   6.143 +
   6.144 +        @SuppressWarnings("LeakingThisInConstructor")
   6.145 +        Ch(Model model) {
   6.146 +            this.model = model;
   6.147 +        }
   6.148 +
   6.149 +        protected @Override boolean createKeys(List<Stream> toPopulate) {
   6.150 +            toPopulate.addAll(model.streams);
   6.151 +            return true;
   6.152 +        }
   6.153 +
   6.154 +        protected @Override Node createNodeForKey(Stream key) {
   6.155 +            return new SerStructureNode.StreamNode(key);
   6.156 +        }
   6.157 +
   6.158 +        protected @Override void addNotify() {
   6.159 +            model.addObserver(this);
   6.160 +        }
   6.161 +
   6.162 +        protected @Override void removeNotify() {
   6.163 +            model.deleteObserver(this);
   6.164 +        }
   6.165 +
   6.166 +        public @Override void update(Observable o, Object arg) {
   6.167 +            refresh(false);
   6.168 +        }
   6.169 +
   6.170 +    }
   6.171 +
   6.172 +}
     7.1 Binary file apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/ser.gif has changed
     8.1 Binary file apisupport.beanbrowser/src/org/netbeans/modules/apisupport/beanbrowser/ser/serAlone.gif has changed