KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSX > magic > MagicClass13


1 /** (c) Brendan Macmillan 2001, 2002, licensed under GNU's GPL 2
2         (If your project is not GPL, then a fee is due - see license on website)
3     Website: http://www.csse.monash.edu.au/~bren/JSX
4     Website: http://freshmeat.net/projects/jsx
5     List (can read without subscribing, need to join to post):
6       http://groups.yahoo.com/group/JSX-ideas/messages
7         Commercial licensing enquiries only:
8             bren@objectlight.com */

9
10
11 package JSX.magic;
12 import java.lang.reflect.*;
13 import java.io.*;
14
15 class MagicClass13 extends MagicClassI {
16
17     private static Method allocateNewObject;
18     private static Method setObjectFieldValue;
19     private static Method setPrimitiveFieldValues;
20     private static Method getFieldIDs;
21     MagicClass13() {
22         try {
23             allocateNewObject = java.io.ObjectInputStream JavaDoc.class.getDeclaredMethod(
24                 "allocateNewObject",
25                 new Class JavaDoc[] {Class JavaDoc.class, Class JavaDoc.class});
26             allocateNewObject.setAccessible(true);
27
28             setObjectFieldValue = java.io.ObjectInputStream JavaDoc.class.getDeclaredMethod(
29                 "setObjectFieldValue",
30                 new Class JavaDoc[] {Object JavaDoc.class, long.class, Class JavaDoc.class, Object JavaDoc.class});
31             setObjectFieldValue.setAccessible(true);
32
33             setPrimitiveFieldValues = java.io.ObjectInputStream JavaDoc.class.getDeclaredMethod(
34                 "setPrimitiveFieldValues",
35                 new Class JavaDoc[] {Object JavaDoc.class, long[].class, char[].class, byte[].class});
36             setPrimitiveFieldValues.setAccessible(true);
37
38             getFieldIDs = java.io.ObjectStreamClass JavaDoc.class.getDeclaredMethod(
39                 "getFieldIDs",
40                 new Class JavaDoc[] {ObjectStreamField[].class, long[].class, long[].class});
41             getFieldIDs.setAccessible(true);
42
43         } catch (NoSuchMethodException JavaDoc noMethod) {
44             throw new InternalError JavaDoc(noMethod.toString());
45         }
46
47         try {
48             osc = (ObjectStreamClass) newInstance(ObjectStreamClass.class);
49         } catch (NotSerializableException e) { // Serializable check in newInstance
50
e.printStackTrace();
51         }
52     }
53
54
55 /**
56     * first non-serializable ancestor with a public no-arg constructor.
57     * currentClass: is the actual runtime class we want to create
58     * currclass: is the closest non-serializable ancestor.
59     * NB: Object is non-serializable, always bottoms out.
60     * old JSX can serialize an Object - differs from JOS...
61     **/

62     public Object JavaDoc newInstance(Class JavaDoc currentClass)
63             throws NotSerializableException {
64
65 /*
66         if (!Serializable.class.isAssignableFrom(currentClass))
67             throw new NotSerializableException("'"+currentClass+"' is not Serializable - JSX *can* serialize such classes, despite them not implementing the 'Serializable' interface; but this feature is currently switched off (since version JSX1.0.4.2), as an experiment to see if it makes any difference. If this is an annoyance to you, please post to the mailing list immediately:\n" +
68             " http://groups.yahoo.com/group/JSX-ideas/messages");
69 */

70
71         Class JavaDoc currclass;
72         if (Serializable.class.isAssignableFrom(currentClass)) {
73 //JOS way:
74
currclass = currentClass; //begin search for ancestor
75
if (currclass != null) {
76                 while (Serializable.class.isAssignableFrom(currclass))
77                     currclass = currclass.getSuperclass();
78             }
79         } else {
80 //JSX way:
81
currclass = Object JavaDoc.class; //always use object
82
}
83
84 //way common to both
85
Object JavaDoc[] argValues = {currentClass, currclass};
86         try {
87             return allocateNewObject.invoke(null, argValues);
88         } catch (InvocationTargetException invokeE) {
89             throw new InternalError JavaDoc(invokeE.toString());
90         } catch (IllegalAccessException JavaDoc noAccess) {
91             throw new InternalError JavaDoc();
92         }
93     }
94
95
96     public void setObjectFieldValue(Object JavaDoc parent, Field f, Class JavaDoc type, Object JavaDoc value) {
97         long[] primIDs = new long[0];
98         long[] objIDs = new long[1]; //we know only one field, and it's an Object
99
myGetFieldIDs(f, primIDs, objIDs);
100
101         Object JavaDoc[] argValues = {parent, new Long JavaDoc(objIDs[0]), type, value};
102         try {
103             setObjectFieldValue.invoke(null, argValues);
104         } catch (InvocationTargetException invokeE) {
105             throw new InternalError JavaDoc(invokeE.toString());
106         } catch (IllegalAccessException JavaDoc noAccess) {
107             throw new InternalError JavaDoc();
108         }
109     }
110
111
112     public void setPrimitiveFieldValues(Object JavaDoc parent, Field f, Object JavaDoc value) {
113         long[] primIDs = new long[1]; //we know only one field, and it's primitive
114
long[] objIDs = new long[0];
115         ObjectStreamField osf = myGetFieldIDs(f, primIDs, objIDs);
116 //Wish: to set final primitive fields in 1.3 using primitive values directly
117
char[] typecode = {osf.getTypeCode()}; //It already knows this
118

119         ByteArrayOutputStream ba1 = new ByteArrayOutputStream();
120         DataOutputStream ba = new DataOutputStream(ba1);
121         try {
122             switch (typecode[0]) {
123                 case 'B': ba.writeByte(((Byte JavaDoc)value).byteValue()); break; //byte
124
case 'C': ba.writeChar(((Character JavaDoc)value).charValue()); break; //char
125
case 'S': ba.writeShort(((Short JavaDoc)value).shortValue()); break; //short
126
case 'I': ba.writeInt(((Integer JavaDoc)value).intValue()); break; //int
127
case 'J': ba.writeLong(((Long JavaDoc)value).longValue()); break; //long
128
case 'F': ba.writeFloat(((Float JavaDoc)value).floatValue()); break; //float
129
case 'D': ba.writeDouble(((Double JavaDoc)value).doubleValue()); break; //double
130
case 'Z': ba.writeBoolean(((Boolean JavaDoc)value).booleanValue()); break; //boolean
131
case '[': //an array...
132
case 'L': //an object
133
default:
134                     throw new InternalError JavaDoc("setPrimitiveFieldValues only does primitives");
135             }
136             ba.flush();
137             ba.close();
138         } catch (IOException byteArrayProblem) {
139             throw new InternalError JavaDoc(byteArrayProblem.toString());
140         }
141
142         Object JavaDoc[] argValues = {parent, primIDs, typecode, ba1.toByteArray()};
143         try {
144             setPrimitiveFieldValues.invoke(null, argValues);
145         } catch (InvocationTargetException invokeE) {
146             throw new InternalError JavaDoc("MagicClass13.setPrimitiveFieldValues() failure");
147         } catch (IllegalAccessException JavaDoc noAccess) {
148             throw new InternalError JavaDoc();
149         }
150     }
151
152
153     static protected ObjectStreamField myGetFieldIDs(Field f, long[] primIDs, long[] objIDs) {
154         ObjectStreamField osf = null;
155         try {
156             osf = new ObjectStreamField(f.getName(), f.getType());
157             Field osfField = ObjectStreamField.class.getDeclaredField("field");
158             osfField.setAccessible(true);
159             osfField.set(osf, f);
160         } catch (NoSuchFieldException JavaDoc noField) {
161             throw new InternalError JavaDoc();
162         } catch (IllegalAccessException JavaDoc noAccess) {
163             throw new InternalError JavaDoc();
164         }
165         ObjectStreamField[] fs = {osf};
166         getFieldIDs(fs, primIDs, objIDs);
167         return osf; //in case needed - primitive uses, object ignores
168
}
169
170
171     static protected void getFieldIDs(ObjectStreamField[] fs, long[] primIDs, long[] objIDs) {
172         try {
173             Object JavaDoc[] argValues = {fs, primIDs, objIDs};
174             getFieldIDs.invoke(null, argValues); //null because static
175
} catch (InvocationTargetException invokeE) {
176             throw new InternalError JavaDoc(invokeE.toString());
177         } catch (IllegalAccessException JavaDoc noAccess) {
178             throw new InternalError JavaDoc();
179         }
180     }
181
182 }
183
Popular Tags