Projekt

Obecné

Profil

Stáhnout (9.35 KB) Statistiky
| Větev: | Tag: | Revize:
1
package jdeserialize;
2
import java.io.*;
3
import java.util.*;
4

    
5
/**
6
 * <p>
7
 * Represents the entire serialized prototype of the class, including all fields,
8
 * inner classes, class annotations, and inheritance hierarchy.  This includes proxy class
9
 * descriptions.
10
 * </p>
11
 *
12
 * <p>
13
 * Generally, this class is used to represent the type of an instance written to an
14
 * ObjectOutputStream with its writeObject() method, or of a related array or field type.
15
 * However, there's a notable exception: when instances of type java.io.ObjectStreamClass
16
 * are written with writeObject(), only their class description is written (cf. Object
17
 * Serialization Specification, 4.3).  They will be represented with an instance of
18
 * classdesc as well.
19
 * </p>
20
 */
21
public class classdesc extends contentbase {
22
    /**
23
     * Type of the class being represented; either a normal class or a proxy class.
24
     */
25
    public classdesctype classtype;
26

    
27
    /**
28
     * Class name.
29
     */
30
    public String name;
31

    
32
    /**
33
     * Serial version UID, as recorded in the stream.
34
     */
35
    public long serialVersionUID;
36

    
37
    /**
38
     * Description flags byte; this should be a mask of values from the ObjectStreamContants 
39
     * class.  Refer to chapter 6 of the Object Stream Serialization Protocol for details.
40
     */
41
    public byte descflags;
42

    
43
    /**
44
     * Array of fields in the class, in the order serialized by the stream writer.
45
     */
46
    public field[] fields;
47

    
48
    /**
49
     * List of inner classes, in the order serialized by the stream writer.
50
     */
51
    public List<classdesc> innerclasses;
52
    
53
    /**
54
     * List of annotation objects; these are *not* Java annotations, but data written by
55
     * the <pre>annotateClass(Class<?>)<pre> and <pre>annotateProxyClass(Class<?>)</pre> methods of an
56
     * ObjectOutputStream.  
57
     */
58
    public List<content> annotations;
59

    
60
    /**
61
     * The superclass of the object, if available.
62
     */
63
    public classdesc superclass;
64

    
65
    /**
66
     * Array of serialized interfaces, in the order serialized by the stream writer.
67
     */
68
    public String[] interfaces;
69

    
70
    /**
71
     * Set of enum constants, for enum classes.
72
     */
73
    public Set<String> enumconstants;
74

    
75
    private boolean isInnerClass = false;
76
    /**
77
     * True if this class has been determined to be an inner class; this determination is
78
     * generally made by connectMemberClasses().
79
     * 
80
     * @return true if the class is an inner class
81
     */
82
    public boolean isInnerClass() {
83
        return isInnerClass;
84
    }
85
    /**
86
     * Sets the value that denotes that the class is an inner class.
87
     *
88
     * @param nis the value to set
89
     */
90
    public void setIsInnerClass(boolean nis) {
91
        this.isInnerClass = nis;
92
    }
93

    
94
    private boolean isLocalInnerClass = false;
95
    /**
96
     * True if this class has been determined to be a local inner class; this
97
     * determination is generally made by connectMemberClasses().
98
     *
99
     * @return true if the class is a local inner class
100
     */
101
    public boolean isLocalInnerClass() {
102
        return isLocalInnerClass;
103
    }
104
    /**
105
     * Sets the flag that denotes whether this class is a local inner class.
106
     * 
107
     * @param nis the value to set
108
     */
109
    public void setIsLocalInnerClass(boolean nis) {
110
        this.isLocalInnerClass = nis;
111
    }
112

    
113
    private boolean isStaticMemberClass = false;
114
    /**
115
     * <p>
116
     * True if this class has been determined to be a static member class; this
117
     * determination is generally made by connectMemberClasses().
118
     * </p>
119
     *
120
     * <p>
121
     * Note that in some cases, static member classes' descriptions will be serialized
122
     * even though their enclosing class is not.  In these cases, this may return false.
123
     * See connectMemberClasses() for details.
124
     * </p>
125
     *
126
     * @return true if this is a static member class
127
     */
128
    public boolean isStaticMemberClass() {
129
        return isStaticMemberClass;
130
    }
131
    /**
132
     * Sets the flag that denotes whether this class is a static member class.
133
     *
134
     * @param nis the value to set
135
     */
136
    public void setIsStaticMemberClass(boolean nis) {
137
        this.isStaticMemberClass = nis;
138
    }
139

    
140
    /**
141
     * Constructor.
142
     *
143
     * @param classtype the type of the class
144
     */
145
    public classdesc(classdesctype classtype) {
146
        super(contenttype.CLASSDESC);
147
        this.classtype = classtype;
148
        this.enumconstants = new HashSet<String>();
149
        this.innerclasses = new ArrayList<classdesc>();
150
    }
151

    
152
    /**
153
     * Add an inner class to the description's list.
154
     * @param cd inner class to add
155
     */
156
    public void addInnerClass(classdesc cd) {
157
        innerclasses.add(cd);
158
    }
159

    
160
    /**
161
     * Add an enum constant to the description's set.
162
     *
163
     * @param constval enum constant string
164
     */
165
    public void addEnum(String constval) {
166
        this.enumconstants.add(constval);
167
    }
168

    
169
    /**
170
     * Determines whether this is an array type. 
171
     * @return true if this is an array type.
172
     */
173
    public boolean isArrayClass() {
174
        if(name != null && name.length() > 1 && name.charAt(0) == '[') {
175
            return true;
176
        } else {
177
            return false;
178
        }
179
    }
180
    public String toString() {
181
        StringBuffer sb = new StringBuffer();
182
        sb.append("[cd ").append(jdeserialize.hex(handle)).append(": name ").append(name);
183
        sb.append(" uid ").append(serialVersionUID);
184
        sb.append("]");
185
        return sb.toString();
186
    }
187

    
188
    /**
189
     * Generates a list of all class descriptions in this class's hierarchy, in the order
190
     * described by the Object Stream Serialization Protocol.  This is the order in which
191
     * fields are read from the stream.
192
     * 
193
     * @param classes a list to be filled in with the hierarchy
194
     */
195
    public void getHierarchy(ArrayList<classdesc> classes) {
196
        if(superclass != null) {
197
            if(superclass.classtype == classdesctype.PROXYCLASS) {
198
                jdeserialize.debugerr("warning: hit a proxy class in superclass hierarchy");
199
            } else {
200
                superclass.getHierarchy(classes);
201
            }
202
        } 
203
        classes.add(this);
204
    }
205
    public void validate() throws ValidityException {
206
        // If neither SC_SERIALIZABLE nor SC_EXTERNALIZABLE is set, then the number of
207
        // fields is always zero.  (spec section 4.3)
208
        if((descflags & (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) == 0 && fields != null && fields.length > 0) {
209
            throw new ValidityException("non-serializable, non-externalizable class has fields!");
210
        }
211
        if((descflags & (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) == (ObjectStreamConstants.SC_SERIALIZABLE | ObjectStreamConstants.SC_EXTERNALIZABLE)) {
212
            throw new ValidityException("both Serializable and Externalizable are set!");
213
        }
214
        if((descflags & ObjectStreamConstants.SC_ENUM) != 0) {
215
            // we're an enum; shouldn't have any fields/superinterfaces
216
            if((fields != null && fields.length > 0) || interfaces != null) {
217
                throw new ValidityException("enums shouldn't implement interfaces or have non-constant fields!");
218
            }
219
        } else {
220
            // non-enums shouldn't have enum constant fields.  
221
            if(enumconstants != null && enumconstants.size() > 0) {
222
                throw new ValidityException("non-enum classes shouldn't have enum constants!");
223
            }
224
        }
225
    }
226

    
227
    public @Override String toJson(String indentation, Map<classdesc, Map<field, Object>> fielddata)
228
    {
229
        StringBuffer sb = new StringBuffer();
230
        String val = "";
231
        
232
        indentation += "\t";
233

    
234
        // ClassName
235
        sb.append("{\n").append(indentation).append("class ").append(this.name);
236
        // extends
237
        if (this.superclass != null) {
238
            sb.append(" extends ").append(this.superclass.name);
239
        }
240
        // implements
241
        if (this.interfaces != null) {
242
            sb.append(" implements ");
243
            for (String str : this.interfaces) {
244
                sb.append(str);
245
            }
246
        }
247
        sb.append(" : {"); // ending of first line
248
        
249
        indentation += "\t";
250

    
251
        for (field f : this.fields) {
252
            // v this.fielddata najit element, jehoz key == classdesc
253
            // v tomto prvku fielddata najdu value (element) podle key == f
254
            // jeho value je chtena hodnota
255
            var locVal = fielddata.get(this).get(f);
256

    
257
            if(locVal instanceof content)
258
            {
259
                val = ((content)locVal).toJson(indentation, fielddata);
260
            }
261
            else {
262
                val = locVal.toString();
263
            }
264

    
265
            sb.append("\n").append(indentation);
266
            sb.append("\"").append(f.name).append("\"");
267
            sb.append(" : ");
268
            sb.append(val);
269

    
270
            if (!f.equals(this.fields[this.fields.length - 1])) {
271
                sb.append(", ");
272
            }
273
        }
274
        indentation = indentation.substring(0, indentation.length() - 1);
275

    
276
        sb.append("\n").append(indentation).append("}");
277
        
278

    
279
        if(this.superclass != null)
280
        {
281
            sb.append(",\n");
282
            sb.append(this.superclass.toJson(indentation, fielddata));
283
        }
284
        
285
        indentation = indentation.substring(0, indentation.length() - 1);
286
        sb.append(indentation).append("\n}");
287

    
288
        return sb.toString();
289
    }
290
}
291

    
(8-8/20)