KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > YapHandlers


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o;
22
23 import com.db4o.foundation.*;
24 import com.db4o.inside.diagnostic.*;
25 import com.db4o.inside.replication.*;
26 import com.db4o.reflect.*;
27 import com.db4o.reflect.generic.*;
28 import com.db4o.types.*;
29
30 /**
31  * @exclude
32  */

33 public final class YapHandlers {
34     
35     private final YapStream _masterStream; // this is master YapStream and not valid
36
// for YapObjectCarrier
37

38     private static final Db4oTypeImpl[] i_db4oTypes = { new BlobImpl()};
39
40     public static final int ANY_ARRAY_ID = 12;
41     public static final int ANY_ARRAY_N_ID = 13;
42
43     // Array Indices in i_YapContainers
44
private static final int CLASSCOUNT = 11;
45
46     private YapClass i_anyArray;
47     private YapClass i_anyArrayN;
48
49     public final YapString i_stringHandler;
50
51     private TypeHandler4[] i_handlers;
52
53     private int i_maxTypeID = ANY_ARRAY_N_ID + 1;
54
55     private YapTypeAbstract[] i_platformTypes;
56     static private final int PRIMITIVECOUNT = 8;
57
58     YapClass[] i_yapClasses;
59
60     // need to keep getID Functions in Sync with ArrayIndex
61
private static final int ANY_INDEX = 10;
62     public static final int ANY_ID = 11;
63     
64     public final YapFieldVirtual[] i_virtualFields = new YapFieldVirtual[2];
65
66     private final Hashtable4 i_classByClass = new Hashtable4(32);
67     
68     Db4oCollections i_collections;
69     
70     YapIndexes i_indexes;
71     
72     ReplicationImpl i_replication;
73     
74     MigrationConnection i_migration;
75     
76     Db4oReplicationReferenceProvider _replicationReferenceProvider;
77     
78     public final DiagnosticProcessor _diagnosticProcessor;
79     
80     
81     public boolean i_encrypt;
82     byte[] i_encryptor;
83     int i_lastEncryptorByte;
84     
85     final GenericReflector _reflector;
86     
87     ReflectClass ICLASS_COMPARE;
88     ReflectClass ICLASS_DB4OTYPE;
89     ReflectClass ICLASS_DB4OTYPEIMPL;
90     public ReflectClass ICLASS_INTERNAL;
91     ReflectClass ICLASS_UNVERSIONED;
92     ReflectClass ICLASS_OBJECT;
93     ReflectClass ICLASS_OBJECTCONTAINER;
94     public ReflectClass ICLASS_STATICCLASS;
95     ReflectClass ICLASS_STRING;
96     ReflectClass ICLASS_TRANSIENTCLASS;
97
98     YapHandlers(final YapStream a_stream, byte stringEncoding, GenericReflector reflector) {
99         
100         _masterStream = a_stream;
101         a_stream.i_handlers = this;
102         
103         _reflector = reflector;
104         _diagnosticProcessor = a_stream.configImpl().diagnosticProcessor();
105         
106         initClassReflectors(reflector);
107         
108         i_indexes = new YapIndexes(a_stream);
109         
110         i_virtualFields[0] = i_indexes.i_fieldVersion;
111         i_virtualFields[1] = i_indexes.i_fieldUUID;
112
113         i_stringHandler = new YapString(a_stream, YapStringIO.forEncoding(stringEncoding));
114
115         i_handlers = new TypeHandler4[] { new YInt(a_stream), new YLong(a_stream), new YFloat(a_stream),
116             new YBoolean(a_stream), new YDouble(a_stream), new YByte(a_stream), new YChar(a_stream),
117             new YShort(a_stream),
118
119             // primitives first
120
i_stringHandler, new YDate(a_stream), new YapClassAny(a_stream) // Index = 10, ID = 11
121
};
122         
123         i_platformTypes = Platform4.types(a_stream);
124
125         if (i_platformTypes.length > 0) {
126             for (int i = 0; i < i_platformTypes.length; i++) {
127                 i_platformTypes[i].initialize();
128                 if (i_platformTypes[i].getID() > i_maxTypeID) {
129                     i_maxTypeID = i_platformTypes[i].getID();
130                 }
131             }
132
133             TypeHandler4[] temp = i_handlers;
134             i_handlers = new TypeHandler4[i_maxTypeID];
135             System.arraycopy(temp, 0, i_handlers, 0, temp.length);
136             for (int i = 0; i < i_platformTypes.length; i++) {
137                 int idx = i_platformTypes[i].getID() - 1;
138                 i_handlers[idx] = i_platformTypes[i];
139             }
140         }
141
142         i_yapClasses = new YapClass[i_maxTypeID + 1];
143
144         for (int i = 0; i < CLASSCOUNT; i++) {
145             int id = i + 1; // note that we avoid 0 here
146
i_yapClasses[i] = new YapClassPrimitive(a_stream, i_handlers[i]);
147             i_yapClasses[i].setID(id);
148             i_classByClass.put(i_handlers[i].classReflector(), i_yapClasses[i]);
149             if(i < ANY_INDEX){
150                 reflector.registerPrimitiveClass(id, i_handlers[i].classReflector().getName(), null);
151             }
152             if (!Deploy.csharp) {
153                 if (i_handlers[i].primitiveClassReflector() != null) {
154                     i_classByClass.put(i_handlers[i].primitiveClassReflector(), i_yapClasses[i]);
155                 }
156             }
157         }
158         for (int i = 0; i < i_platformTypes.length; i++) {
159             int id = i_platformTypes[i].getID();
160             int idx = id - 1;
161             GenericConverter converter = (i_platformTypes[i] instanceof GenericConverter) ? (GenericConverter)i_platformTypes[i] : null;
162             reflector.registerPrimitiveClass(id, i_platformTypes[i].getName(), converter);
163             i_handlers[idx] = i_platformTypes[i];
164             i_yapClasses[idx] = new YapClassPrimitive(a_stream, i_platformTypes[i]);
165             i_yapClasses[idx].setID(id);
166             if (id > i_maxTypeID) {
167                 i_maxTypeID = idx;
168             }
169             i_classByClass.put(i_platformTypes[i].classReflector(), i_yapClasses[idx]);
170             if (!Deploy.csharp) {
171                 if (i_platformTypes[i].primitiveClassReflector() != null) {
172                     i_classByClass.put(i_platformTypes[i].primitiveClassReflector(), i_yapClasses[idx]);
173                 }
174             }
175         }
176
177         i_anyArray = new YapClassPrimitive(a_stream, new YapArray(_masterStream,
178             anyObject(), false));
179         i_anyArray.setID(ANY_ARRAY_ID);
180         i_yapClasses[ANY_ARRAY_ID - 1] = i_anyArray;
181
182         i_anyArrayN = new YapClassPrimitive(a_stream, new YapArrayN(_masterStream,
183             anyObject(), false));
184         i_anyArrayN.setID(ANY_ARRAY_N_ID);
185         i_yapClasses[ANY_ARRAY_N_ID - 1] = i_anyArrayN;
186     }
187
188     int arrayType(Object JavaDoc a_object) {
189         ReflectClass claxx = _masterStream.reflector().forObject(a_object);
190         if (! claxx.isArray()) {
191             return 0;
192         }
193         if (_masterStream.reflector().array().isNDimensional(claxx)) {
194             return YapConst.TYPE_NARRAY;
195         }
196         return YapConst.TYPE_ARRAY;
197     }
198     
199     boolean createConstructor(final ReflectClass claxx, boolean skipConstructor){
200         
201         if (claxx == null) {
202             return false;
203         }
204         
205         if (claxx.isAbstract() || claxx.isInterface()) {
206             return true;
207         }
208         
209         if(! Platform4.callConstructor()){
210             if(claxx.skipConstructor(skipConstructor)){
211                 return true;
212             }
213         }
214         
215         if (! _masterStream.configImpl().testConstructors()) {
216             return true;
217         }
218         
219         if (claxx.newInstance() != null) {
220             return true;
221         }
222         
223         if (_masterStream.reflector().constructorCallsSupported()) {
224             try {
225                 
226                 ReflectConstructor[] constructors = claxx.getDeclaredConstructors();
227                 
228                 Tree sortedConstructors = null;
229                 
230                 // sort constructors by parameter count
231
for (int i = 0; i < constructors.length; i++) {
232                     try{
233                         constructors[i].setAccessible();
234                         int parameterCount = constructors[i].getParameterTypes().length;
235                         sortedConstructors = Tree.add(sortedConstructors, new TreeIntObject(i+constructors.length*parameterCount, constructors[i]));
236                     } catch (Throwable JavaDoc t) {
237                         if(Debug.atHome){
238                             t.printStackTrace();
239                         }
240                     }
241                 }
242                 
243                 // call zero-arg constructors first
244
final boolean[] foundConstructor={false};
245                 if(sortedConstructors != null){
246                     final TypeHandler4[] handlers = i_handlers;
247                     sortedConstructors.traverse(new Visitor4() {
248                         public void visit(Object JavaDoc a_object) {
249                             if(! foundConstructor[0]) {
250                                 ReflectConstructor constructor = (ReflectConstructor)((TreeIntObject)a_object)._object;
251                                 try {
252                                     ReflectClass[] pTypes = constructor.getParameterTypes();
253                                     Object JavaDoc[] parms = new Object JavaDoc[pTypes.length];
254                                     for (int j = 0; j < parms.length; j++) {
255                                         for (int k = 0; k < PRIMITIVECOUNT; k++) {
256                                             if (pTypes[j].equals(handlers[k].primitiveClassReflector())) {
257                                                 parms[j] = ((YapJavaClass) handlers[k])
258                                                     .primitiveNull();
259                                                 break;
260                                             }
261                                         }
262                                     }
263                                     Object JavaDoc res = constructor.newInstance(parms);
264                                     if (res != null) {
265                                         foundConstructor[0] = true;
266                                         claxx.useConstructor(constructor, parms);
267                                     }
268                                 } catch (Throwable JavaDoc t) {
269                                     if(Debug.atHome){
270                                         t.printStackTrace();
271                                     }
272                                 }
273                             }
274                         }
275                     });
276                     
277                 }
278                 if(foundConstructor[0]){
279                     return true;
280                 }
281                 
282             } catch (Throwable JavaDoc t1) {
283                 if(Debug.atHome){
284                     t1.printStackTrace();
285                 }
286
287             }
288         }
289         return false;
290     }
291     
292     final void decrypt(YapReader reader) {
293         if(i_encrypt){
294             int encryptorOffSet = i_lastEncryptorByte;
295             byte[] bytes = reader._buffer;
296             for (int i = reader.getLength() - 1; i >= 0; i--) {
297                 bytes[i] += i_encryptor[encryptorOffSet];
298                 if (encryptorOffSet == 0) {
299                     encryptorOffSet = i_lastEncryptorByte;
300                 } else {
301                     encryptorOffSet--;
302                 }
303             }
304         }
305     }
306     
307     final void encrypt(YapReader reader) {
308         if(i_encrypt){
309             byte[] bytes = reader._buffer;
310             int encryptorOffSet = i_lastEncryptorByte;
311             for (int i = reader.getLength() - 1; i >= 0; i--) {
312                 bytes[i] -= i_encryptor[encryptorOffSet];
313                 if (encryptorOffSet == 0) {
314                     encryptorOffSet = i_lastEncryptorByte;
315                 } else {
316                     encryptorOffSet--;
317                 }
318             }
319         }
320     }
321     
322     public void oldEncryptionOff() {
323         i_encrypt = false;
324         i_encryptor = null;
325         i_lastEncryptorByte = 0;
326         _masterStream.configImpl().oldEncryptionOff();
327     }
328     
329     final TypeHandler4 getHandler(int a_index) {
330         return i_handlers[a_index - 1];
331     }
332
333     final TypeHandler4 handlerForClass(ReflectClass a_class, ReflectClass[] a_Supported) {
334         for (int i = 0; i < a_Supported.length; i++) {
335             if (a_Supported[i].equals(a_class)) {
336                 return i_handlers[i];
337             }
338         }
339         return null;
340     }
341
342     // TODO: Interfaces should be handled by the ANY handler but we
343
// need to write the code to migrate from the old field handler to the new
344
public final TypeHandler4 handlerForClass(YapStream a_stream, ReflectClass a_class) {
345         if(a_class == null){
346             return null;
347         }
348 // if (a_class.isInterface()) {
349
// return anyObject();
350
// }
351
if (a_class.isArray()) {
352             return handlerForClass(a_stream, a_class.getComponentType());
353         }
354         YapClass yc = getYapClassStatic(a_class);
355         if (yc != null) {
356             return ((YapClassPrimitive) yc).i_handler;
357         }
358         return a_stream.produceYapClass(a_class);
359     }
360
361     private TypeHandler4 anyObject() {
362         return i_handlers[ANY_INDEX];
363     }
364     
365     private void initClassReflectors(GenericReflector reflector){
366         ICLASS_COMPARE = reflector.forClass(YapConst.CLASS_COMPARE);
367         ICLASS_DB4OTYPE = reflector.forClass(YapConst.CLASS_DB4OTYPE);
368         ICLASS_DB4OTYPEIMPL = reflector.forClass(YapConst.CLASS_DB4OTYPEIMPL);
369         ICLASS_INTERNAL = reflector.forClass(YapConst.CLASS_INTERNAL);
370         ICLASS_UNVERSIONED = reflector.forClass(YapConst.CLASS_UNVERSIONED);
371         ICLASS_OBJECT = reflector.forClass(YapConst.CLASS_OBJECT);
372         ICLASS_OBJECTCONTAINER = reflector
373                 .forClass(YapConst.CLASS_OBJECTCONTAINER);
374         ICLASS_STATICCLASS = reflector.forClass(YapConst.CLASS_STATICCLASS);
375         ICLASS_STRING = reflector.forClass(String JavaDoc.class);
376         ICLASS_TRANSIENTCLASS = reflector
377                 .forClass(YapConst.CLASS_TRANSIENTCLASS);
378         
379         Platform4.registerCollections(reflector);
380     }
381     
382     void initEncryption(Config4Impl a_config){
383         if (a_config.encrypt() && a_config.password() != null
384             && a_config.password().length() > 0) {
385             i_encrypt = true;
386             i_encryptor = new byte[a_config.password().length()];
387             for (int i = 0; i < i_encryptor.length; i++) {
388                 i_encryptor[i] = (byte) (a_config.password().charAt(i) & 0xff);
389             }
390             i_lastEncryptorByte = a_config.password().length() - 1;
391             return;
392         }
393         
394         oldEncryptionOff();
395     }
396     
397     static Db4oTypeImpl getDb4oType(ReflectClass clazz) {
398         for (int i = 0; i < i_db4oTypes.length; i++) {
399             if (clazz.isInstance(i_db4oTypes[i])) {
400                 return i_db4oTypes[i];
401             }
402         }
403         return null;
404     }
405
406     public YapClass getYapClassStatic(int a_id) {
407         if (a_id > 0 && a_id <= i_maxTypeID) {
408             return i_yapClasses[a_id - 1];
409         }
410         return null;
411     }
412
413     YapClass getYapClassStatic(ReflectClass a_class) {
414         if (a_class == null) {
415             return null;
416         }
417         if (a_class.isArray()) {
418             if (_masterStream.reflector().array().isNDimensional(a_class)) {
419                 return i_anyArrayN;
420             }
421             return i_anyArray;
422         }
423         return (YapClass) i_classByClass.get(a_class);
424     }
425     
426     public boolean isSecondClass(Object JavaDoc a_object){
427         if(a_object != null){
428             ReflectClass claxx = _masterStream.reflector().forObject(a_object);
429             if(i_classByClass.get(claxx) != null){
430                 return true;
431             }
432             if(Deploy.csharp){
433                 return Platform4.isValueType(claxx);
434             }
435         }
436         return false;
437     }
438
439     public boolean isSystemHandler(int id) {
440         return id<=i_maxTypeID;
441     }
442 }
Popular Tags