Source Code Cross Referenced for ClassMetaData.java in  » Testing » PolePosition-0.20 » com » versant » core » metadata » 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 » Testing » PolePosition 0.20 » com.versant.core.metadata 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998 - 2005 Versant Corporation
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         * Versant Corporation - initial API and implementation
0010:         */
0011:        package com.versant.core.metadata;
0012:
0013:        import com.versant.core.jdo.QueryDetails;
0014:        import com.versant.core.metadata.parser.JdoClass;
0015:
0016:        import com.versant.core.util.classhelper.ClassHelper;
0017:        import com.versant.core.util.IntArray;
0018:
0019:        import javax.jdo.spi.PersistenceCapable;
0020:        import java.io.*;
0021:        import java.lang.reflect.Field;
0022:        import java.util.*;
0023:
0024:        import com.versant.core.common.*;
0025:
0026:        /**
0027:         * Meta data for a class that is common to all DataStore's and the enhancer.
0028:         */
0029:        public final class ClassMetaData implements  Serializable, Comparable {
0030:
0031:            /**
0032:             * These are class hierarchy level setting for specifying when a ObjectNotFoundException must be
0033:             * thrown if this instance is not found.
0034:             */
0035:            public static final int NULL_NO_ROW_PASSON = 2;
0036:            public static final int NULL_NO_ROW_TRUE = 1;
0037:            public static final int NULL_NO_ROW_FALSE = 0;
0038:
0039:            /**
0040:             * This is only used for refFields. If the ref Field is not found then return a null
0041:             * instead of a VersantObjectNotFoundException. This is a classLevel setting.
0042:             */
0043:            public int returnNullForRowNotFound;
0044:
0045:            /**
0046:             * The meta data we belong to.
0047:             */
0048:            public final ModelMetaData jmd;
0049:            /**
0050:             * The fully qualified name of the class.
0051:             */
0052:            public final String qname;
0053:            /**
0054:             * The name of the class without package.
0055:             */
0056:            public final String shortName;
0057:            /**
0058:             * The abstract schema name of the class. Default is shortName.
0059:             */
0060:            public String abstractSchemaName;
0061:            /**
0062:             * The original parsed .jdo meta data.
0063:             */
0064:            public transient JdoClass jdoClass;
0065:            /**
0066:             * The class.
0067:             */
0068:            public Class cls;
0069:            /**
0070:             * The package name with a trailing dot if not empty.
0071:             */
0072:            public String packageNameWithDot;
0073:            /**
0074:             * The unique ID for this class. This is generated from a hash of the
0075:             * fully qualified class name. Duplicates are resolved by incrementing
0076:             * the classId.
0077:             *
0078:             * @see #setClassId(int)
0079:             */
0080:            public int classId;
0081:            /**
0082:             * The classId as a String.
0083:             *
0084:             * @see #setClassId(int)
0085:             */
0086:            public String classIdString;
0087:            /**
0088:             * The index of this class in the classes array.
0089:             *
0090:             * @see ModelMetaData#classes
0091:             */
0092:            public int index;
0093:            /**
0094:             * The objectid-class (null if none).
0095:             */
0096:            public Class objectIdClass;
0097:            /**
0098:             * The persistent superclass (null if none).
0099:             */
0100:            public Class pcSuperClass;
0101:            /**
0102:             * The meta data for the persistent superclass (null if none).
0103:             */
0104:            public ClassMetaData pcSuperMetaData;
0105:            /**
0106:             * The meta data for the persistent class heirachy. This includes
0107:             * all our superclasses in order as well as our selves (i.e. a class
0108:             * with no PC superclasses will have a pcHeirachy containing just
0109:             * itself).
0110:             */
0111:            public ClassMetaData[] pcHeirachy;
0112:            /**
0113:             * The meta data for our persistent subclasses (null if none).
0114:             */
0115:            public ClassMetaData[] pcSubclasses;
0116:            /**
0117:             * The topmost class in the heirachy (i.e. pcHeirachy[0]).
0118:             */
0119:            public ClassMetaData top;
0120:            /**
0121:             * This flag is set if instances of the class are not allowed. An attempt
0122:             * to persist an instance of a class with this flag set will trigger an
0123:             * exception.
0124:             */
0125:            public boolean instancesNotAllowed;
0126:            /**
0127:             * The type of identity.
0128:             *
0129:             * @see MDStatics#IDENTITY_TYPE_APPLICATION
0130:             * @see MDStatics#IDENTITY_TYPE_DATASTORE
0131:             * @see MDStatics#IDENTITY_TYPE_NONDURABLE
0132:             */
0133:            public int identityType;
0134:            /**
0135:             * The persistent fields declared in this class (i.e. excluding
0136:             * superclasses) in relative fieldNo order. This includes extra fake
0137:             * fields created to hold information required by the store (e.g. row
0138:             * version values for a JDBC class). The fake fields are always at the
0139:             * end of this array after all the real fields.
0140:             */
0141:            public FieldMetaData[] fields;
0142:            /**
0143:             * The persistent fields declared in this class and in superclasses in
0144:             * State fieldNo order. This includes extra fake fields.
0145:             *
0146:             * @see State
0147:             */
0148:            public FieldMetaData[] stateFields;
0149:            /**
0150:             * Fields as mapped from the horizontal superclass.
0151:             */
0152:            public FieldMetaData[] horizontalFields;
0153:            /**
0154:             * The number of real fields in this class. This must be filled in by the
0155:             * store owning this class. This excludes fake fields.
0156:             */
0157:            public int realFieldCount;
0158:            /**
0159:             * The total number of fields in all of our superclasses (i.e. the
0160:             * total of fields.length for all our superclasses). This is useful
0161:             * to convert relative fieldNo's to State fieldNos.
0162:             */
0163:            public int super FieldCount;
0164:            /**
0165:             * The application primary key fields in alpha (field number) order.
0166:             * This is null if not using application identity.
0167:             */
0168:            public FieldMetaData[] pkFields;
0169:            /**
0170:             * The field nos of the pk fields.
0171:             */
0172:            public int[] pkFieldNos;
0173:            /**
0174:             * If the class is using datastore identity, then this is the java type
0175:             * code ({@link MDStatics.INT} etc) of the identity as if it was a
0176:             * Java field.
0177:             */
0178:            public int datastoreIdentityTypeCode;
0179:            /**
0180:             * If the class is using datastore identity, then this is the java type
0181:             * of the identity as if it was a Java field.
0182:             */
0183:            public Class datastoreIdentityType;
0184:            /**
0185:             * This is all the fields that must be managed. eg transaction or persistent.
0186:             */
0187:            public int[] stateFieldNos;
0188:            /**
0189:             * Array of the managed fields in abs field no order.
0190:             */
0191:            public FieldMetaData[] managedFields;
0192:            /**
0193:             * This is all the managed fields. This is an array where the index
0194:             * represents the absFieldNo and the value at the index the stateFieldNo. This
0195:             * is used to convert between abs and stateFieldNos
0196:             */
0197:            public int[] absToRel;
0198:            /**
0199:             * This is an utility array that is filled from 0 to the amount of managed
0200:             * fields. It is used to pass as argument to the pc.
0201:             */
0202:            public int[] allManagedFieldNosArray;
0203:            /**
0204:             * The abs fieldNos of all fields that is either is pc ref or a collection of pc ref.
0205:             */
0206:            public int[] absPCTypeFields;
0207:            /**
0208:             * The fields that are marked as transactional but not persistent.
0209:             */
0210:            public int[] txFieldNos;
0211:            public int[] txfieldManagedFieldNos;
0212:            /**
0213:             * This holds all the nonAutoSetStateFieldNos. These fields are stateFieldNos.
0214:             */
0215:            public int[] nonAutoSetStateFieldNos;
0216:            /**
0217:             * This holds all the autoSetStateFieldNos. These fields are managedFieldNos.
0218:             */
0219:            public int[] autoSetManagedFieldNos;
0220:            /**
0221:             * The fields of the persistent fields that may contain direct (e.g.
0222:             * foreign key) references to other PC classes. This must be filled in
0223:             * by the dataStore owning this class. This information is used to sort
0224:             * graphs of persistent objects for persisting in the correct order
0225:             * (e.g. to avoid tripping database integrity constraints).
0226:             */
0227:            public int[] directRefStateFieldNos;
0228:            /**
0229:             * The reference fields that are used to complete collections
0230:             * mapped using a foreign key in the element table. Null if none.
0231:             */
0232:            public int[] fkCollectionRefStateFieldNos;
0233:            /**
0234:             * Must orphans be deleted? An instance is considered an orphan if it
0235:             * is on the many side of at least one one-to-many (master detail)
0236:             * relationship and all of its back references are null (i.e. it has
0237:             * no parents).
0238:             */
0239:            public boolean deleteOrphans;
0240:            /**
0241:             * This is true if this class or any of its superclasses has any
0242:             * secondary fields.
0243:             */
0244:            public boolean hasSecondaryFields;
0245:            /**
0246:             * The fields that must be persisted on pass 2 in fieldNo order. This
0247:             * is filled using the secondaryField flag on FieldMetaData. Note that
0248:             * NOT these are relative fieldNos.
0249:             *
0250:             * @see FieldMetaData#secondaryField
0251:             */
0252:            public transient int[] pass2Fields;
0253:
0254:            public int[] pass2AbsFieldNos;
0255:            /**
0256:             * Is this class read-only?
0257:             */
0258:            public boolean readOnly;
0259:            /**
0260:             * The caching strategy for this class (one of the CACHE_STRATEGY_xxx
0261:             * constants).
0262:             */
0263:            public int cacheStrategy;
0264:            /**
0265:             * Flag to indicate that the cacheStrategy was all and all instances
0266:             * have been read once.
0267:             */
0268:            public boolean cacheStrategyAllDone;
0269:            /**
0270:             * The name of the DataStore this class belongs to. Any DataStore may
0271:             * have multiple names for different physical stores. This may be
0272:             * null indicating the default.
0273:             */
0274:            public transient String dataStoreName;
0275:            /**
0276:             * The fetch groups.
0277:             */
0278:            public FetchGroup[] fetchGroups;
0279:            public FetchGroup[] sortedFetchGroups;
0280:            public transient ArrayList fgTmp;
0281:            public transient HashMap nameGroupMap;
0282:            /**
0283:             * The referenced objects fetch group (null if none i.e. this class and
0284:             * its superclasses and subclasses have no references to other PC objects).
0285:             * This includes polyrefs and collections and is used to do reachability
0286:             * searches.
0287:             */
0288:            public FetchGroup refFetchGroup;
0289:            /**
0290:             * The dependent objects fetch group (null if none i.e. this class and
0291:             * its superclasses and subclasses have no references to dependent PC
0292:             * objects). This is used to do a reachability search when deleting.
0293:             */
0294:            public FetchGroup depFetchGroup;
0295:            /**
0296:             * This fetch group contains all fields that must be filled in the
0297:             * original state (e.g. jdoVersion etc.) when persisting changes to
0298:             * instances. It will be null if the class has no such fields (e.g.
0299:             * using optimistic locking 'none').
0300:             */
0301:            public FetchGroup reqFetchGroup;
0302:            /**
0303:             * The many-to-many fetch group (null if none i.e. this class and
0304:             * its superclasses and subclasses have no many-to-many managed
0305:             * collection fields). This is used to clear these fields when deleting.
0306:             * It also includes all fields that must be present to persist changes
0307:             * to an instance.
0308:             */
0309:            public FetchGroup managedManyToManyFetchGroup;
0310:            /**
0311:             * The total number of FetchGroups in all of our superclasses (i.e. the
0312:             * total of fetchGroups.length for all our superclasses). This is used
0313:             * to convert relative fetch group indexes to State fetch group indexes.
0314:             */
0315:            public int super FetchGroupCount;
0316:            /**
0317:             * This contains all the fetch groups sorted in fieldNo order. This is
0318:             * used to find a fetch group containing a particular set of fieldNos.
0319:             */
0320:            public transient List allFetchGroups;
0321:            public transient Comparator allFComparator = new AllFetchGroupComp();
0322:            /**
0323:             * Extra store specific meta data.
0324:             */
0325:            public transient Object storeClass;
0326:            /**
0327:             * Does this class use changed optimistic locking i.e. include the original
0328:             * values of changed fields in the where clause for JDBC.
0329:             */
0330:            public boolean changedOptimisticLocking;
0331:            /**
0332:             * If this class uses version or timestamp optimistic locking then this
0333:             * is the field holding the value.
0334:             */
0335:            public FieldMetaData optimisticLockingField;
0336:            /**
0337:             * Factory for State and OID instances for this class. This is set by
0338:             * the StorageManagerFactory.
0339:             */
0340:            public StateAndOIDFactory stateAndOIDFactory;
0341:            /**
0342:             * The oid class name for hyperdrive.
0343:             */
0344:            public String oidClassName;
0345:            /**
0346:             * The state class name.
0347:             */
0348:            public String stateClassName;
0349:            /**
0350:             * The fieldNo's of the sco fields. This is stateFieldNo's
0351:             */
0352:            public int[] scoFieldNos;
0353:
0354:            /**
0355:             * If we or any of our superclasses have any autoSet fields then this
0356:             * is true.
0357:             *
0358:             * @see FieldMetaData#autoSet
0359:             */
0360:            public boolean hasAutoSetFields;
0361:            /**
0362:             * These are the absolute field numbers of the fields that are loaded into
0363:             * an instance when it is populated with the default fetch group. This
0364:             * may be a subset of the fields in the FetchGroup instance for the DFG
0365:             * as extra fields (e.g. OIDs for references) may be fetched as well but
0366:             * not loaded.
0367:             *
0368:             * @see com.versant.core.jdo.PCStateMan#loadDFGIntoPC
0369:             */
0370:            public int[] dfgAbsFieldNos;
0371:            /**
0372:             * The same as {@link ClassMetaData#dfgAbsFieldNos} but only the state field
0373:             * numbers instead of abs field numbers.
0374:             *
0375:             * @see #dfgAbsFieldNos
0376:             */
0377:            public int[] dfgStateFieldNos;
0378:            /**
0379:             * The position of this class in the topological sort of the graph created
0380:             * by following direct references between classes. Example: If A
0381:             * references B, then A.index < B.index and A must be deleted before B
0382:             * to avoid tripping constraints.
0383:             *
0384:             * @see #referenceGraphCycle
0385:             */
0386:            public int referenceGraphIndex;
0387:            /**
0388:             * If this class is involved in a reference cycle with other classes then
0389:             * this flag will be set (e.g. this is true for classes A -> B -> C -> A).
0390:             * Constraints must not be generated for any references between classes
0391:             * with this flag set.
0392:             *
0393:             * @see #referenceGraphIndex
0394:             */
0395:            public boolean referenceGraphCycle;
0396:            /**
0397:             * This is true if the keys are created using a key generator.
0398:             */
0399:            public boolean useKeyGen;
0400:            /**
0401:             * Must a flush be done if getObjectId is called on a new instance of
0402:             * this class? This is set for classes using post-insert key generators.
0403:             * This is also used to decide if a full graph sort is required on persist.
0404:             */
0405:            public boolean postInsertKeyGenerator;
0406:            /**
0407:             * If the DataStore requires all fields of a dirty instance to store it
0408:             * and not just the dirty fields then this flag is true
0409:             * (e.g. VdsDataStore).
0410:             */
0411:            public boolean storeAllFields;
0412:            /**
0413:             * If the DataStore requires notification before a p-clean instance is made
0414:             * dirty or deleted in a datastore tx then this flag is true (e.g.
0415:             * VdsDataStore).
0416:             */
0417:            public boolean notifyDataStoreOnDirtyOrDelete;
0418:
0419:            private HashMap namedQueryMap; // query name -> QueryDetails
0420:
0421:            /**
0422:             * This is a total of all the subClasses (direct and indirect);
0423:             */
0424:            public transient int totalNoOfSubClasses;
0425:
0426:            private transient Object metaDataInstance;
0427:            private transient RuntimeException error;
0428:            private transient long errorTime = Long.MAX_VALUE;
0429:            /**
0430:             * This is a List that includes this and all the subCmds of all children and sub-children etc.
0431:             */
0432:            private transient List heirarchyList;
0433:            /**
0434:             * If this class is horizontal mapped. i.e. its fields should be in the table
0435:             * of the subclass.
0436:             */
0437:            public boolean horizontal;
0438:            /**
0439:             * The metadata if this class is the subclass of a horizontal super class.
0440:             */
0441:            public ClassMetaData horizontalCMD;
0442:            /**
0443:             * This can be used to override the need for a objectIdClass for appid instances
0444:             */
0445:            private boolean objectIdClasssRequired = true;
0446:
0447:            public ClassMetaData(JdoClass jdoClass, ModelMetaData jmd) {
0448:                this .jdoClass = jdoClass;
0449:                this .jmd = jmd;
0450:                qname = jdoClass.getQName();
0451:                int i = qname.lastIndexOf('.');
0452:                shortName = i < 0 ? qname : qname.substring(i + 1);
0453:                abstractSchemaName = shortName;
0454:            }
0455:
0456:            /**
0457:             * Calculate and set the superFieldCount and superFetchGroup value
0458:             * for this class and recursively all of its subclasses. This also
0459:             * initializes various arrays of fieldNos etc.
0460:             */
0461:            public void calcSuperCounts() {
0462:                if (pcSuperMetaData != null) {
0463:                    super FieldCount = pcSuperMetaData.super FieldCount
0464:                            + pcSuperMetaData.fields.length;
0465:                    super FetchGroupCount = pcSuperMetaData.super FetchGroupCount
0466:                            + pcSuperMetaData.fetchGroups.length;
0467:
0468:                    FieldMetaData[] super StateFields = pcSuperMetaData.stateFields;
0469:                    int n = super StateFields.length;
0470:                    stateFields = new FieldMetaData[n + fields.length];
0471:                    System.arraycopy(super StateFields, 0, stateFields, 0, n);
0472:                    System.arraycopy(fields, 0, stateFields, n, fields.length);
0473:                } else {
0474:                    stateFields = fields;
0475:                }
0476:
0477:                if (pcSubclasses != null) {
0478:                    for (int i = pcSubclasses.length - 1; i >= 0; i--) {
0479:                        pcSubclasses[i].calcSuperCounts();
0480:                    }
0481:                }
0482:
0483:                // this may happen if there have been previous errors
0484:                if (stateFields == null)
0485:                    return;
0486:
0487:                // see if we have any timestamp or version fields
0488:                for (int i = stateFields.length - 1; i >= 0; i--) {
0489:                    FieldMetaData f = stateFields[i];
0490:                    if (hasAutoSetFields = f.autoSet != MDStatics.AUTOSET_NO)
0491:                        break;
0492:                }
0493:
0494:                // find all the direct references
0495:                IntArray a = new IntArray(stateFields.length);
0496:                for (int i = stateFields.length - 1; i >= 0; i--) {
0497:                    FieldMetaData f = stateFields[i];
0498:                    if (f.isDirectRef())
0499:                        a.add(i);
0500:                }
0501:                directRefStateFieldNos = a.toArray();
0502:            }
0503:
0504:            /**
0505:             * This is called at the end of all metadata creation. This inits all the fieldnos
0506:             * arrays.
0507:             */
0508:            public void initMDFields() {
0509:                if (pcSuperMetaData != null) {
0510:                    initStateFields();
0511:                    createStateFieldNos();
0512:
0513:                    pass2Fields = mergeFieldsNos(pcSuperMetaData.pass2Fields,
0514:                            pass2Fields);
0515:
0516:                    pkFields = pcSuperMetaData.pkFields;
0517:                    pkFieldNos = pcSuperMetaData.pkFieldNos;
0518:                } else {
0519:                    initStateFields();
0520:                    /**
0521:                     * Create the fieldNo array for the state fields.
0522:                     */
0523:                    createStateFieldNos();
0524:
0525:                    if (pkFields != null) {
0526:                        int n = pkFields.length;
0527:                        int[] pkFieldNos = new int[n];
0528:                        for (int i = 0; i < n; i++) {
0529:                            pkFieldNos[i] = pkFields[i].managedFieldNo;
0530:                        }
0531:                        this .pkFieldNos = pkFieldNos;
0532:                    }
0533:                }
0534:                hasSecondaryFields = pass2Fields != null
0535:                        && pass2Fields.length > 0;
0536:
0537:                if (pcSubclasses != null) {
0538:                    for (int i = pcSubclasses.length - 1; i >= 0; i--) {
0539:                        pcSubclasses[i].initMDFields();
0540:                    }
0541:                }
0542:            }
0543:
0544:            /**
0545:             * This will iterate through the fmd's of this state and set the state
0546:             * field no' s.
0547:             */
0548:            private void initStateFields() {
0549:                if (fields == null)
0550:                    return; // possible if previous error
0551:                for (int i = 0; i < fields.length; i++) {
0552:                    FieldMetaData field = fields[i];
0553:                    field.stateFieldNo = (field.fieldNo + super FieldCount);
0554:                }
0555:            }
0556:
0557:            /**
0558:             * This creates various fieldNos arrays.
0559:             */
0560:            private void createStateFieldNos() {
0561:                if (stateFields == null)
0562:                    return; // possible if previous error
0563:                stateFieldNos = new int[stateFields.length];
0564:                ArrayList mList = new ArrayList();
0565:                IntArray nAutoFs = new IntArray();
0566:                IntArray autoFs = new IntArray();
0567:
0568:                /**
0569:                 * This is to iterate through all the fields for this PC instance
0570:                 * and set their field no as defined by the spec. This implies that if
0571:                 * a Class defines 2 fields 'a' and 'b' that 'a' must be field no '0'
0572:                 * and 'b' must be field no '1'.
0573:                 */
0574:                if (pcSuperMetaData != null) {
0575:                    mList.addAll(Arrays.asList(pcSuperMetaData.managedFields));
0576:                }
0577:                if (horizontalCMD != null) {
0578:                    mList.addAll(Arrays.asList(horizontalFields));
0579:                }
0580:                for (int i = 0; i < fields.length; i++) {
0581:                    FieldMetaData field = fields[i];
0582:                    if (field.fake)
0583:                        continue;
0584:                    mList.add(field);
0585:                }
0586:
0587:                managedFields = new FieldMetaData[mList.size()];
0588:                mList.toArray(managedFields);
0589:
0590:                IntArray txManagedFNOs = new IntArray();
0591:                absToRel = new int[mList.size()];
0592:                allManagedFieldNosArray = new int[mList.size()];
0593:                for (int i = 0; i < managedFields.length; i++) {
0594:                    FieldMetaData mField = managedFields[i];
0595:                    mField.managedFieldNo = i;
0596:                    allManagedFieldNosArray[i] = i;
0597:                    absToRel[i] = mField.stateFieldNo;
0598:                    if (mField.persistenceModifier == MDStatics.PERSISTENCE_MODIFIER_TRANSACTIONAL) {
0599:                        txManagedFNOs.add(mField.managedFieldNo);
0600:                    }
0601:                }
0602:
0603:                for (int i = 0; i < stateFields.length; i++) {
0604:                    FieldMetaData stateField = stateFields[i];
0605:                    if (stateField.autoSet == MDStatics.AUTOSET_NO) {
0606:                        nAutoFs.add(stateField.stateFieldNo);
0607:                    } else {
0608:                        if (stateField.managedFieldNo != -1)
0609:                            autoFs.add(stateField.managedFieldNo);
0610:                    }
0611:                    stateFieldNos[i] = stateField.stateFieldNo;
0612:                }
0613:
0614:                txfieldManagedFieldNos = txManagedFNOs.toArray();
0615:
0616:                IntArray tmpPass2FieldsAbs = new IntArray();
0617:                for (int i = 0; i < mList.size(); i++) {
0618:                    FieldMetaData fieldMetaData = (FieldMetaData) mList.get(i);
0619:                    if (fieldMetaData.secondaryField) {
0620:                        tmpPass2FieldsAbs.add(fieldMetaData.managedFieldNo);
0621:                    }
0622:                }
0623:                pass2AbsFieldNos = tmpPass2FieldsAbs.toArray();
0624:                tmpPass2FieldsAbs = null;
0625:
0626:                nonAutoSetStateFieldNos = nAutoFs.toArray();
0627:                autoSetManagedFieldNos = autoFs.toArray();
0628:
0629:                IntArray dfgFieldNoArray = new IntArray();
0630:                IntArray dfgStateFieldNoArray = new IntArray();
0631:                for (int i = 0; i < managedFields.length; i++) {
0632:                    FieldMetaData managedField = managedFields[i];
0633:                    if (managedField.isJDODefaultFetchGroup()) {
0634:                        dfgFieldNoArray.add(managedField.managedFieldNo);
0635:                        dfgStateFieldNoArray.add(managedField.stateFieldNo);
0636:                    }
0637:                }
0638:                dfgAbsFieldNos = dfgFieldNoArray.toArray();
0639:                dfgStateFieldNos = dfgStateFieldNoArray.toArray();
0640:
0641:                IntArray absPCTypeFieldArray = new IntArray();
0642:                for (int i = 0; i < managedFields.length; i++) {
0643:                    FieldMetaData field = managedFields[i];
0644:                    if (field.elementTypeMetaData != null
0645:                            || field.typeMetaData != null
0646:                            || field.keyTypeMetaData != null) {
0647:                        absPCTypeFieldArray.add(field.managedFieldNo);
0648:                    }
0649:                }
0650:                absPCTypeFields = absPCTypeFieldArray.toArray();
0651:
0652:                fillSCOFieldNos();
0653:                fillValueTypeFieldNos();
0654:                fillTxFields();
0655:            }
0656:
0657:            /**
0658:             * Fill in the scoFieldNos array.
0659:             */
0660:            private void fillSCOFieldNos() {
0661:                FieldMetaData[] fields = managedFields;
0662:                final int numFields = fields.length;
0663:                IntArray fieldNos = new IntArray(numFields);
0664:                for (int i = 0; i < numFields; i++) {
0665:                    FieldMetaData fmd = fields[i];
0666:                    //TODO Fix this: the 'MDStatics.CATEGORY_ARRAY' check is due to a bug. If this is not set then array does not work.
0667:                    if (fmd.scoField
0668:                            && fmd.category != MDStatics.CATEGORY_ARRAY) {
0669:                        fieldNos.add(fmd.stateFieldNo);
0670:                    }
0671:                }
0672:                scoFieldNos = fieldNos.toArray();
0673:            }
0674:
0675:            // set the fieldNo for each field
0676:            private void fillTxFields() {
0677:                FieldMetaData[] fields = managedFields;
0678:                IntArray txFields = new IntArray();
0679:                for (int i = 0; i < fields.length; i++) {
0680:                    //add all fields mark as transactional to the txFields.
0681:                    if (fields[i].persistenceModifier == MDStatics.PERSISTENCE_MODIFIER_TRANSACTIONAL) {
0682:                        txFields.add(fields[i].stateFieldNo);
0683:                    }
0684:                }
0685:                txFieldNos = txFields.toArray();
0686:            }
0687:
0688:            /**
0689:             * Fill in the valueTypeFieldNos array for cmd.
0690:             */
0691:            private void fillValueTypeFieldNos() {
0692:
0693:            }
0694:
0695:            /**
0696:             * Merge two arrays as one. Before the local fieldNo's is merged it is
0697:             * bumped up the the superFieldCount.
0698:             *
0699:             * @param s
0700:             * @param l
0701:             * @return
0702:             */
0703:            private final int[] mergeFieldsNos(int[] s, int[] l) {
0704:                int[] n = null;
0705:                if (s == null && l == null) {
0706:                } else if (s == null) {
0707:                    n = l;
0708:                    for (int i = 0; i < l.length; i++) {
0709:                        l[i] = l[i] + super FieldCount;
0710:                    }
0711:                } else if (l == null) {
0712:                    n = s;
0713:                } else {
0714:                    n = new int[s.length + l.length];
0715:                    System.arraycopy(s, 0, n, 0, s.length);
0716:                    for (int i = 0; i < l.length; i++) {
0717:                        l[i] = l[i] + super FieldCount;
0718:                    }
0719:                    System.arraycopy(l, 0, n, s.length, l.length);
0720:                }
0721:                return n;
0722:            }
0723:
0724:            /**
0725:             * Calculate the pcHeirachy for this class and recursively all of its
0726:             * subclasses. This also copies then identityType field down to
0727:             * subclasses.
0728:             */
0729:            public void calcPcHeirachy() {
0730:                if (pcSuperMetaData != null) {
0731:                    ClassMetaData[] super PcHeirachy = pcSuperMetaData.pcHeirachy;
0732:                    int n = super PcHeirachy.length;
0733:                    pcHeirachy = new ClassMetaData[n + 1];
0734:                    System.arraycopy(super PcHeirachy, 0, pcHeirachy, 0, n);
0735:                    pcHeirachy[n] = this ;
0736:                    identityType = pcSuperMetaData.identityType;
0737:                } else {
0738:                    pcHeirachy = new ClassMetaData[] { this  };
0739:                }
0740:                top = pcHeirachy[0];
0741:                if (pcSubclasses != null) {
0742:                    for (int i = pcSubclasses.length - 1; i >= 0; i--) {
0743:                        pcSubclasses[i].calcPcHeirachy();
0744:                    }
0745:                }
0746:            }
0747:
0748:            /**
0749:             * This is called on the base cmd of the heirachy.
0750:             * <p/>
0751:             * The idea is that pc subs must have the same cache strat as the least derived.
0752:             * A strat of yes and all is handled as the same in this case.
0753:             *
0754:             * @param strat
0755:             */
0756:            private void overRideCacheStrategy(int strat) {
0757:                if (cacheStrategy != strat) {
0758:                    switch (cacheStrategy) {
0759:                    case MDStatics.CACHE_STRATEGY_NO:
0760:                        cacheStrategy = strat;
0761:                        break;
0762:                    case MDStatics.CACHE_STRATEGY_YES:
0763:                        if (strat != MDStatics.CACHE_STRATEGY_ALL) {
0764:                            cacheStrategy = strat;
0765:                        }
0766:                        break;
0767:                    case MDStatics.CACHE_STRATEGY_ALL:
0768:                        if (strat != MDStatics.CACHE_STRATEGY_YES) {
0769:                            cacheStrategy = strat;
0770:                        }
0771:                        break;
0772:                    default:
0773:                        throw BindingSupportImpl.getInstance().internal(
0774:                                "Unknown caching strategy : '" + strat + "'");
0775:                    }
0776:                }
0777:                if (pcSubclasses != null) {
0778:                    for (int i = 0; i < pcSubclasses.length; i++) {
0779:                        pcSubclasses[i].overRideCacheStrategy(strat);
0780:                    }
0781:                }
0782:            }
0783:
0784:            public void overRideCacheStrategy() {
0785:                if (pcSuperMetaData != null) {
0786:                    throw BindingSupportImpl.getInstance().internal(
0787:                            "This is only allowed to be "
0788:                                    + "called on the base of heirachy.");
0789:                }
0790:                overRideCacheStrategy(cacheStrategy);
0791:            }
0792:
0793:            /**
0794:             * Get meta data for the field fname or null if none. This will only
0795:             * find real fields declared in this class or one of our superclasses.
0796:             */
0797:            public FieldMetaData getFieldMetaData(String fname) {
0798:                // do a binary search since fields is sorted by name
0799:                int low = 0;
0800:                int high = realFieldCount - 1;
0801:                while (low <= high) {
0802:                    int mid = (low + high) / 2;
0803:                    FieldMetaData midVal = fields[mid];
0804:                    int cmp = midVal.name.compareTo(fname);
0805:                    if (cmp < 0) {
0806:                        low = mid + 1;
0807:                    } else if (cmp > 0) {
0808:                        high = mid - 1;
0809:                    } else {
0810:                        return midVal;
0811:                    }
0812:                }
0813:                if (horizontalCMD != null) {
0814:                    low = 0;
0815:                    high = horizontalFields.length - 1;
0816:                    while (low <= high) {
0817:                        int mid = (low + high) / 2;
0818:                        FieldMetaData midVal = horizontalFields[mid];
0819:                        int cmp = midVal.name.compareTo(fname);
0820:                        if (cmp < 0) {
0821:                            low = mid + 1;
0822:                        } else if (cmp > 0) {
0823:                            high = mid - 1;
0824:                        } else {
0825:                            return midVal;
0826:                        }
0827:                    }
0828:                }
0829:                if (horizontalCMD != null) {
0830:                    low = 0;
0831:                    high = horizontalFields.length - 1;
0832:                    while (low <= high) {
0833:                        int mid = (low + high) / 2;
0834:                        FieldMetaData midVal = horizontalFields[mid];
0835:                        int cmp = midVal.origName.compareTo(fname);
0836:                        if (cmp < 0) {
0837:                            low = mid + 1;
0838:                        } else if (cmp > 0) {
0839:                            high = mid - 1;
0840:                        } else {
0841:                            return midVal;
0842:                        }
0843:                    }
0844:                    return null;
0845:                }
0846:                if (pcSuperMetaData == null)
0847:                    return null;
0848:                return pcSuperMetaData.getFieldMetaData(fname);
0849:            }
0850:
0851:            /**
0852:             * Get the fetch group with gname or null if none.
0853:             */
0854:            public FetchGroup getFetchGroup(String gname) {
0855:                if (gname.equals(FetchGroup.DFG_NAME))
0856:                    return fetchGroups[0];
0857:                // do a binary search since groups is sorted by name
0858:                int low = 1;
0859:                int high = sortedFetchGroups == null ? 0
0860:                        : sortedFetchGroups.length - 1;
0861:                while (low <= high) {
0862:                    int mid = (low + high) / 2;
0863:                    FetchGroup midVal = sortedFetchGroups[mid];
0864:                    int cmp = midVal.name.compareTo(gname);
0865:                    if (cmp < 0) {
0866:                        low = mid + 1;
0867:                    } else if (cmp > 0) {
0868:                        high = mid - 1;
0869:                    } else {
0870:                        return midVal;
0871:                    }
0872:                }
0873:                return null;
0874:            }
0875:
0876:            /**
0877:             * Add a new FetchGroup to the allFetchGroups array maintaining the
0878:             * sort order.
0879:             */
0880:            private void addToAllFetchGroups(FetchGroup fg) {
0881:                allFetchGroups.add(fg);
0882:                Collections.sort(allFetchGroups, allFComparator);
0883:            }
0884:
0885:            /**
0886:             * Get the fetch group with index fgIndex. If the group does not match
0887:             * clsId then the super fetch group is used and so on recursively. If
0888:             * no fetch group is found a JDOGenieFatalInternalException is thrown.
0889:             */
0890:            public final FetchGroup getFetchGroup(int fgIndex, int clsId) {
0891:                FetchGroup fg = fetchGroups[fgIndex];
0892:                for (; fg.classMetaData.classId != clsId;) {
0893:                    ClassMetaData smd = fg.classMetaData.pcSuperMetaData;
0894:                    if (smd == null) {
0895:                        ClassMetaData t = jmd.getClassMetaData(clsId);
0896:                        throw BindingSupportImpl.getInstance().internal(
0897:                                "No FetchGroup found to match fgIndex "
0898:                                        + fgIndex + " classId " + clsId + " ("
0899:                                        + (t == null ? null : t.toString())
0900:                                        + ")" + " on " + this  + " (classId "
0901:                                        + classId + ")");
0902:                    }
0903:                    fg = smd.fetchGroups[fgIndex];
0904:                }
0905:                return fg;
0906:            }
0907:
0908:            /**
0909:             * Init the stateFieldNo array for all our FetchGroup's and create
0910:             * allFetchGroups.
0911:             */
0912:            public void finishFetchGroups() {
0913:                int n = fetchGroups == null ? 0 : fetchGroups.length;
0914:                allFetchGroups = new ArrayList(n);
0915:                for (int i = n - 1; i >= 0; i--) {
0916:                    FetchGroup g = fetchGroups[i];
0917:                    g.finish();
0918:                    addToAllFetchGroups(g);
0919:                }
0920:            }
0921:
0922:            /**
0923:             * Create the subFetchGroups array on all fetch groups.
0924:             */
0925:            public void finishFetchGroups2() {
0926:                if (pcSubclasses == null)
0927:                    return;
0928:                int sclen = pcSubclasses.length;
0929:                ArrayList a = new ArrayList(sclen);
0930:                int n = fetchGroups.length;
0931:                for (int i = n - 1; i >= 0; i--) {
0932:                    a.clear();
0933:                    FetchGroup g = fetchGroups[i];
0934:                    for (int j = 0; j < sclen; j++) {
0935:                        ClassMetaData sc = pcSubclasses[j];
0936:                        FetchGroup sub = sc.findSubFetchGroup(g);
0937:                        if (sub != null)
0938:                            a.add(sub);
0939:                    }
0940:                    g.subFetchGroups = new FetchGroup[a.size()];
0941:                    a.toArray(g.subFetchGroups);
0942:                }
0943:            }
0944:
0945:            private FetchGroup findSubFetchGroup(FetchGroup super Group) {
0946:                for (int i = 0; i < fetchGroups.length; i++) {
0947:                    FetchGroup g = fetchGroups[i];
0948:                    if (g.super FetchGroup == super Group)
0949:                        return g;
0950:                }
0951:                return null;
0952:            }
0953:
0954:            /**
0955:             * Sort by classId. Do not change this ordering.
0956:             */
0957:            public int compareTo(Object o) {
0958:                ClassMetaData cmd = (ClassMetaData) o;
0959:                if (classId < cmd.classId)
0960:                    return -1;
0961:                if (classId > cmd.classId)
0962:                    return +1;
0963:                return 0;
0964:            }
0965:
0966:            /**
0967:             * Create a new empty OID for this class.
0968:             *
0969:             * @param resolved Is this a resolved OID?
0970:             * @see OID#isResolved
0971:             * @see OID#resolve
0972:             */
0973:            public OID createOID(boolean resolved) {
0974:                return stateAndOIDFactory.createOID(this , resolved);
0975:            }
0976:
0977:            /**
0978:             * Create a new empty State for this class.
0979:             */
0980:            public State createState() {
0981:                return stateAndOIDFactory.createState(this );
0982:            }
0983:
0984:            /**
0985:             * Create an OID for a new object of this class.
0986:             */
0987:            public NewObjectOID createNewObjectOID() {
0988:                return stateAndOIDFactory.createNewObjectOID(this );
0989:            }
0990:
0991:            /**
0992:             * Is cmd one of our ancestors or ourself?
0993:             */
0994:            public boolean isAncestorOrSelf(ClassMetaData cmd) {
0995:                if (cmd == this )
0996:                    return true;
0997:                for (ClassMetaData c = pcSuperMetaData; c != null; c = c.pcSuperMetaData) {
0998:                    if (c == cmd)
0999:                        return true;
1000:                }
1001:                return false;
1002:            }
1003:
1004:            public String toString() {
1005:                return "Class " + qname;
1006:            }
1007:
1008:            /**
1009:             * Get the name of this class without package.
1010:             */
1011:            public String getShortName() {
1012:                int i = qname.lastIndexOf('.');
1013:                if (i >= 0) {
1014:                    return qname.substring(i + 1);
1015:                } else {
1016:                    return qname;
1017:                }
1018:            }
1019:
1020:            public void dump() {
1021:                dump(System.out, "");
1022:            }
1023:
1024:            public void dump(PrintStream out, String indent) {
1025:                out.println(indent + this );
1026:                String is = indent + "  ";
1027:                out.println(is + "qname = " + qname);
1028:                out.println(is + "cls = " + cls);
1029:                out.println(is + "classId = " + classId);
1030:                out.println(is + "index = " + index);
1031:                out.println(is + "objectIdClass = " + objectIdClass);
1032:                out.println(is + "pcSuperClass = " + pcSuperClass);
1033:                out.println(is + "pcSuperMetaData = " + pcSuperMetaData);
1034:                out.println(is + "identityType = "
1035:                        + MDStaticUtils.toIdentityTypeString(identityType));
1036:                out.println(is + "readOnly = " + readOnly);
1037:                out.println(is + "cache = "
1038:                        + MDStaticUtils.toCacheString(cacheStrategy));
1039:                out.println(is + "jdoClass = " + jdoClass);
1040:                out.println(is + "jdbcClass = " + storeClass);
1041:                out.println(is + "realFieldCount = " + realFieldCount);
1042:                out.println(is + "superFieldCount = " + super FieldCount);
1043:                out.println(is + "superFetchGroupCount = "
1044:                        + super FetchGroupCount);
1045:                out.println(is + "hasAutoSetFields = " + hasAutoSetFields);
1046:                StringBuffer s = new StringBuffer();
1047:                s.append(is);
1048:                s.append("directRefStateFieldNos = ");
1049:                if (directRefStateFieldNos == null) {
1050:                    s.append("null");
1051:                } else {
1052:                    s.append("[");
1053:                    for (int i = 0; i < directRefStateFieldNos.length; i++) {
1054:                        if (i > 0)
1055:                            s.append(", ");
1056:                        s.append(directRefStateFieldNos[i]);
1057:                    }
1058:                    s.append(']');
1059:                }
1060:                out.println(s);
1061:                if (pcHeirachy != null) {
1062:                    for (int i = 0; i < pcHeirachy.length; i++) {
1063:                        out.println(is + "pcHeirachy[" + i + "] "
1064:                                + pcHeirachy[i]);
1065:                    }
1066:                } else {
1067:                    out.println(is + "pcHeirachy is null");
1068:                }
1069:                if (pcSubclasses != null) {
1070:                    out.println(is + pcSubclasses.length
1071:                            + " persistent subclass(es)");
1072:                    for (int i = 0; i < pcSubclasses.length; i++) {
1073:                        out.println(is + "[" + i + "] " + pcSubclasses[i]);
1074:                    }
1075:                }
1076:                if (fields != null) {
1077:                    out.println(is + fields.length + " persistent field(s)");
1078:                    for (int i = 0; i < fields.length; i++) {
1079:                        fields[i].dump(out, is);
1080:                    }
1081:                }
1082:                if (stateFields != null) {
1083:                    for (int i = 0; i < stateFields.length; i++) {
1084:                        out.println(is + "stateFields[" + i + "] = "
1085:                                + stateFields[i] + " stateFieldNo = "
1086:                                + stateFields[i].stateFieldNo);
1087:                    }
1088:                } else {
1089:                    out.println(is + "stateFields is null");
1090:                }
1091:                if (stateFieldNos != null) {
1092:                    for (int i = 0; i < stateFieldNos.length; i++) {
1093:                        out.println(is + "stateFieldNos[" + i + "] = "
1094:                                + stateFieldNos[i]);
1095:                    }
1096:                } else {
1097:                    out.println(is + "stateFieldNos is null");
1098:                }
1099:                if (scoFieldNos != null) {
1100:                    for (int i = 0; i < scoFieldNos.length; i++) {
1101:                        out.println(is + "scoFieldNos[" + i + "] = "
1102:                                + scoFieldNos[i]);
1103:                    }
1104:                } else {
1105:                    out.println(is + "scoFieldNos is null");
1106:                }
1107:                if (pkFieldNos != null) {
1108:                    for (int i = 0; i < pkFieldNos.length; i++) {
1109:                        out.println(is + "pkFieldNos[" + i + "] = "
1110:                                + pkFieldNos[i]);
1111:                    }
1112:                } else {
1113:                    out.println(is + " pkFieldNos is null");
1114:                }
1115:                if (pass2Fields != null) {
1116:                    for (int i = 0; i < pass2Fields.length; i++) {
1117:                        out.println(is + " pass2Fields[" + i + "] = "
1118:                                + pass2Fields[i]);
1119:                    }
1120:                } else {
1121:                    out.println(is + " pass2Fields is null");
1122:                }
1123:                if (fetchGroups != null) {
1124:                    out.println(is + fetchGroups.length + " fetch group(s)");
1125:                    for (int i = 0; i < fetchGroups.length; i++) {
1126:                        out.println(is + "fetchg[" + i + "] = ");
1127:                        fetchGroups[i].dump(out, is);
1128:                    }
1129:                }
1130:                if (absToRel != null) {
1131:                    out.println(is + "The managedFieldMapping: size = "
1132:                            + allManagedFieldNosArray);
1133:                    for (int i = 0; i < absToRel.length; i++) {
1134:                        int managedFieldNo = absToRel[i];
1135:                        out.println(is + "mFieldNo " + i + " -> "
1136:                                + managedFieldNo);
1137:                    }
1138:                }
1139:            }
1140:
1141:            /**
1142:             * Is this class part of a heirachy (i.e. Does this class have super classes
1143:             * or sub classes that are PesistentCapable)
1144:             *
1145:             * @return true if this class has super classes or sub classes that
1146:             *         are PesistentCapable
1147:             */
1148:            public boolean isInHeirachy() {
1149:                return !(pcHeirachy.length == 1 && pcSubclasses == null);
1150:            }
1151:
1152:            /**
1153:             * Get the classloader that loaded our class.
1154:             */
1155:            public ClassLoader getClassLoader() {
1156:                ClassLoader l = cls.getClassLoader();
1157:                if (l == null) {
1158:                    return ClassHelper.get().getSystemClassLoader();
1159:                } else {
1160:                    return l;
1161:                }
1162:            }
1163:
1164:            public void initMDFields2() {
1165:                if (fields == null) {
1166:                    return;
1167:                }
1168:                for (int i = 0; i < fields.length; i++) {
1169:                    FieldMetaData managedField = fields[i];
1170:                    if (managedField.isEmbeddedRef()
1171:                            && managedField.embeddedFmds != null) {
1172:                        FieldMetaData[] embManFields = managedField.managedEmbeddedFields = new FieldMetaData[managedField.typeMetaData.managedFields.length];
1173:                        for (int j = 0; j < managedField.embeddedFmds.length; j++) {
1174:                            FieldMetaData embeddedFmd = managedField.embeddedFmds[j];
1175:                            embManFields[embeddedFmd.origFmd.managedFieldNo] = embeddedFmd;
1176:                        }
1177:                    }
1178:                }
1179:                if (pcSubclasses != null) {
1180:                    for (int i = pcSubclasses.length - 1; i >= 0; i--) {
1181:                        pcSubclasses[i].initMDFields2();
1182:                    }
1183:                }
1184:            }
1185:
1186:            public boolean isEmbeddedRef(int stateFieldNo) {
1187:                return stateFields[stateFieldNo].embedded
1188:                        && stateFields[stateFieldNo].category == MDStatics.CATEGORY_REF;
1189:            }
1190:
1191:            public void setObjectIdClasssRequired(boolean objectIdClasssRequired) {
1192:                this .objectIdClasssRequired = objectIdClasssRequired;
1193:            }
1194:
1195:            public boolean isObjectIdClasssRequired() {
1196:                if (identityType != MDStatics.IDENTITY_TYPE_APPLICATION)
1197:                    return false;
1198:                if (horizontal)
1199:                    return false;
1200:                if (!objectIdClasssRequired)
1201:                    return false;
1202:                return true;
1203:            }
1204:
1205:            /**
1206:             * obfuscator gives problems if its private
1207:             */
1208:            public static final class AllFetchGroupComp implements  Comparator {
1209:
1210:                public int compare(Object o1, Object o2) {
1211:                    return ((FetchGroup) o1).name
1212:                            .compareTo(((FetchGroup) o2).name);
1213:                }
1214:
1215:                public int compare(FetchGroup o1, FetchGroup o2) {
1216:                    return o1.name.compareTo(o2.name);
1217:                }
1218:            }
1219:
1220:            /**
1221:             * Set our referenceGraphIndex.
1222:             */
1223:            public void setReferenceGraphIndex(int referenceGraphIndex) {
1224:                this .referenceGraphIndex = referenceGraphIndex;
1225:            }
1226:
1227:            /**
1228:             * Set our referenceGraphCycle and recursively all of our subclasses.
1229:             */
1230:            public void setReferenceGraphCycle(boolean referenceGraphCycle) {
1231:                this .referenceGraphCycle = referenceGraphCycle;
1232:                if (pcSubclasses != null) {
1233:                    for (int i = pcSubclasses.length - 1; i >= 0; i--) {
1234:                        pcSubclasses[i]
1235:                                .setReferenceGraphCycle(referenceGraphCycle);
1236:                    }
1237:                }
1238:            }
1239:
1240:            /**
1241:             * Find a primary key field of this class or the topmost superclass in
1242:             * its heirachy by name or null if none.
1243:             */
1244:            public FieldMetaData findPkField(String fname) {
1245:                if (pkFields == null) {
1246:                    if (pcSuperMetaData == null) {
1247:                        throw BindingSupportImpl.getInstance().internal(
1248:                                "Not an application identity class: " + qname);
1249:                    }
1250:                    return pcSuperMetaData.findPkField(fname);
1251:                }
1252:                for (int i = pkFields.length - 1; i >= 0; i--) {
1253:                    FieldMetaData f = pkFields[i];
1254:                    if (f.name.equals(fname))
1255:                        return f;
1256:                }
1257:                return null;
1258:            }
1259:
1260:            /**
1261:             * Find all the fields declared in the class.
1262:             */
1263:            public FieldInfo[] getDeclaredFields() {
1264:                Field[] fa = cls.getDeclaredFields();
1265:                int n = fa.length;
1266:                FieldInfo[] a = new FieldInfo[n];
1267:                for (int i = 0; i < n; i++) {
1268:                    Field f = fa[i];
1269:
1270:                    a[i] = new FieldInfo(f.getName(), f.getModifiers(), f
1271:                            .getType());
1272:
1273:                }
1274:                return a;
1275:            }
1276:
1277:            /**
1278:             * Is this class PersistenceCapable (i.e. has it been enhanced?).
1279:             */
1280:            public boolean isPersistenceCapable() {
1281:                return PersistenceCapable.class.isAssignableFrom(cls);
1282:            }
1283:
1284:            /**
1285:             * Info about a field collected with reflection.
1286:             */
1287:            public static class FieldInfo {
1288:
1289:                private String name;
1290:                private int modifiers;
1291:                private Class type;
1292:
1293:                public FieldInfo(String name, int modifiers, Class type) {
1294:                    this .name = name;
1295:                    this .modifiers = modifiers;
1296:                    this .type = type;
1297:                }
1298:
1299:                public String getName() {
1300:                    return name;
1301:                }
1302:
1303:                public int getModifiers() {
1304:                    return modifiers;
1305:                }
1306:
1307:                public Class getType() {
1308:                    return type;
1309:                }
1310:            }
1311:
1312:            /**
1313:             * Add the indexes of all the classes in the heirachy rooted at this class
1314:             * including this class to a.
1315:             */
1316:            public void findHeirachyIndexes(IntArray a) {
1317:                a.add(index);
1318:                if (pcSubclasses == null)
1319:                    return;
1320:                for (int i = pcSubclasses.length - 1; i >= 0; i--) {
1321:                    pcSubclasses[i].findHeirachyIndexes(a);
1322:                }
1323:            }
1324:
1325:            /**
1326:             * Get an instance of our class for meta data analysis. If our class is
1327:             * abstract then we may return an instance of one of our subclasses. If
1328:             * we have no concrete subclasses then null is returned. The instance
1329:             * is cached.
1330:             */
1331:            public Object getMetaDataInstance() {
1332:                if (metaDataInstance == null) {
1333:                    if (cls == null) {
1334:                        throw BindingSupportImpl.getInstance().internal(
1335:                                "cls is null: " + qname);
1336:                    }
1337:                    try {
1338:                        metaDataInstance = cls.newInstance();
1339:                    } catch (InstantiationException e) {
1340:                        if (pcSubclasses == null)
1341:                            return null;
1342:                        for (int i = 0; i < pcSubclasses.length; i++) {
1343:                            metaDataInstance = pcSubclasses[i]
1344:                                    .getMetaDataInstance();
1345:                            if (metaDataInstance != null)
1346:                                break;
1347:                        }
1348:                    } catch (IllegalAccessException e) {
1349:                        BindingSupportImpl.getInstance().invalidOperation(
1350:                                "Unable to create instance of " + qname + ": "
1351:                                        + e, e);
1352:                    }
1353:                }
1354:                return metaDataInstance;
1355:            }
1356:
1357:            /**
1358:             * Check the consistency of the meta data. This will try and validate parts
1359:             * of the data structure against other parts to find bugs.
1360:             */
1361:            public void validate() {
1362:
1363:                // make sure that the index of each field in the fields's array
1364:                // matches the fieldNo field on FieldMetaData
1365:                if (fields != null) {
1366:                    for (int i = 0; i < fields.length; i++) {
1367:                        FieldMetaData fmd = fields[i];
1368:                        if (i != fmd.fieldNo) {
1369:                            throw createValidationError(fmd.name
1370:                                    + ": i != fields[i].fieldNo: " + i + " != "
1371:                                    + fields[i].fieldNo);
1372:                        }
1373:                    }
1374:                }
1375:
1376:                // make sure that the index of each field in the stateField's array
1377:                // matches the stateFieldNo field on FieldMetaData
1378:                if (stateFields != null) {
1379:                    for (int i = 0; i < stateFields.length; i++) {
1380:                        FieldMetaData fmd = stateFields[i];
1381:                        if (i != fmd.stateFieldNo) {
1382:                            throw createValidationError(fmd.name
1383:                                    + ": i != stateFields[i].stateFieldNo: "
1384:                                    + i + " != " + stateFields[i].stateFieldNo);
1385:                        }
1386:                        if (i != stateFieldNos[i]) {
1387:                            throw createValidationError(fmd.name
1388:                                    + ": i != stateFieldNos[i]: " + i + " != "
1389:                                    + stateFieldNos[i]);
1390:                        }
1391:                    }
1392:                }
1393:            }
1394:
1395:            private RuntimeException createValidationError(String msg) {
1396:                return BindingSupportImpl.getInstance().internal(
1397:                        "Validation failed: " + qname + ": " + msg);
1398:            }
1399:
1400:            /**
1401:             * Cleanup any data structures not needed after meta data generation.
1402:             */
1403:            public void cleanupAfterMetaDataGeneration() {
1404:            }
1405:
1406:            public void setClassId(int classId) {
1407:                this .classId = classId;
1408:                classIdString = Integer.toString(classId);
1409:            }
1410:
1411:            public void addError(RuntimeException e, boolean quiet) {
1412:                if (Debug.DEBUG) {
1413:                    e.printStackTrace(System.out);
1414:                }
1415:                if (error == null) {
1416:                    errorTime = System.currentTimeMillis();
1417:                    error = e;
1418:                    try {
1419:                        Thread.sleep(1);
1420:                    } catch (InterruptedException e1) {
1421:                        // ignore
1422:                    }
1423:                }
1424:                if (!quiet)
1425:                    throw e;
1426:            }
1427:
1428:            public long getFirstErrorTime() {
1429:                return errorTime;
1430:            }
1431:
1432:            public RuntimeException getFirstError() {
1433:                RuntimeException e = null;
1434:                long fieldErrorTime = Long.MAX_VALUE;
1435:                if (fields != null) {
1436:                    int length = fields.length;
1437:                    for (int i = 0; i < length; i++) {
1438:                        FieldMetaData field = fields[i];
1439:                        if (field.hasErrors()) {
1440:                            e = field.getFirstError();
1441:                            fieldErrorTime = field.getFirstErrorTime();
1442:                            break;
1443:                        }
1444:                    }
1445:                }
1446:                if (error == null) {
1447:                    return e;
1448:                } else {
1449:                    if (fieldErrorTime > errorTime) {
1450:                        return error;
1451:                    } else if (fieldErrorTime < errorTime) {
1452:                        return e;
1453:                    } else {
1454:                        return error;
1455:                    }
1456:                }
1457:            }
1458:
1459:            public boolean hasErrors() {
1460:                if (fields != null) {
1461:                    int length = fields.length;
1462:                    for (int i = 0; i < length; i++) {
1463:                        FieldMetaData field = fields[i];
1464:                        if (field.hasErrors()) {
1465:                            return true;
1466:                        }
1467:                    }
1468:                }
1469:                return error != null;
1470:            }
1471:
1472:            /**
1473:             * Add a NamedQuery to this class.
1474:             *
1475:             * @throws IllegalArgumentException if there is already one with the
1476:             *                                  same name
1477:             */
1478:            public void addNamedQuery(String queryName, QueryDetails qp) {
1479:                if (namedQueryMap == null)
1480:                    namedQueryMap = new HashMap(17);
1481:                if (namedQueryMap.containsKey(queryName)) {
1482:                    throw BindingSupportImpl.getInstance().illegalArgument(
1483:                            "Meta data for Class " + qname
1484:                                    + " already has a query called '"
1485:                                    + queryName + "'");
1486:                }
1487:                namedQueryMap.put(queryName, qp);
1488:            }
1489:
1490:            /**
1491:             * Return QueryDetails for the named query or null if none. The caller
1492:             * must not modify the returned instance.
1493:             */
1494:            public QueryDetails getNamedQuery(String queryName) {
1495:                return namedQueryMap == null ? null
1496:                        : (QueryDetails) namedQueryMap.get(queryName);
1497:            }
1498:
1499:            /**
1500:             * Get Map.Entry's for all of our named queries in alpha order or empty list
1501:             * if none. The key of each Entry is the name and the value the QueryDetails
1502:             * instance.
1503:             */
1504:            public List getNamedQueries() {
1505:                if (namedQueryMap == null)
1506:                    return Collections.EMPTY_LIST;
1507:                ArrayList ans = new ArrayList(namedQueryMap.entrySet());
1508:                Collections.sort(ans, new Comparator() {
1509:                    public int compare(Object o1, Object o2) {
1510:                        String a = (String) ((Map.Entry) o1).getKey();
1511:                        String b = (String) ((Map.Entry) o2).getKey();
1512:                        return a.compareTo(b);
1513:                    }
1514:                });
1515:                return ans;
1516:            }
1517:
1518:            public transient int weight = 0;
1519:
1520:            public List getHeirarchyList() {
1521:                if (heirarchyList == null) {
1522:                    ArrayList subsList = new ArrayList();
1523:                    subsList.add(this );
1524:                    int startIndex = 0;
1525:                    int endIndex = 1;
1526:                    for (; startIndex < endIndex;) {
1527:                        for (int j = startIndex; j < endIndex; j++) {
1528:                            ClassMetaData[] subs = ((ClassMetaData) subsList
1529:                                    .get(j)).pcSubclasses;
1530:                            if (subs == null)
1531:                                continue;
1532:                            for (int i = 0; i < subs.length; i++) {
1533:                                subsList.add(subs[i]);
1534:                            }
1535:                        }
1536:                        startIndex = endIndex;
1537:                        endIndex = subsList.size();
1538:                    }
1539:                    heirarchyList = subsList;
1540:                    return subsList;
1541:                }
1542:                return heirarchyList;
1543:            }
1544:
1545:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.