001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal;
022:
023: import com.db4o.*;
024: import com.db4o.foundation.*;
025: import com.db4o.internal.diagnostic.*;
026: import com.db4o.internal.handlers.*;
027: import com.db4o.internal.replication.*;
028: import com.db4o.reflect.*;
029: import com.db4o.reflect.generic.*;
030:
031: /**
032: * @exclude
033: *
034: * TODO: This class was written to make ObjectContainerBase
035: * leaner, so TransportObjectContainer has less members.
036: *
037: * All funcionality of this class should become part of
038: * ObjectContainerBase and the functionality in
039: * ObjectContainerBase should delegate to independant
040: * modules without circular references.
041: *
042: */
043: public final class HandlerRegistry {
044:
045: private final ObjectContainerBase _container; // this is the master container and not valid
046: // for TransportObjectContainer
047:
048: private static final Db4oTypeImpl[] _db4oTypes = { new BlobImpl() };
049:
050: private ClassMetadata i_anyArray;
051:
052: private ClassMetadata i_anyArrayN;
053:
054: public StringHandler _stringHandler;
055:
056: private Hashtable4 _handlers = new Hashtable4(16);
057:
058: private Hashtable4 _classes = new Hashtable4(16);
059:
060: private Hashtable4 _classMetadata = new Hashtable4(16);
061:
062: private Hashtable4 _ids = new Hashtable4(16);
063:
064: private int _highestBuiltinTypeID = Handlers4.ANY_ARRAY_N_ID + 1;
065:
066: static private final int PRIMITIVECOUNT = 8;
067:
068: public static final int ANY_ID = 11;
069:
070: private final VirtualFieldMetadata[] _virtualFields = new VirtualFieldMetadata[2];
071:
072: private final Hashtable4 _mapReflectorToHandler = new Hashtable4(32);
073:
074: private final Hashtable4 _mapHandlerToReflector = new Hashtable4(32);
075:
076: private SharedIndexedFields _indexes;
077:
078: /**
079: * @deprecated
080: */
081: ReplicationImpl i_replication;
082:
083: MigrationConnection i_migration;
084:
085: Db4oReplicationReferenceProvider _replicationReferenceProvider;
086:
087: public final DiagnosticProcessor _diagnosticProcessor;
088:
089: public boolean i_encrypt;
090: byte[] i_encryptor;
091: int i_lastEncryptorByte;
092:
093: final GenericReflector _reflector;
094:
095: private final Hashtable4 _handlerVersions = new Hashtable4(16);
096:
097: private LatinStringIO _stringIO;
098:
099: public ReflectClass ICLASS_COMPARE;
100: ReflectClass ICLASS_DB4OTYPE;
101: ReflectClass ICLASS_DB4OTYPEIMPL;
102: public ReflectClass ICLASS_INTERNAL;
103: ReflectClass ICLASS_UNVERSIONED;
104: public ReflectClass ICLASS_OBJECT;
105: ReflectClass ICLASS_OBJECTCONTAINER;
106: public ReflectClass ICLASS_STATICCLASS;
107: public ReflectClass ICLASS_STRING;
108: ReflectClass ICLASS_TRANSIENTCLASS;
109:
110: HandlerRegistry(final ObjectContainerBase container,
111: byte stringEncoding, GenericReflector reflector) {
112:
113: _stringIO = LatinStringIO.forEncoding(stringEncoding);
114:
115: _container = container;
116: container._handlers = this ;
117:
118: _reflector = reflector;
119: _diagnosticProcessor = container.configImpl()
120: .diagnosticProcessor();
121:
122: initClassReflectors(reflector);
123:
124: _indexes = new SharedIndexedFields(container);
125:
126: _virtualFields[0] = _indexes._version;
127: _virtualFields[1] = _indexes._uUID;
128:
129: registerBuiltinHandlers();
130:
131: registerPlatformTypes();
132:
133: initArrayHandlers();
134: }
135:
136: private void initArrayHandlers() {
137: UntypedFieldHandler handler = untypedHandler();
138: ReflectClass classReflector = handler.classReflector();
139:
140: i_anyArray = new PrimitiveFieldHandler(_container,
141: new ArrayHandler(_container, handler, false),
142: Handlers4.ANY_ARRAY_ID, classReflector);
143: _classMetadata.put(Handlers4.ANY_ARRAY_ID, i_anyArray);
144:
145: i_anyArrayN = new PrimitiveFieldHandler(_container,
146: new MultidimensionalArrayHandler(_container, handler,
147: false), Handlers4.ANY_ARRAY_N_ID,
148: classReflector);
149:
150: _classMetadata.put(Handlers4.ANY_ARRAY_N_ID, i_anyArrayN);
151: }
152:
153: private void registerPlatformTypes() {
154: NetTypeHandler[] handlers = Platform4.types(_container);
155: for (int i = 0; i < handlers.length; i++) {
156: handlers[i].initialize();
157: GenericConverter converter = (handlers[i] instanceof GenericConverter) ? (GenericConverter) handlers[i]
158: : null;
159: registerBuiltinHandler(handlers[i].getID(), handlers[i],
160: true, handlers[i].getName(), converter);
161: }
162: }
163:
164: private void registerBuiltinHandlers() {
165:
166: IntHandler intHandler = new IntHandler(_container);
167: registerBuiltinHandler(Handlers4.INT_ID, intHandler);
168: registerHandlerVersion(intHandler, 0, new IntHandler0(
169: _container));
170:
171: LongHandler longHandler = new LongHandler(_container);
172: registerBuiltinHandler(Handlers4.LONG_ID, longHandler);
173: registerHandlerVersion(longHandler, 0, new LongHandler0(
174: _container));
175:
176: FloatHandler floatHandler = new FloatHandler(_container);
177: registerBuiltinHandler(Handlers4.FLOAT_ID, floatHandler);
178: registerHandlerVersion(floatHandler, 0, new FloatHandler0(
179: _container));
180:
181: BooleanHandler booleanHandler = new BooleanHandler(_container);
182: registerBuiltinHandler(Handlers4.BOOLEAN_ID, booleanHandler);
183: // TODO: Are we missing a boolean handler version?
184:
185: DoubleHandler doubleHandler = new DoubleHandler(_container);
186: registerBuiltinHandler(Handlers4.DOUBLE_ID, doubleHandler);
187: registerHandlerVersion(doubleHandler, 0, new DoubleHandler0(
188: _container));
189:
190: ByteHandler byteHandler = new ByteHandler(_container);
191: registerBuiltinHandler(Handlers4.BYTE_ID, byteHandler);
192: // TODO: Are we missing a byte handler version?
193:
194: CharHandler charHandler = new CharHandler(_container);
195: registerBuiltinHandler(Handlers4.CHAR_ID, charHandler);
196: // TODO: Are we missing a char handler version?
197:
198: ShortHandler shortHandler = new ShortHandler(_container);
199: registerBuiltinHandler(Handlers4.SHORT_ID, shortHandler);
200: registerHandlerVersion(shortHandler, 0, new ShortHandler0(
201: _container));
202:
203: _stringHandler = new StringHandler2(_container);
204: registerBuiltinHandler(Handlers4.STRING_ID, _stringHandler);
205: registerHandlerVersion(_stringHandler, 0, new StringHandler0(
206: _stringHandler));
207:
208: DateHandler dateHandler = new DateHandler(_container);
209: registerBuiltinHandler(Handlers4.DATE_ID, dateHandler);
210: registerHandlerVersion(dateHandler, 0, new DateHandler0(
211: _container));
212:
213: UntypedFieldHandler untypedFieldHandler = new UntypedFieldHandler(
214: _container);
215: registerBuiltinHandler(Handlers4.UNTYPED_ID,
216: untypedFieldHandler, false, null, null);
217: registerHandlerVersion(untypedFieldHandler, 0,
218: new UntypedFieldHandler0(_container));
219: }
220:
221: private void registerBuiltinHandler(int id,
222: BuiltinTypeHandler handler) {
223: registerBuiltinHandler(id, handler, true, handler
224: .classReflector().getName(), null);
225: }
226:
227: private void registerBuiltinHandler(int id,
228: BuiltinTypeHandler handler, boolean registerPrimitiveClass,
229: String primitiveName, GenericConverter converter) {
230:
231: if (registerPrimitiveClass) {
232: _reflector.registerPrimitiveClass(id, primitiveName,
233: converter);
234: }
235:
236: ReflectClass classReflector = handler.classReflector();
237:
238: _handlers.put(id, handler);
239: _classes.put(id, classReflector);
240:
241: PrimitiveFieldHandler primitiveFieldHandler = new PrimitiveFieldHandler(
242: _container, handler, id, classReflector);
243: _classMetadata.put(id, primitiveFieldHandler);
244: map(id, primitiveFieldHandler, classReflector);
245:
246: if (!Deploy.csharp) {
247: if (handler instanceof PrimitiveHandler) {
248: PrimitiveHandler primitiveHandler = (PrimitiveHandler) handler;
249: ReflectClass primitiveClassReflector = primitiveHandler
250: .primitiveClassReflector();
251: if (primitiveClassReflector != null) {
252: map(0, primitiveFieldHandler,
253: primitiveClassReflector);
254: }
255: }
256: }
257:
258: if (id > _highestBuiltinTypeID) {
259: _highestBuiltinTypeID = id;
260: }
261: }
262:
263: private void map(int id, TypeHandler4 handler,
264: ReflectClass classReflector) {
265: _mapReflectorToHandler.put(classReflector, handler);
266: _mapHandlerToReflector.put(handler, classReflector);
267: if (id != 0) {
268: _ids.put(handler, new Integer(id));
269: }
270: }
271:
272: private void registerHandlerVersion(TypeHandler4 handler,
273: int version, TypeHandler4 replacement) {
274: _handlerVersions.put(new HandlerVersionKey(handler, version),
275: replacement);
276: }
277:
278: public TypeHandler4 correctHandlerVersion(TypeHandler4 handler,
279: int version) {
280: TypeHandler4 replacement = (TypeHandler4) _handlerVersions
281: .get(new HandlerVersionKey(handler, version));
282: if (replacement != null) {
283: return replacement;
284: }
285: if (handler instanceof MultidimensionalArrayHandler
286: && (version == 0)) {
287: return new MultidimensionalArrayHandler0(handler);
288: }
289: if (handler instanceof ArrayHandler && (version == 0)) {
290: return new ArrayHandler0(handler);
291: }
292: return handler;
293: }
294:
295: int arrayType(Object a_object) {
296: ReflectClass claxx = _container.reflector().forObject(a_object);
297: if (!claxx.isArray()) {
298: return 0;
299: }
300: if (_container.reflector().array().isNDimensional(claxx)) {
301: return Const4.TYPE_NARRAY;
302: }
303: return Const4.TYPE_ARRAY;
304: }
305:
306: boolean createConstructor(final ReflectClass claxx,
307: boolean skipConstructor) {
308:
309: if (claxx == null) {
310: return false;
311: }
312:
313: if (claxx.isAbstract() || claxx.isInterface()) {
314: return true;
315: }
316:
317: if (!Platform4.callConstructor()) {
318: if (claxx.skipConstructor(skipConstructor, _container
319: .config().testConstructors())) {
320: return true;
321: }
322: }
323:
324: if (!_container.configImpl().testConstructors()) {
325: return true;
326: }
327:
328: if (claxx.newInstance() != null) {
329: return true;
330: }
331:
332: if (_container.reflector().constructorCallsSupported()) {
333: Tree sortedConstructors = sortConstructorsByParamsCount(claxx);
334: return findConstructor(claxx, sortedConstructors);
335: }
336: return false;
337: }
338:
339: private boolean findConstructor(final ReflectClass claxx,
340: Tree sortedConstructors) {
341: if (sortedConstructors == null) {
342: return false;
343: }
344:
345: Iterator4 iter = new TreeNodeIterator(sortedConstructors);
346: while (iter.moveNext()) {
347: Object obj = iter.current();
348: ReflectConstructor constructor = (ReflectConstructor) ((TreeIntObject) obj)._object;
349: ReflectClass[] paramTypes = constructor.getParameterTypes();
350: Object[] params = new Object[paramTypes.length];
351: for (int j = 0; j < params.length; j++) {
352: params[j] = nullValue(paramTypes[j]);
353: }
354: Object res = constructor.newInstance(params);
355: if (res != null) {
356: claxx.useConstructor(constructor, params);
357: return true;
358: }
359: }
360: return false;
361: }
362:
363: private Object nullValue(ReflectClass clazz) {
364: for (int k = 1; k <= PRIMITIVECOUNT; k++) {
365: PrimitiveHandler handler = (PrimitiveHandler) handlerForID(k);
366: if (clazz.equals(handler.primitiveClassReflector())) {
367: return handler.primitiveNull();
368: }
369: }
370: return null;
371: }
372:
373: private Tree sortConstructorsByParamsCount(final ReflectClass claxx) {
374: ReflectConstructor[] constructors = claxx
375: .getDeclaredConstructors();
376:
377: Tree sortedConstructors = null;
378:
379: // sort constructors by parameter count
380: for (int i = 0; i < constructors.length; i++) {
381: constructors[i].setAccessible();
382: int parameterCount = constructors[i].getParameterTypes().length;
383: sortedConstructors = Tree.add(sortedConstructors,
384: new TreeIntObject(i + constructors.length
385: * parameterCount, constructors[i]));
386: }
387: return sortedConstructors;
388: }
389:
390: public final void decrypt(Buffer reader) {
391: if (i_encrypt) {
392: int encryptorOffSet = i_lastEncryptorByte;
393: byte[] bytes = reader._buffer;
394: for (int i = reader.length() - 1; i >= 0; i--) {
395: bytes[i] += i_encryptor[encryptorOffSet];
396: if (encryptorOffSet == 0) {
397: encryptorOffSet = i_lastEncryptorByte;
398: } else {
399: encryptorOffSet--;
400: }
401: }
402: }
403: }
404:
405: public final void encrypt(Buffer reader) {
406: if (i_encrypt) {
407: byte[] bytes = reader._buffer;
408: int encryptorOffSet = i_lastEncryptorByte;
409: for (int i = reader.length() - 1; i >= 0; i--) {
410: bytes[i] -= i_encryptor[encryptorOffSet];
411: if (encryptorOffSet == 0) {
412: encryptorOffSet = i_lastEncryptorByte;
413: } else {
414: encryptorOffSet--;
415: }
416: }
417: }
418: }
419:
420: public void oldEncryptionOff() {
421: i_encrypt = false;
422: i_encryptor = null;
423: i_lastEncryptorByte = 0;
424: _container.configImpl().oldEncryptionOff();
425: }
426:
427: public final ReflectClass classForID(int id) {
428: return (ReflectClass) _classes.get(id);
429: }
430:
431: public final TypeHandler4 handlerForID(int id) {
432: return (TypeHandler4) _handlers.get(id);
433: }
434:
435: public final int handlerID(TypeHandler4 handler) {
436: if (handler instanceof ClassMetadata) {
437: return ((ClassMetadata) handler).getID();
438: }
439: Object idAsInt = _ids.get(handler);
440: if (idAsInt == null) {
441: return 0;
442: }
443: return ((Integer) idAsInt).intValue();
444: }
445:
446: // TODO: Interfaces should be handled by the ANY handler but we
447: // need to write the code to migrate from the old field handler to the new
448: public final TypeHandler4 handlerForClass(
449: ObjectContainerBase container, ReflectClass clazz) {
450: return classMetadataForClass(container, clazz).typeHandler();
451: }
452:
453: public final ClassMetadata classMetadataForClass(
454: ObjectContainerBase container, ReflectClass clazz) {
455: if (clazz == null) {
456: return null;
457: }
458: ReflectClass baseType = Handlers4.baseType(clazz);
459: ClassMetadata classMetadata = classMetadataForClass(baseType);
460: if (classMetadata != null) {
461: return classMetadata;
462: }
463: return container.produceClassMetadata(baseType);
464: }
465:
466: public UntypedFieldHandler untypedHandler() {
467: return (UntypedFieldHandler) handlerForID(Handlers4.UNTYPED_ID);
468: }
469:
470: private void initClassReflectors(GenericReflector reflector) {
471: ICLASS_COMPARE = reflector.forClass(Const4.CLASS_COMPARE);
472: ICLASS_DB4OTYPE = reflector.forClass(Const4.CLASS_DB4OTYPE);
473: ICLASS_DB4OTYPEIMPL = reflector
474: .forClass(Const4.CLASS_DB4OTYPEIMPL);
475: ICLASS_INTERNAL = reflector.forClass(Const4.CLASS_INTERNAL);
476: ICLASS_UNVERSIONED = reflector
477: .forClass(Const4.CLASS_UNVERSIONED);
478: ICLASS_OBJECT = reflector.forClass(Const4.CLASS_OBJECT);
479: ICLASS_OBJECTCONTAINER = reflector
480: .forClass(Const4.CLASS_OBJECTCONTAINER);
481: ICLASS_STATICCLASS = reflector
482: .forClass(Const4.CLASS_STATICCLASS);
483: ICLASS_STRING = reflector.forClass(String.class);
484: ICLASS_TRANSIENTCLASS = reflector
485: .forClass(Const4.CLASS_TRANSIENTCLASS);
486:
487: Platform4.registerCollections(reflector);
488: }
489:
490: void initEncryption(Config4Impl a_config) {
491: if (a_config.encrypt() && a_config.password() != null
492: && a_config.password().length() > 0) {
493: i_encrypt = true;
494: i_encryptor = new byte[a_config.password().length()];
495: for (int i = 0; i < i_encryptor.length; i++) {
496: i_encryptor[i] = (byte) (a_config.password().charAt(i) & 0xff);
497: }
498: i_lastEncryptorByte = a_config.password().length() - 1;
499: return;
500: }
501:
502: oldEncryptionOff();
503: }
504:
505: static Db4oTypeImpl getDb4oType(ReflectClass clazz) {
506: for (int i = 0; i < _db4oTypes.length; i++) {
507: if (clazz.isInstance(_db4oTypes[i])) {
508: return _db4oTypes[i];
509: }
510: }
511: return null;
512: }
513:
514: public ClassMetadata classMetadataForId(int id) {
515: return (ClassMetadata) _classMetadata.get(id);
516: }
517:
518: ClassMetadata classMetadataForClass(ReflectClass clazz) {
519: if (clazz == null) {
520: return null;
521: }
522: if (clazz.isArray()) {
523: if (_container.reflector().array().isNDimensional(clazz)) {
524: return i_anyArrayN;
525: }
526: return i_anyArray;
527: }
528: return (ClassMetadata) _mapReflectorToHandler.get(clazz);
529: }
530:
531: public ReflectClass classReflectorForHandler(TypeHandler4 handler) {
532: return (ReflectClass) _mapHandlerToReflector.get(handler);
533: }
534:
535: public boolean isSecondClass(Object a_object) {
536: if (a_object != null) {
537: ReflectClass claxx = _container.reflector().forObject(
538: a_object);
539: if (_mapReflectorToHandler.get(claxx) != null) {
540: return true;
541: }
542: if (Deploy.csharp) {
543: return Platform4.isValueType(claxx);
544: }
545: }
546: return false;
547: }
548:
549: public boolean isSystemHandler(int id) {
550: return id <= _highestBuiltinTypeID;
551: }
552:
553: public void migrationConnection(MigrationConnection mgc) {
554: i_migration = mgc;
555: }
556:
557: public MigrationConnection migrationConnection() {
558: return i_migration;
559: }
560:
561: /**
562: * @deprecated
563: */
564: public void replication(ReplicationImpl impl) {
565: i_replication = impl;
566: }
567:
568: /**
569: * @deprecated
570: */
571: public ReplicationImpl replication() {
572: return i_replication;
573: }
574:
575: public VirtualFieldMetadata virtualFieldByName(String name) {
576: for (int i = 0; i < _virtualFields.length; i++) {
577: if (name.equals(_virtualFields[i].getName())) {
578: return _virtualFields[i];
579: }
580: }
581: return null;
582: }
583:
584: public boolean isVariableLength(TypeHandler4 handler) {
585: return handler instanceof VariableLengthTypeHandler;
586: }
587:
588: public SharedIndexedFields indexes() {
589: return _indexes;
590: }
591:
592: public LatinStringIO stringIO() {
593: return _stringIO;
594: }
595:
596: public void stringIO(LatinStringIO io) {
597: _stringIO = io;
598: }
599: }
|