Source Code Cross Referenced for FieldMetadata.java in  » Database-DBMS » db4o-6.4 » com » db4o » internal » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db4o 6.4 » com.db4o.internal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Copyright (C) 2004 - 2007  db4objects Inc.  http://www.db4o.com
0002:
0003:        This file is part of the db4o open source object database.
0004:
0005:        db4o is free software; you can redistribute it and/or modify it under
0006:        the terms of version 2 of the GNU General Public License as published
0007:        by the Free Software Foundation and as clarified by db4objects' GPL 
0008:        interpretation policy, available at
0009:        http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
0010:        Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
0011:        Suite 350, San Mateo, CA 94403, USA.
0012:
0013:        db4o is distributed in the hope that it will be useful, but WITHOUT ANY
0014:        WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015:        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0016:        for more details.
0017:
0018:        You should have received a copy of the GNU General Public License along
0019:        with this program; if not, write to the Free Software Foundation, Inc.,
0020:        59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */
0021:        package com.db4o.internal;
0022:
0023:        import com.db4o.*;
0024:        import com.db4o.config.*;
0025:        import com.db4o.ext.*;
0026:        import com.db4o.foundation.*;
0027:        import com.db4o.internal.btree.*;
0028:        import com.db4o.internal.handlers.*;
0029:        import com.db4o.internal.marshall.*;
0030:        import com.db4o.internal.query.processor.*;
0031:        import com.db4o.internal.slots.*;
0032:        import com.db4o.reflect.*;
0033:        import com.db4o.reflect.generic.*;
0034:
0035:        /**
0036:         * @exclude
0037:         */
0038:        public class FieldMetadata implements  StoredField {
0039:
0040:            private ClassMetadata _containingClass;
0041:
0042:            //  position in ClassMetadata i_fields
0043:            private int _arrayPosition;
0044:
0045:            private String _name;
0046:
0047:            private boolean _isArray;
0048:
0049:            private boolean _isNArray;
0050:
0051:            private boolean _isPrimitive;
0052:
0053:            private ReflectField _javaField;
0054:
0055:            TypeHandler4 _handler;
0056:
0057:            protected int _handlerID;
0058:
0059:            private int _state;
0060:
0061:            private static final int NOT_LOADED = 0;
0062:
0063:            private static final int UNAVAILABLE = -1;
0064:
0065:            private static final int AVAILABLE = 1;
0066:
0067:            private Config4Field _config;
0068:
0069:            private Db4oTypeImpl _db4oType;
0070:
0071:            private int _linkLength;
0072:
0073:            private BTree _index;
0074:
0075:            static final FieldMetadata[] EMPTY_ARRAY = new FieldMetadata[0];
0076:
0077:            public FieldMetadata(ClassMetadata classMetadata) {
0078:                _containingClass = classMetadata;
0079:            }
0080:
0081:            FieldMetadata(ClassMetadata containingClass,
0082:                    ObjectTranslator translator) {
0083:                // for TranslatedFieldMetadata only
0084:                this (containingClass);
0085:                init(containingClass, translator.getClass().getName());
0086:                _state = AVAILABLE;
0087:                ObjectContainerBase stream = container();
0088:                _handler = stream._handlers.handlerForClass(stream, stream
0089:                        .reflector()
0090:                        .forClass(translatorStoredClass(translator)));
0091:            }
0092:
0093:            protected final Class translatorStoredClass(
0094:                    ObjectTranslator translator) {
0095:                try {
0096:                    return translator.storedClass();
0097:                } catch (RuntimeException e) {
0098:                    throw new ReflectException(e);
0099:                }
0100:            }
0101:
0102:            FieldMetadata(ClassMetadata containingClass,
0103:                    ObjectMarshaller marshaller) {
0104:                // for CustomMarshallerFieldMetadata only
0105:                this (containingClass);
0106:                init(containingClass, marshaller.getClass().getName());
0107:                _state = AVAILABLE;
0108:                _handler = container()._handlers.untypedHandler();
0109:            }
0110:
0111:            FieldMetadata(ClassMetadata containingClass, ReflectField field,
0112:                    TypeHandler4 handler, int handlerID) {
0113:                this (containingClass);
0114:                init(containingClass, field.getName());
0115:                _javaField = field;
0116:                _javaField.setAccessible();
0117:                _handler = handler;
0118:                _handlerID = handlerID;
0119:
0120:                // TODO: beautify !!!  possibly pull up isPrimitive to ReflectField
0121:                boolean isPrimitive = false;
0122:                if (field instanceof  GenericField) {
0123:                    isPrimitive = ((GenericField) field).isPrimitive();
0124:                }
0125:                configure(field.getFieldType(), isPrimitive);
0126:                checkDb4oType();
0127:                _state = AVAILABLE;
0128:            }
0129:
0130:            protected FieldMetadata(int handlerID, TypeHandler4 handler) {
0131:                _handlerID = handlerID;
0132:                _handler = handler;
0133:            }
0134:
0135:            /**
0136:             * @param classMetadata
0137:             * @param oldSlot 
0138:             */
0139:            public void addFieldIndex(MarshallerFamily mf,
0140:                    ClassMetadata classMetadata, StatefulBuffer buffer,
0141:                    Slot oldSlot) throws FieldIndexException {
0142:                if (!hasIndex()) {
0143:                    incrementOffset(buffer);
0144:                    return;
0145:                }
0146:
0147:                try {
0148:                    addIndexEntry(buffer, readIndexEntry(mf, buffer));
0149:                } catch (CorruptionException exc) {
0150:                    throw new FieldIndexException(exc, this );
0151:                }
0152:            }
0153:
0154:            protected void addIndexEntry(StatefulBuffer a_bytes,
0155:                    Object indexEntry) {
0156:                addIndexEntry(a_bytes.getTransaction(), a_bytes.getID(),
0157:                        indexEntry);
0158:            }
0159:
0160:            public void addIndexEntry(Transaction trans, int parentID,
0161:                    Object indexEntry) {
0162:                if (!hasIndex()) {
0163:                    return;
0164:                }
0165:
0166:                BTree index = getIndex(trans);
0167:
0168:                // Although we checked hasIndex() already, we have to check
0169:                // again here since index creation in YapFieldUUID can be
0170:                // unsuccessful if it's called too early for PBootRecord.
0171:                if (index == null) {
0172:                    return;
0173:                }
0174:                index.add(trans, createFieldIndexKey(parentID, indexEntry));
0175:            }
0176:
0177:            private FieldIndexKey createFieldIndexKey(int parentID,
0178:                    Object indexEntry) {
0179:                Object convertedIndexEntry = indexEntryFor(indexEntry);
0180:                return new FieldIndexKey(parentID, convertedIndexEntry);
0181:            }
0182:
0183:            protected Object indexEntryFor(Object indexEntry) {
0184:                return _javaField.indexEntry(indexEntry);
0185:            }
0186:
0187:            public boolean canUseNullBitmap() {
0188:                return true;
0189:            }
0190:
0191:            // alive() checked
0192:            public Object readIndexEntry(MarshallerFamily mf,
0193:                    StatefulBuffer writer) throws CorruptionException,
0194:                    Db4oIOException {
0195:                return ((IndexableTypeHandler) _handler).readIndexEntry(mf,
0196:                        writer);
0197:            }
0198:
0199:            public void removeIndexEntry(Transaction trans, int parentID,
0200:                    Object indexEntry) {
0201:                if (!hasIndex()) {
0202:                    return;
0203:                }
0204:
0205:                if (_index == null) {
0206:                    return;
0207:                }
0208:                _index.remove(trans, createFieldIndexKey(parentID, indexEntry));
0209:            }
0210:
0211:            public boolean alive() {
0212:                if (_state == AVAILABLE) {
0213:                    return true;
0214:                }
0215:                if (_state == NOT_LOADED) {
0216:
0217:                    if (_handler == null) {
0218:
0219:                        // this may happen if the local ClassMetadataRepository
0220:                        // has not been updated from the server and presumably 
0221:                        // in some refactoring cases. 
0222:
0223:                        // We try to heal the problem by re-reading the class.
0224:
0225:                        // This could be dangerous, if the class type of a field
0226:                        // has been modified.
0227:
0228:                        // TODO: add class refactoring features
0229:
0230:                        _handler = loadJavaField1();
0231:                        checkHandlerID();
0232:                    }
0233:
0234:                    loadJavaField();
0235:
0236:                    if (_handler != null) {
0237:                        // TODO: This part is not quite correct.
0238:                        // We are using the old array information read from file to wrap.
0239:
0240:                        // If a schema evolution changes an array to a different variable,
0241:                        // we are in trouble here.
0242:                        _handler = wrapHandlerToArrays(container(), _handler);
0243:                    }
0244:
0245:                    if (_handler == null || _javaField == null) {
0246:                        _state = UNAVAILABLE;
0247:                        _javaField = null;
0248:                    } else {
0249:                        _state = AVAILABLE;
0250:                        checkDb4oType();
0251:                    }
0252:                }
0253:                return _state == AVAILABLE;
0254:            }
0255:
0256:            private void checkHandlerID() {
0257:                if (!(_handler instanceof  ClassMetadata)) {
0258:                    return;
0259:                }
0260:                ClassMetadata classMetadata = (ClassMetadata) _handler;
0261:                int id = classMetadata.getID();
0262:
0263:                if (_handlerID == 0) {
0264:                    _handlerID = id;
0265:                    return;
0266:                }
0267:                if (id > 0 && id != _handlerID) {
0268:                    // wrong type, refactoring, field should be turned off 
0269:                    _handler = null;
0270:                }
0271:            }
0272:
0273:            boolean canAddToQuery(String fieldName) {
0274:                if (!alive()) {
0275:                    return false;
0276:                }
0277:                return fieldName.equals(getName()) && containingClass() != null
0278:                        && !containingClass().isInternal();
0279:            }
0280:
0281:            public boolean canHold(ReflectClass claxx) {
0282:                // alive() is checked in QField caller
0283:                if (claxx == null) {
0284:                    return !_isPrimitive;
0285:                }
0286:                return Handlers4.handlerCanHold(_handler, claxx);
0287:            }
0288:
0289:            public Object coerce(ReflectClass claxx, Object obj) {
0290:                // alive() is checked in QField caller
0291:
0292:                if (claxx == null || obj == null) {
0293:                    return _isPrimitive ? No4.INSTANCE : obj;
0294:                }
0295:
0296:                if (_handler instanceof  PrimitiveHandler) {
0297:                    return ((PrimitiveHandler) _handler).coerce(claxx, obj);
0298:                }
0299:
0300:                if (!canHold(claxx)) {
0301:                    return No4.INSTANCE;
0302:                }
0303:
0304:                return obj;
0305:            }
0306:
0307:            public final boolean canLoadByIndex() {
0308:                if (_handler instanceof  ClassMetadata) {
0309:                    ClassMetadata yc = (ClassMetadata) _handler;
0310:                    if (yc.isArray()) {
0311:                        return false;
0312:                    }
0313:                }
0314:                return true;
0315:            }
0316:
0317:            void cascadeActivation(Transaction trans, Object onObject,
0318:                    int depth, boolean activate) {
0319:                if (!alive()) {
0320:                    return;
0321:                }
0322:                if (!(_handler instanceof  FirstClassHandler)) {
0323:                    return;
0324:                }
0325:                FirstClassHandler firstClassHandler = (FirstClassHandler) _handler;
0326:
0327:                try {
0328:                    Object cascadeTo = getOrCreate(trans, onObject);
0329:                    if (cascadeTo == null) {
0330:                        return;
0331:                    }
0332:                    firstClassHandler.cascadeActivation(trans, cascadeTo,
0333:                            depth, activate);
0334:                } catch (Exception e) {
0335:                    // FIXME: Catch all
0336:                }
0337:            }
0338:
0339:            private void checkDb4oType() {
0340:                if (_javaField != null) {
0341:                    if (container()._handlers.ICLASS_DB4OTYPE
0342:                            .isAssignableFrom(_javaField.getFieldType())) {
0343:                        _db4oType = HandlerRegistry.getDb4oType(_javaField
0344:                                .getFieldType());
0345:                    }
0346:                }
0347:            }
0348:
0349:            void collectConstraints(Transaction a_trans, QConObject a_parent,
0350:                    Object a_template, Visitor4 a_visitor) {
0351:                Object obj = getOn(a_trans, a_template);
0352:                if (obj != null) {
0353:                    Collection4 objs = Platform4.flattenCollection(a_trans
0354:                            .container(), obj);
0355:                    Iterator4 j = objs.iterator();
0356:                    while (j.moveNext()) {
0357:                        obj = j.current();
0358:                        if (obj != null) {
0359:
0360:                            if (_isPrimitive) {
0361:                                if (_handler instanceof  PrimitiveHandler) {
0362:                                    if (obj
0363:                                            .equals(((PrimitiveHandler) _handler)
0364:                                                    .primitiveNull())) {
0365:                                        return;
0366:                                    }
0367:                                }
0368:                            }
0369:
0370:                            if (Deploy.csharp) {
0371:                                if (Platform4.ignoreAsConstraint(obj)) {
0372:                                    return;
0373:                                }
0374:                            }
0375:                            if (!a_parent.hasObjectInParentPath(obj)) {
0376:                                a_visitor.visit(new QConObject(a_trans,
0377:                                        a_parent, qField(a_trans), obj));
0378:                            }
0379:                        }
0380:                    }
0381:                }
0382:            }
0383:
0384:            public final TreeInt collectIDs(MarshallerFamily mf, TreeInt tree,
0385:                    StatefulBuffer a_bytes) throws FieldIndexException {
0386:                if (!alive()) {
0387:                    return tree;
0388:                }
0389:                if (_handler instanceof  ClassMetadata) {
0390:                    return (TreeInt) Tree.add(tree, new TreeInt(a_bytes
0391:                            .readInt()));
0392:                } else if (_handler instanceof  ArrayHandler) {
0393:                    return ((ArrayHandler) _handler).collectIDs(mf, tree,
0394:                            a_bytes);
0395:                }
0396:                return tree;
0397:            }
0398:
0399:            void configure(ReflectClass clazz, boolean isPrimitive) {
0400:                _isArray = clazz.isArray();
0401:                if (_isArray) {
0402:                    ReflectArray reflectArray = container().reflector().array();
0403:                    _isNArray = reflectArray.isNDimensional(clazz);
0404:                    _isPrimitive = reflectArray.getComponentType(clazz)
0405:                            .isPrimitive();
0406:                    _handler = wrapHandlerToArrays(container(), _handler);
0407:                } else {
0408:                    _isPrimitive = isPrimitive | clazz.isPrimitive();
0409:                }
0410:            }
0411:
0412:            private final TypeHandler4 wrapHandlerToArrays(
0413:                    ObjectContainerBase container, TypeHandler4 handler) {
0414:                if (_isNArray) {
0415:                    return new MultidimensionalArrayHandler(container, handler,
0416:                            arraysUsePrimitiveClassReflector());
0417:                }
0418:                if (_isArray) {
0419:                    return new ArrayHandler(container, handler,
0420:                            arraysUsePrimitiveClassReflector());
0421:                }
0422:                return handler;
0423:            }
0424:
0425:            private boolean arraysUsePrimitiveClassReflector() {
0426:                return Deploy.csharp ? false : _isPrimitive;
0427:            }
0428:
0429:            void deactivate(Transaction a_trans, Object a_onObject, int a_depth) {
0430:                if (!alive()) {
0431:                    return;
0432:                }
0433:                boolean isEnumClass = _containingClass.isEnum();
0434:                if (_isPrimitive && !_isArray) {
0435:                    if (!isEnumClass) {
0436:                        _javaField.set(a_onObject,
0437:                                ((PrimitiveHandler) _handler).primitiveNull());
0438:                    }
0439:                    return;
0440:                }
0441:                if (a_depth > 0) {
0442:                    cascadeActivation(a_trans, a_onObject, a_depth, false);
0443:                }
0444:                if (!isEnumClass) {
0445:                    _javaField.set(a_onObject, null);
0446:                }
0447:            }
0448:
0449:            /** @param isUpdate */
0450:            public void delete(MarshallerFamily mf, StatefulBuffer a_bytes,
0451:                    boolean isUpdate) throws FieldIndexException {
0452:                if (!checkAlive(a_bytes)) {
0453:                    return;
0454:                }
0455:
0456:                try {
0457:                    removeIndexEntry(mf, a_bytes);
0458:                    boolean dotnetValueType = false;
0459:                    if (Deploy.csharp) {
0460:                        dotnetValueType = Platform4
0461:                                .isValueType(getStoredType());
0462:                    }
0463:                    if ((_config != null && _config.cascadeOnDelete()
0464:                            .definiteYes())
0465:                            || dotnetValueType) {
0466:                        int preserveCascade = a_bytes.cascadeDeletes();
0467:                        a_bytes.setCascadeDeletes(1);
0468:                        _handler.deleteEmbedded(mf, a_bytes);
0469:                        a_bytes.setCascadeDeletes(preserveCascade);
0470:                    } else if (_config != null
0471:                            && _config.cascadeOnDelete().definiteNo()) {
0472:                        int preserveCascade = a_bytes.cascadeDeletes();
0473:                        a_bytes.setCascadeDeletes(0);
0474:                        _handler.deleteEmbedded(mf, a_bytes);
0475:                        a_bytes.setCascadeDeletes(preserveCascade);
0476:                    } else {
0477:                        _handler.deleteEmbedded(mf, a_bytes);
0478:                    }
0479:                } catch (CorruptionException exc) {
0480:                    throw new FieldIndexException(exc, this );
0481:                }
0482:            }
0483:
0484:            private final void removeIndexEntry(MarshallerFamily mf,
0485:                    StatefulBuffer a_bytes) throws CorruptionException,
0486:                    Db4oIOException {
0487:                if (!hasIndex()) {
0488:                    return;
0489:                }
0490:                int offset = a_bytes._offset;
0491:                Object obj = readIndexEntry(mf, a_bytes);
0492:                removeIndexEntry(a_bytes.getTransaction(), a_bytes.getID(), obj);
0493:                a_bytes._offset = offset;
0494:            }
0495:
0496:            public boolean equals(Object obj) {
0497:                if (obj instanceof  FieldMetadata) {
0498:                    FieldMetadata yapField = (FieldMetadata) obj;
0499:                    yapField.alive();
0500:                    alive();
0501:                    return yapField._isPrimitive == _isPrimitive
0502:                            && yapField._handler.equals(_handler)
0503:                            && yapField._name.equals(_name);
0504:                }
0505:                return false;
0506:            }
0507:
0508:            public int hashCode() {
0509:                return _name.hashCode();
0510:            }
0511:
0512:            public final Object get(Object onObject) {
0513:                return get(null, onObject);
0514:            }
0515:
0516:            public final Object get(Transaction trans, Object onObject) {
0517:                if (_containingClass == null) {
0518:                    return null;
0519:                }
0520:                ObjectContainerBase container = container();
0521:                if (container == null) {
0522:                    return null;
0523:                }
0524:                synchronized (container._lock) {
0525:
0526:                    // FIXME: The following is not really transactional.
0527:                    //        This will work OK for normal C/S and for
0528:                    //        single local mode but the transaction will
0529:                    //        be wrong for MTOC.
0530:                    if (trans == null) {
0531:                        trans = container.transaction();
0532:                    }
0533:
0534:                    container.checkClosed();
0535:                    ObjectReference ref = trans.referenceForObject(onObject);
0536:                    if (ref == null) {
0537:                        return null;
0538:                    }
0539:                    int id = ref.getID();
0540:                    if (id <= 0) {
0541:                        return null;
0542:                    }
0543:                    UnmarshallingContext context = new UnmarshallingContext(
0544:                            trans, ref, Const4.ADD_TO_ID_TREE, false);
0545:                    return context.readFieldValue(this );
0546:                }
0547:            }
0548:
0549:            public String getName() {
0550:                return _name;
0551:            }
0552:
0553:            public final ClassMetadata handlerClassMetadata(
0554:                    ObjectContainerBase container) {
0555:                // alive needs to be checked by all callers: Done
0556:                TypeHandler4 handler = baseTypeHandler();
0557:                if (Handlers4.handlesSimple(handler)) {
0558:                    return container._handlers.classMetadataForId(handlerID());
0559:                }
0560:                return (ClassMetadata) handler;
0561:            }
0562:
0563:            private TypeHandler4 baseTypeHandler() {
0564:                return Handlers4.baseTypeHandler(_handler);
0565:            }
0566:
0567:            public TypeHandler4 getHandler() {
0568:                // alive needs to be checked by all callers: Done
0569:                return _handler;
0570:            }
0571:
0572:            public int handlerID() {
0573:                // alive needs to be checked by all callers: Done
0574:                return _handlerID;
0575:            }
0576:
0577:            /** @param trans */
0578:            public Object getOn(Transaction trans, Object onObject) {
0579:                if (alive()) {
0580:                    return _javaField.get(onObject);
0581:                }
0582:                return null;
0583:            }
0584:
0585:            /**
0586:             * dirty hack for com.db4o.types some of them need to be set automatically
0587:             * TODO: Derive from YapField for Db4oTypes
0588:             */
0589:            public Object getOrCreate(Transaction trans, Object onObject) {
0590:                if (!alive()) {
0591:                    return null;
0592:                }
0593:                Object obj = _javaField.get(onObject);
0594:                if (_db4oType != null && obj == null) {
0595:                    obj = _db4oType.createDefault(trans);
0596:                    _javaField.set(onObject, obj);
0597:                }
0598:                return obj;
0599:            }
0600:
0601:            public final ClassMetadata containingClass() {
0602:                // alive needs to be checked by all callers: Done
0603:                return _containingClass;
0604:            }
0605:
0606:            public ReflectClass getStoredType() {
0607:                if (_javaField == null) {
0608:                    return null;
0609:                }
0610:                return Handlers4.baseType(_javaField.getFieldType());
0611:            }
0612:
0613:            public ObjectContainerBase container() {
0614:                if (_containingClass == null) {
0615:                    return null;
0616:                }
0617:                return _containingClass.container();
0618:            }
0619:
0620:            public boolean hasConfig() {
0621:                return _config != null;
0622:            }
0623:
0624:            public boolean hasIndex() {
0625:                // alive needs to be checked by all callers: Done
0626:                return _index != null;
0627:            }
0628:
0629:            public final void incrementOffset(Buffer buffer) {
0630:                buffer.incrementOffset(linkLength());
0631:            }
0632:
0633:            public final void init(ClassMetadata containingClass, String name) {
0634:                _containingClass = containingClass;
0635:                _name = name;
0636:                initIndex(containingClass, name);
0637:            }
0638:
0639:            final void initIndex(ClassMetadata containingClass, String name) {
0640:                if (containingClass.config() == null) {
0641:                    return;
0642:                }
0643:                _config = containingClass.config().configField(name);
0644:                if (Debug.configureAllFields && _config == null) {
0645:                    _config = (Config4Field) containingClass.config()
0646:                            .objectField(_name);
0647:                }
0648:            }
0649:
0650:            public void init(int handlerID, boolean isPrimitive,
0651:                    boolean isArray, boolean isNArray) {
0652:                _handlerID = handlerID;
0653:                _isPrimitive = isPrimitive;
0654:                _isArray = isArray;
0655:                _isNArray = isNArray;
0656:            }
0657:
0658:            private boolean _initialized = false;
0659:
0660:            final void initConfigOnUp(Transaction trans) {
0661:                if (_config != null && !_initialized) {
0662:                    _initialized = true;
0663:                    _config.initOnUp(trans, this );
0664:                }
0665:            }
0666:
0667:            public void instantiate(UnmarshallingContext context) {
0668:                if (!checkAlive(context.buffer())) {
0669:                    return;
0670:                }
0671:                Object toSet = read(context);
0672:                informAboutTransaction(toSet, context.transaction());
0673:                set(context.persistentObject(), toSet);
0674:            }
0675:
0676:            private boolean checkAlive(Buffer buffer) {
0677:                boolean alive = alive();
0678:                if (!alive) {
0679:                    incrementOffset(buffer);
0680:                }
0681:                return alive;
0682:            }
0683:
0684:            private void informAboutTransaction(Object obj, Transaction trans) {
0685:                if (_db4oType != null && obj != null) {
0686:                    ((Db4oTypeImpl) obj).setTrans(trans);
0687:                }
0688:            }
0689:
0690:            public boolean isArray() {
0691:                return _isArray;
0692:            }
0693:
0694:            protected int linkLength() {
0695:                alive();
0696:
0697:                if (_linkLength == 0) {
0698:                    _linkLength = calculateLinkLength();
0699:                }
0700:                return _linkLength;
0701:            }
0702:
0703:            private int calculateLinkLength() {
0704:                if (_handler == null) {
0705:                    // must be ClassMetadata
0706:                    return Const4.ID_LENGTH;
0707:                }
0708:                if (_handler instanceof  PersistentBase) {
0709:                    return ((PersistentBase) _handler).linkLength();
0710:                }
0711:                if (_handler instanceof  PrimitiveHandler) {
0712:                    return ((PrimitiveHandler) _handler).linkLength();
0713:                }
0714:                if (_handler instanceof  VariableLengthTypeHandler) {
0715:                    return ((VariableLengthTypeHandler) _handler).linkLength();
0716:                }
0717:
0718:                // TODO: For custom handlers there will have to be a way 
0719:                //       to calculate the length in the slot.
0720:
0721:                //        Options:
0722:
0723:                //        (1) Remember when the first object is marshalled.
0724:                //        (2) Add a #defaultValue() method to TypeHandler4,
0725:                //            marshall the default value and check.
0726:                //        (3) Add a way to test the custom handler when it
0727:                //            is installed and remember the length there. 
0728:
0729:                throw new NotImplementedException();
0730:            }
0731:
0732:            public void loadHandler(ObjectContainerBase a_stream) {
0733:                _handler = a_stream.handlerByID(_handlerID);
0734:            }
0735:
0736:            private void loadJavaField() {
0737:                TypeHandler4 handler = loadJavaField1();
0738:                if (handler == null || (!handler.equals(_handler))) {
0739:                    _javaField = null;
0740:                    _state = UNAVAILABLE;
0741:                }
0742:            }
0743:
0744:            private TypeHandler4 loadJavaField1() {
0745:                ReflectClass claxx = _containingClass.classReflector();
0746:                if (claxx == null) {
0747:                    return null;
0748:                }
0749:                _javaField = claxx.getDeclaredField(_name);
0750:                if (_javaField == null) {
0751:                    return null;
0752:                }
0753:                _javaField.setAccessible();
0754:                ObjectContainerBase container = container();
0755:                container.showInternalClasses(true);
0756:                TypeHandler4 handlerForClass = container._handlers
0757:                        .handlerForClass(container, _javaField.getFieldType());
0758:                container.showInternalClasses(false);
0759:                return handlerForClass;
0760:            }
0761:
0762:            private int adjustUpdateDepth(Object obj, int updateDepth) {
0763:                int minimumUpdateDepth = 1;
0764:                if (_containingClass.isCollection(obj)) {
0765:                    GenericReflector reflector = _containingClass.reflector();
0766:                    minimumUpdateDepth = reflector
0767:                            .collectionUpdateDepth(reflector.forObject(obj));
0768:                }
0769:                if (updateDepth < minimumUpdateDepth) {
0770:                    return minimumUpdateDepth;
0771:                }
0772:                return updateDepth;
0773:            }
0774:
0775:            private boolean cascadeOnUpdate(
0776:                    Config4Class parentClassConfiguration) {
0777:                return ((parentClassConfiguration != null && (parentClassConfiguration
0778:                        .cascadeOnUpdate().definiteYes())) || (_config != null && (_config
0779:                        .cascadeOnUpdate().definiteYes())));
0780:            }
0781:
0782:            public void marshall(MarshallingContext context, Object obj) {
0783:                // alive needs to be checked by all callers: Done
0784:                int updateDepth = context.updateDepth();
0785:                if (obj != null
0786:                        && cascadeOnUpdate(context.classConfiguration())) {
0787:                    context.updateDepth(adjustUpdateDepth(obj, updateDepth));
0788:                }
0789:                context.createIndirection(_handler);
0790:                _handler.write(context, obj);
0791:                context.updateDepth(updateDepth);
0792:                if (hasIndex()) {
0793:                    context.addIndexEntry(this , obj);
0794:                }
0795:            }
0796:
0797:            public boolean needsArrayAndPrimitiveInfo() {
0798:                return true;
0799:            }
0800:
0801:            public boolean needsHandlerId() {
0802:                return true;
0803:            }
0804:
0805:            public Comparable4 prepareComparison(Object obj) {
0806:                if (alive()) {
0807:                    _handler.prepareComparison(obj);
0808:                    return _handler;
0809:                }
0810:                return null;
0811:            }
0812:
0813:            public QField qField(Transaction a_trans) {
0814:                int yapClassID = 0;
0815:                if (_containingClass != null) {
0816:                    yapClassID = _containingClass.getID();
0817:                }
0818:                return new QField(a_trans, _name, this , yapClassID,
0819:                        _arrayPosition);
0820:            }
0821:
0822:            public Object read(InternalReadContext context) {
0823:                if (!checkAlive(context.buffer())) {
0824:                    return null;
0825:                }
0826:                return context.read(_handler);
0827:            }
0828:
0829:            /**
0830:             * @param trans
0831:             * @param ref
0832:             */
0833:            public void readVirtualAttribute(Transaction trans, Buffer buffer,
0834:                    ObjectReference ref) {
0835:                incrementOffset(buffer);
0836:            }
0837:
0838:            void refresh() {
0839:                TypeHandler4 handler = loadJavaField1();
0840:                if (handler != null) {
0841:                    handler = wrapHandlerToArrays(container(), handler);
0842:                    if (handler.equals(_handler)) {
0843:                        return;
0844:                    }
0845:                }
0846:                _javaField = null;
0847:                _state = UNAVAILABLE;
0848:            }
0849:
0850:            // FIXME: needs test case
0851:            public void rename(String newName) {
0852:                ObjectContainerBase container = container();
0853:                if (!container.isClient()) {
0854:                    _name = newName;
0855:                    _containingClass.setStateDirty();
0856:                    _containingClass.write(container.systemTransaction());
0857:                } else {
0858:                    Exceptions4.throwRuntimeException(58);
0859:                }
0860:            }
0861:
0862:            public void setArrayPosition(int a_index) {
0863:                _arrayPosition = a_index;
0864:            }
0865:
0866:            public void set(Object onObject, Object obj) {
0867:                // TODO: remove the following if and check callers
0868:                if (null == _javaField)
0869:                    return;
0870:                _javaField.set(onObject, obj);
0871:            }
0872:
0873:            void setName(String a_name) {
0874:                _name = a_name;
0875:            }
0876:
0877:            boolean supportsIndex() {
0878:                return alive() && (_handler instanceof  Indexable4)
0879:                        && (!(_handler instanceof  UntypedFieldHandler));
0880:            }
0881:
0882:            public final void traverseValues(final Visitor4 userVisitor) {
0883:                if (!alive()) {
0884:                    return;
0885:                }
0886:                traverseValues(container().transaction(), userVisitor);
0887:            }
0888:
0889:            public final void traverseValues(final Transaction transaction,
0890:                    final Visitor4 userVisitor) {
0891:                if (!alive()) {
0892:                    return;
0893:                }
0894:                assertHasIndex();
0895:                ObjectContainerBase stream = transaction.container();
0896:                if (stream.isClient()) {
0897:                    Exceptions4
0898:                            .throwRuntimeException(Messages.CLIENT_SERVER_UNSUPPORTED);
0899:                }
0900:                synchronized (stream.lock()) {
0901:                    _index.traverseKeys(transaction, new Visitor4() {
0902:                        public void visit(Object obj) {
0903:                            FieldIndexKey key = (FieldIndexKey) obj;
0904:                            userVisitor.visit(((IndexableTypeHandler) _handler)
0905:                                    .indexEntryToObject(transaction, key
0906:                                            .value()));
0907:                        }
0908:                    });
0909:                }
0910:            }
0911:
0912:            private void assertHasIndex() {
0913:                if (!hasIndex()) {
0914:                    Exceptions4
0915:                            .throwRuntimeException(Messages.ONLY_FOR_INDEXED_FIELDS);
0916:                }
0917:            }
0918:
0919:            public String toString() {
0920:                StringBuffer sb = new StringBuffer();
0921:                if (_containingClass != null) {
0922:                    sb.append(_containingClass.getName());
0923:                    sb.append(".");
0924:                    sb.append(getName());
0925:                }
0926:                return sb.toString();
0927:            }
0928:
0929:            private void initIndex(Transaction systemTrans) {
0930:                initIndex(systemTrans, 0);
0931:            }
0932:
0933:            public void initIndex(Transaction systemTrans, final int id) {
0934:                if (_index != null) {
0935:                    throw new IllegalStateException();
0936:                }
0937:                if (systemTrans.container().isClient()) {
0938:                    return;
0939:                }
0940:                _index = newBTree(systemTrans, id);
0941:            }
0942:
0943:            protected final BTree newBTree(Transaction systemTrans, final int id) {
0944:                ObjectContainerBase stream = systemTrans.container();
0945:                Indexable4 indexHandler = indexHandler(stream);
0946:                if (indexHandler == null) {
0947:                    if (Debug.atHome) {
0948:                        System.err.println("Could not create index for " + this 
0949:                                + ": No index handler found");
0950:                    }
0951:                    return null;
0952:                }
0953:                return new BTree(systemTrans, id, new FieldIndexKeyHandler(
0954:                        stream, indexHandler));
0955:            }
0956:
0957:            protected Indexable4 indexHandler(ObjectContainerBase stream) {
0958:                if (_javaField == null) {
0959:                    return null;
0960:                }
0961:                ReflectClass indexType = _javaField.indexType();
0962:                TypeHandler4 classHandler = stream._handlers.handlerForClass(
0963:                        stream, indexType);
0964:                if (!(classHandler instanceof  Indexable4)) {
0965:                    return null;
0966:                }
0967:                return (Indexable4) classHandler;
0968:            }
0969:
0970:            /** @param trans */
0971:            public BTree getIndex(Transaction trans) {
0972:                return _index;
0973:            }
0974:
0975:            public boolean isVirtual() {
0976:                return false;
0977:            }
0978:
0979:            public boolean isPrimitive() {
0980:                return _isPrimitive;
0981:            }
0982:
0983:            public BTreeRange search(Transaction transaction, Object value) {
0984:                assertHasIndex();
0985:                Object transActionalValue = wrapWithTransactionContext(
0986:                        transaction, value);
0987:                BTreeNodeSearchResult lowerBound = searchLowerBound(
0988:                        transaction, transActionalValue);
0989:                BTreeNodeSearchResult upperBound = searchUpperBound(
0990:                        transaction, transActionalValue);
0991:                return lowerBound.createIncludingRange(upperBound);
0992:            }
0993:
0994:            private Object wrapWithTransactionContext(Transaction transaction,
0995:                    Object value) {
0996:                if (_handler instanceof  ClassMetadata) {
0997:                    value = ((ClassMetadata) _handler)
0998:                            .wrapWithTransactionContext(transaction, value);
0999:                }
1000:                return value;
1001:            }
1002:
1003:            private BTreeNodeSearchResult searchUpperBound(
1004:                    Transaction transaction, final Object value) {
1005:                return searchBound(transaction, Integer.MAX_VALUE, value);
1006:            }
1007:
1008:            private BTreeNodeSearchResult searchLowerBound(
1009:                    Transaction transaction, final Object value) {
1010:                return searchBound(transaction, 0, value);
1011:            }
1012:
1013:            private BTreeNodeSearchResult searchBound(Transaction transaction,
1014:                    int parentID, Object keyPart) {
1015:                return getIndex(transaction).searchLeaf(transaction,
1016:                        createFieldIndexKey(parentID, keyPart),
1017:                        SearchTarget.LOWEST);
1018:            }
1019:
1020:            public boolean rebuildIndexForClass(LocalObjectContainer stream,
1021:                    ClassMetadata yapClass) {
1022:                // FIXME: BTree traversal over index here.
1023:                long[] ids = yapClass.getIDs();
1024:                for (int i = 0; i < ids.length; i++) {
1025:                    rebuildIndexForObject(stream, yapClass, (int) ids[i]);
1026:                }
1027:                return ids.length > 0;
1028:            }
1029:
1030:            /** @param classMetadata */
1031:            protected void rebuildIndexForObject(LocalObjectContainer stream,
1032:                    final ClassMetadata classMetadata, final int objectId)
1033:                    throws FieldIndexException {
1034:                StatefulBuffer writer = stream.readWriterByID(stream
1035:                        .systemTransaction(), objectId);
1036:                if (writer != null) {
1037:                    rebuildIndexForWriter(stream, writer, objectId);
1038:                } else {
1039:                    if (Deploy.debug) {
1040:                        throw new RuntimeException(
1041:                                "Unexpected null object for ID");
1042:                    }
1043:                }
1044:            }
1045:
1046:            protected void rebuildIndexForWriter(LocalObjectContainer stream,
1047:                    StatefulBuffer writer, final int objectId) {
1048:                ObjectHeader oh = new ObjectHeader(stream, writer);
1049:                Object obj = readIndexEntryForRebuild(writer, oh);
1050:                addIndexEntry(stream.systemTransaction(), objectId, obj);
1051:            }
1052:
1053:            private Object readIndexEntryForRebuild(StatefulBuffer writer,
1054:                    ObjectHeader oh) {
1055:                return oh.objectMarshaller().readIndexEntry(oh.classMetadata(),
1056:                        oh._headerAttributes, this , writer);
1057:            }
1058:
1059:            public void dropIndex(Transaction systemTrans) {
1060:                if (_index == null) {
1061:                    return;
1062:                }
1063:                ObjectContainerBase stream = systemTrans.container();
1064:                if (stream.configImpl().messageLevel() > Const4.NONE) {
1065:                    stream.message("dropping index " + toString());
1066:                }
1067:                _index.free(systemTrans);
1068:                stream.setDirtyInSystemTransaction(containingClass());
1069:                _index = null;
1070:            }
1071:
1072:            public void defragField(MarshallerFamily mf, BufferPair readers) {
1073:                getHandler().defrag(mf, readers, true);
1074:            }
1075:
1076:            public void createIndex() {
1077:
1078:                if (hasIndex()) {
1079:                    return;
1080:                }
1081:                LocalObjectContainer container = (LocalObjectContainer) container();
1082:
1083:                if (container.configImpl().messageLevel() > Const4.NONE) {
1084:                    container.message("creating index " + toString());
1085:                }
1086:                initIndex(container.systemTransaction());
1087:                container.setDirtyInSystemTransaction(containingClass());
1088:                reindex(container);
1089:            }
1090:
1091:            private void reindex(LocalObjectContainer container) {
1092:                ClassMetadata clazz = containingClass();
1093:                if (rebuildIndexForClass(container, clazz)) {
1094:                    container.systemTransaction().commit();
1095:                }
1096:            }
1097:
1098:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.