Source Code Cross Referenced for MetaDataManager.java in  » Database-ORM » JPOX » org » jpox » 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 » Database ORM » JPOX » org.jpox.metadata 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************
0002:        Copyright (c) 2004 Andy Jefferson and others. All rights reserved. 
0003:        Licensed under the Apache License, Version 2.0 (the "License");
0004:        you may not use this file except in compliance with the License.
0005:        You may obtain a copy of the License at
0006:
0007:            http://www.apache.org/licenses/LICENSE-2.0
0008:
0009:        Unless required by applicable law or agreed to in writing, software
0010:        distributed under the License is distributed on an "AS IS" BASIS,
0011:        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012:        See the License for the specific language governing permissions and
0013:        limitations under the License. 
0014:         
0015:
0016:        Contributors:
0017:            ...
0018:         **********************************************************************/package org.jpox.metadata;
0019:
0020:        import java.io.IOException;
0021:        import java.lang.reflect.Constructor;
0022:        import java.net.MalformedURLException;
0023:        import java.net.URL;
0024:        import java.util.ArrayList;
0025:        import java.util.Collection;
0026:        import java.util.Collections;
0027:        import java.util.Comparator;
0028:        import java.util.Enumeration;
0029:        import java.util.HashMap;
0030:        import java.util.HashSet;
0031:        import java.util.Iterator;
0032:        import java.util.List;
0033:        import java.util.Map;
0034:        import java.util.Set;
0035:        import java.util.TreeSet;
0036:
0037:        import javax.jdo.spi.JDOImplHelper;
0038:        import javax.jdo.spi.RegisterClassEvent;
0039:        import javax.jdo.spi.RegisterClassListener;
0040:
0041:        import org.jpox.ClassLoaderResolver;
0042:        import org.jpox.OMFContext;
0043:        import org.jpox.api.ApiAdapter;
0044:        import org.jpox.exceptions.ClassNotResolvedException;
0045:        import org.jpox.exceptions.JPOXException;
0046:        import org.jpox.exceptions.JPOXUserException;
0047:        import org.jpox.metadata.annotations.AnnotationManager;
0048:        import org.jpox.metadata.xml.MetaDataParser;
0049:        import org.jpox.util.ClassUtils;
0050:        import org.jpox.util.JPOXLogger;
0051:        import org.jpox.util.JavaUtils;
0052:        import org.jpox.util.Localiser;
0053:        import org.jpox.util.StringUtils;
0054:
0055:        /**
0056:         * Manager of MetaData information in JPOX having scope of an ObjectManagerFactory.
0057:         * Each PMF/EMF will effectively have a single MetaDataManager handling all XML/Annotations MetaData.
0058:         * <p>
0059:         * A MetaDataManager can be "initialised" to start with particular MetaData. This is typically performed
0060:         * when the operation has a "persistence-unit", which defines the classes/jars/mapping-files to use.
0061:         * Alternatively, it can be initialised using a set of classes and mapping-files (for use by SchemaTool
0062:         * and the Enhancer when specifying the files as input).
0063:         * <P>
0064:         * Acts as a registry of metadata so that metadata files don't need to be 
0065:         * parsed multiple times. MetaData is stored as a FileMetaData, which contains
0066:         * PackageMetaData, which contains ClassMetaData, and so on. This maps exactly
0067:         * to the users model of their metadata. The users access point is 
0068:         * <B>getMetaDataForClass()</B> which will check the known classes without metadata,
0069:         * then check the existing registered metdata, then check the valid locations for 
0070:         * metdata files. This way, the metadata is managed from this single point.
0071:         * </P>
0072:         * <P>
0073:         * Maintains a list of all classes that have been checked for MetaData and
0074:         * don't have any available. This avoids the needs to look up MetaData multiple
0075:         * times finding the same result. Currently this list is for all ClassMetaData 
0076:         * objects keyed by the class name.
0077:         * </P>
0078:         * TODO Update MetaDataManager to be able to share ClassMetaData with other MetaDataManager
0079:         * so we need a central (singleton/static) registry that allows such communication.
0080:         *
0081:         * @version $Revision: 1.170 $ 
0082:         */
0083:        public abstract class MetaDataManager {
0084:            /** Localiser for messages. */
0085:            protected static final Localiser LOCALISER = Localiser
0086:                    .getInstance("org.jpox.metadata.Localisation");
0087:
0088:            /** The ObjectManagerFactory Context that this metadata manager is operating in. */
0089:            protected OMFContext omfContext = null;
0090:
0091:            /** Manager for annotations. */
0092:            protected AnnotationManager annotationManager = null;
0093:
0094:            /** Parser for MetaData. */
0095:            protected MetaDataParser metaDataParser = null;
0096:
0097:            /** Flag whether we should validate the metadata files when parsing. */
0098:            protected boolean validateMetaData = true;
0099:
0100:            /** Cache of class names that are known to not have MetaData/annotations. */
0101:            protected Collection classesWithoutPersistenceInfo = new HashSet();
0102:
0103:            /** Map of FileMetaData for the parsed files, keyed by the URL string. */
0104:            protected Map fileMetaDataByURLString = new HashMap();
0105:
0106:            /** Map of ClassMetaData, keyed by the class name. */
0107:            protected Map classMetaDataByClass = new HashMap();
0108:
0109:            /** Map of ClassMetaData, keyed by the JPA "entity name". */
0110:            protected Map classMetaDataByEntityName = new HashMap();
0111:
0112:            /** Map of QueryMetaData, keyed by the (class name + query name). */
0113:            protected Map queryMetaDataByName = new HashMap();
0114:
0115:            /** Map of FetchPlanMetaData, keyed by the fetch plan name. */
0116:            protected Map fetchPlanMetaDataByName = new HashMap();
0117:
0118:            /** Map of SequenceMetaData, keyed by the package name and sequence name. */
0119:            protected Map sequenceMetaDataByPackageSequence = new HashMap();
0120:
0121:            /** Map of TableGeneratorMetaData, keyed by the package name and generator name. */
0122:            protected Map tableGeneratorMetaDataByPackageSequence = new HashMap();
0123:
0124:            /** Map of QueryResultMetaData keyed by the name. */
0125:            protected Map queryResultMetaDataByName = new HashMap();
0126:
0127:            /** Indicator for whether this manager is managing the enhancement process, else it's runtime. */
0128:            protected boolean enhancing = false;
0129:
0130:            /** Flag for initialisation state when starting using a "persistence-unit". Used to prevent double initialise. */
0131:            protected boolean initialised = false;
0132:
0133:            /** EventListeners. Use a list to preserve ordering. */
0134:            protected List listeners = new ArrayList();
0135:
0136:            /** Factory for MetaData objects (class, field, property, interface). */
0137:            private MetaDataFactory metaDataFactory;
0138:
0139:            /**
0140:             * Whether the MetaData manager supports ORM concepts and metadata. 
0141:             * When using an object datastore this will be false.
0142:             */
0143:            protected boolean supportsORM = true;
0144:
0145:            /**
0146:             * Constructor, specifying the OMFContext used.
0147:             * @param ctxt OMF Context that this metadata manager operates in
0148:             */
0149:            public MetaDataManager(OMFContext ctxt) {
0150:                this .omfContext = ctxt;
0151:                JDOImplHelper.getInstance().removeRegisterClassListener(
0152:                        new MetaDataRegisterClassListener());
0153:                this .setValidate(ctxt.getPersistenceConfiguration()
0154:                        .getMetaDataValidate());
0155:
0156:                if (JavaUtils.isJRE1_5OrAbove()) {
0157:                    try {
0158:                        ClassLoaderResolver clr = ctxt
0159:                                .getClassLoaderResolver(null);
0160:                        Class annotationReaderClass = clr.classForName(ctxt
0161:                                .getPersistenceConfiguration()
0162:                                .getMetaDataAnnotationsManager());
0163:
0164:                        Class[] ctrArgs = new Class[] { MetaDataManager.class };
0165:                        Object[] ctrParams = new Object[] { this  };
0166:                        Constructor ctor = annotationReaderClass
0167:                                .getConstructor(ctrArgs);
0168:                        annotationManager = (AnnotationManager) ctor
0169:                                .newInstance(ctrParams);
0170:                    } catch (Exception e) {
0171:                        JPOXLogger.METADATA.info(LOCALISER.msg("044045"));
0172:                    }
0173:                }
0174:
0175:                // Register all of the types managed by the TypeManager as not needing MetaData/Annotations.
0176:                Set supportedClasses = getOMFContext().getTypeManager()
0177:                        .getSupportedTypes();
0178:                Iterator iter = supportedClasses.iterator();
0179:                while (iter.hasNext()) {
0180:                    classesWithoutPersistenceInfo.add(iter.next());
0181:                }
0182:
0183:                if (omfContext.getStoreManager() != null) {
0184:                    // Object datastores dont "map" for persistence so dont need ORM
0185:                    supportsORM = omfContext.getStoreManager()
0186:                            .usesDatastoreClass();
0187:                }
0188:            }
0189:
0190:            /**
0191:             * Accessor for whether the MetaData manager supports ORM concepts and metadata.
0192:             * With object datastores this will return false.
0193:             * @return Whether we support ORM
0194:             */
0195:            public boolean supportsORM() {
0196:                return supportsORM;
0197:            }
0198:
0199:            /**
0200:             * Method to log the configuration of this manager.
0201:             */
0202:            protected void logConfiguration() {
0203:                // Log the configuration
0204:                String inputTypes = null;
0205:                if (annotationManager != null) {
0206:                    inputTypes = "XML, Annotations";
0207:                } else {
0208:                    inputTypes = "XML";
0209:                }
0210:
0211:                JPOXLogger.METADATA.debug("MetaDataManager : " + " Input=("
0212:                        + inputTypes + ")" + " XML-Validation="
0213:                        + validateMetaData);
0214:            }
0215:
0216:            /**
0217:             * Initialisation method to define the initial metadata files and class names being handled by this MetaDataManager.
0218:             * @param metadataFiles The metadata files
0219:             * @param classNames The class names
0220:             * @param clr ClassLoader Resolver
0221:             * @return Array of the FileMetaData that is managed
0222:             * @throws JPOXUserException (with nested exceptions) if an error occurs parsing the files
0223:             */
0224:            public FileMetaData[] initialise(String[] metadataFiles,
0225:                    String[] classNames, ClassLoaderResolver clr) {
0226:                if (initialised) {
0227:                    // TODO Throw exception
0228:                    return null;
0229:                }
0230:                if (JPOXLogger.METADATA.isDebugEnabled()) {
0231:                    JPOXLogger.METADATA.debug(LOCALISER.msg("044013"));
0232:                }
0233:
0234:                HashSet exceptions = new HashSet();
0235:                ArrayList fileMetaData = new ArrayList();
0236:
0237:                // Load MetaData files first
0238:                for (int i = 0; i < metadataFiles.length; i++) {
0239:                    try {
0240:                        URL fileURL = null;
0241:                        try {
0242:                            fileURL = new URL("file:" + metadataFiles[i]);
0243:                        } catch (MalformedURLException mue) {
0244:                            fileURL = clr.getResource(metadataFiles[i], null);
0245:                        }
0246:                        if (fileURL != null
0247:                                && fileMetaDataByURLString.get(fileURL
0248:                                        .toString()) == null) {
0249:                            FileMetaData filemd = parseFile(fileURL);
0250:                            if (filemd != null) {
0251:                                registerFile(fileURL.toString(), filemd, clr);
0252:                                fileMetaData.add(filemd);
0253:                            } else {
0254:                                throw new JPOXUserException(LOCALISER.msg(
0255:                                        "044015", metadataFiles[i]));
0256:                            }
0257:                        }
0258:                    } catch (Exception e) {
0259:                        exceptions.add(e);
0260:                    }
0261:                }
0262:
0263:                // Load classes
0264:                for (int i = 0; i < classNames.length; i++) {
0265:                    try {
0266:                        Class cls = clr.classForName(classNames[i]);
0267:                        // Check for MetaData for this class (take precedence over annotations if they exist)
0268:                        AbstractClassMetaData cmd = (AbstractClassMetaData) classMetaDataByClass
0269:                                .get(classNames[i]);
0270:                        if (cmd == null) {
0271:                            // No MetaData so try annotations
0272:                            FileMetaData filemd = loadAnnotationsForClass(cls,
0273:                                    clr, true, false);
0274:                            if (filemd != null) {
0275:                                // Store file against an annotations specific "URL"
0276:                                registerFile("annotations:" + classNames[i],
0277:                                        filemd, clr);
0278:                                fileMetaData.add(filemd);
0279:                            } else {
0280:                                // Class has no metadata or annotations so warn the user
0281:                                JPOXLogger.METADATA.info(LOCALISER.msg(
0282:                                        "044017", classNames[i]));
0283:                            }
0284:                        } else {
0285:                            // We have MetaData, and any annotations will be merged in during the populate process
0286:                        }
0287:                    } catch (ClassNotResolvedException e) {
0288:                        // log and ignore this exception
0289:                        JPOXLogger.METADATA.error(StringUtils
0290:                                .getStringFromStackTrace(e));
0291:                    } catch (Exception e) {
0292:                        exceptions.add(e);
0293:                    }
0294:                }
0295:
0296:                if (exceptions.size() > 0) {
0297:                    // Exceptions while loading MetaData/annotations
0298:                    throw new JPOXUserException(LOCALISER.msg("044016"),
0299:                            (Throwable[]) exceptions
0300:                                    .toArray(new Throwable[exceptions.size()]),
0301:                            null);
0302:                }
0303:
0304:                if (fileMetaData.size() > 0) {
0305:                    // MetaData has been loaded for the unit
0306:                    // a). Populate MetaData
0307:                    if (JPOXLogger.METADATA.isDebugEnabled()) {
0308:                        JPOXLogger.METADATA.debug(LOCALISER.msg("044018"));
0309:                    }
0310:                    Iterator iter = fileMetaData.iterator();
0311:                    while (iter.hasNext()) {
0312:                        FileMetaData filemd = (FileMetaData) iter.next();
0313:                        populateFileMetaData(filemd, clr, null);
0314:                    }
0315:
0316:                    // b). Initialise MetaData
0317:                    if (JPOXLogger.METADATA.isDebugEnabled()) {
0318:                        JPOXLogger.METADATA.debug(LOCALISER.msg("044019"));
0319:                    }
0320:                    iter = fileMetaData.iterator();
0321:                    while (iter.hasNext()) {
0322:                        FileMetaData filemd = (FileMetaData) iter.next();
0323:                        try {
0324:                            initialiseFileMetaData(filemd, clr, null);
0325:                        } catch (Exception e) {
0326:                            exceptions.add(e);
0327:                        }
0328:                    }
0329:                    if (exceptions.size() > 0) {
0330:                        throw new JPOXUserException(LOCALISER.msg("044020"),
0331:                                (Throwable[]) exceptions
0332:                                        .toArray(new Throwable[exceptions
0333:                                                .size()]));
0334:                    }
0335:                }
0336:
0337:                if (JPOXLogger.METADATA.isDebugEnabled()) {
0338:                    JPOXLogger.METADATA.debug(LOCALISER.msg("044014"));
0339:                }
0340:                initialised = true;
0341:                return (FileMetaData[]) fileMetaData
0342:                        .toArray(new FileMetaData[fileMetaData.size()]);
0343:            }
0344:
0345:            /**
0346:             * Initialisation method to define the "persistence-unit" being handled by this MetaDataManager.
0347:             * @param persistenceUnitName name of the "persistence-unit"
0348:             * @param clr ClassLoader Resolver
0349:             * @return Array of the FileMetaData that is managed
0350:             * @throws JPOXUserException if an error occurs parsing the persistence-unit info
0351:             */
0352:            public FileMetaData[] initialise(String persistenceUnitName,
0353:                    ClassLoaderResolver clr) {
0354:                PersistenceUnitMetaData pumd = null;
0355:                pumd = getMetaDataForPersistenceUnit(persistenceUnitName);
0356:                if (pumd == null) {
0357:                    throw new JPOXUserException(LOCALISER.msg("044047",
0358:                            persistenceUnitName));
0359:                } else {
0360:                    return initialise(pumd, clr);
0361:                }
0362:            }
0363:
0364:            /**
0365:             * Initialisation method to define the "persistence-unit" being handled by this MetaDataManager.
0366:             * @param pumd The MetaData for this "persistence-unit"
0367:             * @param clr ClassLoader Resolver
0368:             * @return Array of the FileMetaData that is managed
0369:             * @throws JPOXUserException if an error occurs parsing the persistence-unit info
0370:             */
0371:            public FileMetaData[] initialise(PersistenceUnitMetaData pumd,
0372:                    ClassLoaderResolver clr) {
0373:                if (initialised) {
0374:                    // TODO Throw exception
0375:                    return null;
0376:                }
0377:                if (JPOXLogger.METADATA.isDebugEnabled()) {
0378:                    JPOXLogger.METADATA.debug(LOCALISER.msg("044021", pumd
0379:                            .getName()));
0380:                }
0381:
0382:                HashSet exceptions = new HashSet();
0383:                ArrayList fileMetaData = new ArrayList();
0384:
0385:                // Load XML metadata for all <mapping-file> specifications
0386:                HashSet mappingFiles = new HashSet();
0387:                mappingFiles.add("META-INF/orm.xml"); // Default location
0388:                if (pumd.getMappingFiles() != null) {
0389:                    mappingFiles.addAll(pumd.getMappingFiles());
0390:                }
0391:                if (mappingFiles != null && mappingFiles.size() > 0) {
0392:                    Iterator iter = mappingFiles.iterator();
0393:                    while (iter.hasNext()) {
0394:                        String mappingFileName = (String) iter.next();
0395:                        try {
0396:                            Enumeration files = clr.getResources(
0397:                                    mappingFileName, Thread.currentThread()
0398:                                            .getContextClassLoader());
0399:                            while (files.hasMoreElements()) {
0400:                                URL url = (URL) files.nextElement();
0401:                                if (url != null
0402:                                        && fileMetaDataByURLString.get(url
0403:                                                .toString()) == null) {
0404:                                    FileMetaData filemd = parseFile(url);
0405:                                    if (filemd != null) {
0406:                                        // Register the file
0407:                                        registerFile(url.toString(), filemd,
0408:                                                clr);
0409:                                        fileMetaData.add(filemd);
0410:                                    }
0411:                                }
0412:                            }
0413:                        } catch (InvalidMetaDataException imde) {
0414:                            // Error in the metadata for this file
0415:                            JPOXLogger.METADATA.error(StringUtils
0416:                                    .getStringFromStackTrace(imde));
0417:                            exceptions.add(imde);
0418:                        } catch (IOException ioe) {
0419:                            JPOXLogger.METADATA.error(LOCALISER.msg("044027",
0420:                                    pumd.getName(), mappingFileName, ioe
0421:                                            .getMessage()), ioe);
0422:                        }
0423:                    }
0424:                }
0425:
0426:                // Load annotation metadata for all <class>, <jar-file> specifications
0427:                Set classNames = new HashSet();
0428:                if (!enhancing) {
0429:                    HashSet jarFileNames = pumd.getJarFiles();
0430:                    if (jarFileNames != null) {
0431:                        Iterator iter = jarFileNames.iterator();
0432:                        while (iter.hasNext()) {
0433:                            Object jarFile = iter.next();
0434:                            if (jarFile instanceof  String) {
0435:                                String[] jarClassNames = ClassUtils
0436:                                        .getClassNamesForJarFile((String) jarFile);
0437:                                if (jarClassNames != null) {
0438:                                    for (int i = 0; i < jarClassNames.length; i++) {
0439:                                        classNames.add(jarClassNames[i]);
0440:                                    }
0441:                                }
0442:                            } else if (jarFile instanceof  URL) {
0443:                                String[] jarClassNames = ClassUtils
0444:                                        .getClassNamesForJarFile((URL) jarFile);
0445:                                if (jarClassNames != null) {
0446:                                    for (int i = 0; i < jarClassNames.length; i++) {
0447:                                        classNames.add(jarClassNames[i]);
0448:                                    }
0449:                                }
0450:                            }
0451:                        }
0452:                    }
0453:                }
0454:                if (pumd.getClassNames() != null) {
0455:                    classNames.addAll(pumd.getClassNames());
0456:                }
0457:                if (classNames.size() > 0 && annotationManager != null) {
0458:                    // Process all classes
0459:                    Iterator iter = classNames.iterator();
0460:                    while (iter.hasNext()) {
0461:                        // Check for MetaData for this class (take precedence over annotations if they exist)
0462:                        String className = (String) iter.next();
0463:                        AbstractClassMetaData cmd = (AbstractClassMetaData) classMetaDataByClass
0464:                                .get(className);
0465:                        if (cmd == null) {
0466:                            // No MetaData so try annotations
0467:                            try {
0468:                                Class cls = clr.classForName(className);
0469:                                FileMetaData filemd = loadAnnotationsForClass(
0470:                                        cls, clr, true, false);
0471:                                if (filemd != null) {
0472:                                    fileMetaData.add(filemd);
0473:                                }
0474:                            } catch (Exception e) {
0475:                                exceptions.add(e);
0476:                            }
0477:                        } else {
0478:                            // We have MetaData, and any annotations will be merged in during the populate process
0479:                        }
0480:                    }
0481:                }
0482:
0483:                if (exceptions.size() > 0) {
0484:                    throw new JPOXUserException(LOCALISER.msg("044026", pumd
0485:                            .getName()), (Throwable[]) exceptions
0486:                            .toArray(new Throwable[exceptions.size()]));
0487:                }
0488:
0489:                if (fileMetaData.size() > 0) {
0490:                    // MetaData has been loaded for the unit
0491:                    // a). Populate MetaData
0492:                    if (JPOXLogger.METADATA.isDebugEnabled()) {
0493:                        JPOXLogger.METADATA.debug(LOCALISER.msg("044024", pumd
0494:                                .getName()));
0495:                    }
0496:                    Iterator iter = fileMetaData.iterator();
0497:                    while (iter.hasNext()) {
0498:                        FileMetaData filemd = (FileMetaData) iter.next();
0499:                        populateFileMetaData(filemd, clr, null);
0500:                    }
0501:
0502:                    // b). Initialise MetaData
0503:                    if (JPOXLogger.METADATA.isDebugEnabled()) {
0504:                        JPOXLogger.METADATA.debug(LOCALISER.msg("044025", pumd
0505:                                .getName()));
0506:                    }
0507:                    iter = fileMetaData.iterator();
0508:                    while (iter.hasNext()) {
0509:                        FileMetaData filemd = (FileMetaData) iter.next();
0510:                        try {
0511:                            initialiseFileMetaData(filemd, clr, null);
0512:                        } catch (Exception e) {
0513:                            JPOXLogger.METADATA.error(StringUtils
0514:                                    .getStringFromStackTrace(e));
0515:                            exceptions.add(e);
0516:                        }
0517:                    }
0518:                    if (exceptions.size() > 0) {
0519:                        throw new JPOXUserException(LOCALISER.msg("044026",
0520:                                pumd.getName()), (Throwable[]) exceptions
0521:                                .toArray(new Throwable[exceptions.size()]));
0522:                    }
0523:                }
0524:
0525:                if (JPOXLogger.METADATA.isDebugEnabled()) {
0526:                    JPOXLogger.METADATA.debug(LOCALISER.msg("044022", pumd
0527:                            .getName()));
0528:                }
0529:                initialised = true;
0530:                return (FileMetaData[]) fileMetaData
0531:                        .toArray(new FileMetaData[fileMetaData.size()]);
0532:            }
0533:
0534:            /**
0535:             * Mutator for whether to validate the MetaData files for XML compliance.
0536:             * @param validate Whether to validate
0537:             */
0538:            public void setValidate(boolean validate) {
0539:                validateMetaData = validate;
0540:            }
0541:
0542:            /**
0543:             * Accessor for the ObjectManagerFactory Context that this manager is running in.
0544:             * @return The ObjectManagerFactory Context
0545:             */
0546:            public OMFContext getOMFContext() {
0547:                return omfContext;
0548:            }
0549:
0550:            /**
0551:             * Accessor for the API adapter being used by this MetaDataManager.
0552:             * @return API adapter.
0553:             */
0554:            public ApiAdapter getApiAdapter() {
0555:                return omfContext.getApiAdapter();
0556:            }
0557:
0558:            /**
0559:             * Clear resources
0560:             */
0561:            public void close() {
0562:                classMetaDataByClass.clear();
0563:                queryMetaDataByName.clear();
0564:                fetchPlanMetaDataByName.clear();
0565:                sequenceMetaDataByPackageSequence.clear();
0566:                tableGeneratorMetaDataByPackageSequence.clear();
0567:                queryResultMetaDataByName.clear();
0568:                fileMetaDataByURLString.clear();
0569:                classesWithoutPersistenceInfo.clear();
0570:                classMetaDataByClass = null;
0571:                queryMetaDataByName = null;
0572:                fetchPlanMetaDataByName = null;
0573:                sequenceMetaDataByPackageSequence = null;
0574:                tableGeneratorMetaDataByPackageSequence = null;
0575:                fileMetaDataByURLString = null;
0576:                classesWithoutPersistenceInfo = null;
0577:            }
0578:
0579:            /**
0580:             * Accessor for whether we are managing the enhancement process.
0581:             * @return Whether we are enhancing
0582:             */
0583:            public boolean isEnhancing() {
0584:                return enhancing;
0585:            }
0586:
0587:            /**
0588:             * Convenience method to return if the specified class is a known persistable class.
0589:             * @param className Name of the class
0590:             * @return Whether it is persistable
0591:             */
0592:            public boolean isClassPersistable(String className) {
0593:                AbstractClassMetaData acmd = readMetaDataForClass(className);
0594:                if (acmd == null) {
0595:                    return false;
0596:                }
0597:                return (acmd.getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE);
0598:            }
0599:
0600:            /**
0601:             * Accessor for all FileMetaData currently managed here.
0602:             * @return FileMetaData managed here currently
0603:             */
0604:            public FileMetaData[] getFileMetaData() {
0605:                Collection filemds = fileMetaDataByURLString.values();
0606:                return (FileMetaData[]) filemds
0607:                        .toArray(new FileMetaData[filemds.size()]);
0608:            }
0609:
0610:            /**
0611:             * Accessor for the names of the classes with MetaData currently registered with this manager.
0612:             * @return Names of classes with MetaData
0613:             */
0614:            public Collection getClassesWithMetaData() {
0615:                return Collections.unmodifiableCollection(classMetaDataByClass
0616:                        .keySet());
0617:            }
0618:
0619:            /**
0620:             * Convenience method to check if we have metadata present for the specified class.
0621:             * @param className The name of the class to check
0622:             * @return Whether the metadata is already registered for this class
0623:             */
0624:            public boolean hasMetaDataForClass(String className) {
0625:                if (className == null) {
0626:                    return false;
0627:                }
0628:
0629:                // Check if this class has no MetaData before instantiating its class
0630:                if (isClassWithoutPersistenceInfo(className)) {
0631:                    return false;
0632:                }
0633:
0634:                return (classMetaDataByClass.get(className) != null);
0635:            }
0636:
0637:            /**
0638:             * Accessor for whether a class doesn't have MetaData or annotations.
0639:             * @param className Name of the class
0640:             * @return Whether it has no metadata and annotations
0641:             */
0642:            protected boolean isClassWithoutPersistenceInfo(String className) {
0643:                if (className == null) {
0644:                    return true;
0645:                }
0646:
0647:                // Standard Java classes have no MetaData
0648:                if (className.startsWith("java.")
0649:                        || className.startsWith("javax.")) {
0650:                    return true;
0651:                }
0652:
0653:                // Use the cache to determine if it has metadata
0654:                return classesWithoutPersistenceInfo.contains(className);
0655:            }
0656:
0657:            /**
0658:             * Accessor for the MetaData for a class given the name and a loader.
0659:             * All MetaData returned from this method will be initialised and ready for full use.
0660:             * If the class can't be loaded, null will be returned. 
0661:             * @param className Name of the class to find MetaData for
0662:             * @param clr ClassLoaderResolver resolver for use in loading the class.
0663:             * @return The ClassMetaData for this class (or null if not found)
0664:             **/
0665:            public synchronized AbstractClassMetaData getMetaDataForClass(
0666:                    String className, ClassLoaderResolver clr) {
0667:                if (className == null) {
0668:                    return null;
0669:                }
0670:
0671:                // Check if this class has no MetaData/annotations before instantiating its class
0672:                if (isClassWithoutPersistenceInfo(className)) {
0673:                    return null;
0674:                }
0675:
0676:                // Resolve the class
0677:                Class c = null;
0678:                try {
0679:                    if (clr == null) {
0680:                        c = Class.forName(className);
0681:                    } else {
0682:                        c = clr.classForName(className, null, false);
0683:                    }
0684:                } catch (ClassNotFoundException cnfe) {
0685:                } catch (ClassNotResolvedException cnre) {
0686:                }
0687:                if (c == null) {
0688:                    return null;
0689:                }
0690:
0691:                return getMetaDataForClass(c, clr);
0692:            }
0693:
0694:            /** Temporary list of the FileMetaData objects utilised in this call for metadata. */
0695:            protected ArrayList utilisedFileMetaData = new ArrayList();
0696:
0697:            /**
0698:             * Main accessor for the MetaData for a class.
0699:             * All MetaData returned from this method will be initialised and ready for full use.
0700:             * @param c The class to find MetaData for
0701:             * @param clr the ClassLoaderResolver
0702:             * @return The ClassMetaData for this class (or null if not found)
0703:             */
0704:            public synchronized AbstractClassMetaData getMetaDataForClass(
0705:                    Class c, ClassLoaderResolver clr) {
0706:                if (c == null) {
0707:                    return null;
0708:                }
0709:
0710:                if (isClassWithoutPersistenceInfo(c.getName())) {
0711:                    return null;
0712:                }
0713:
0714:                AbstractClassMetaData cmd = null;
0715:                if (c.isInterface()) {
0716:                    // "persistent-interface" - check if it has class built at runtime and return the MetaData for it 
0717:                    cmd = getClassMetaDataForImplementationOfPersistentInterface(c
0718:                            .getName());
0719:                } else {
0720:                    // "persistent-class"
0721:                    cmd = getMetaDataForClassInternal(c, clr);
0722:                }
0723:
0724:                if (cmd != null) {
0725:                    // Make sure that anything returned is initialised
0726:                    if (!cmd.isPopulated()) {
0727:                        // Initialise the class in question
0728:                        cmd.populate();
0729:                    }
0730:                    if (!cmd.isInitialised()) {
0731:                        // Initialise the class in question
0732:                        cmd.initialise();
0733:                    }
0734:
0735:                    if (utilisedFileMetaData.size() > 0) {
0736:                        // Initialise all FileMetaData that were processed in this call
0737:                        Iterator iter = utilisedFileMetaData.iterator();
0738:                        while (iter.hasNext()) {
0739:                            FileMetaData filemd = (FileMetaData) iter.next();
0740:                            initialiseFileMetaData(filemd, clr, c
0741:                                    .getClassLoader());
0742:                        }
0743:                    }
0744:                } else {
0745:                    if (!c.isInterface()) {
0746:                        classesWithoutPersistenceInfo.add(c.getName());
0747:                    }
0748:                }
0749:                utilisedFileMetaData.clear();
0750:                return cmd;
0751:            }
0752:
0753:            /**
0754:             * Accessor for the MetaData for a class given the "entity-name".
0755:             * @param entityName The entity name to find MetaData for
0756:             * @return The ClassMetaData for this entity name (or null if not found)
0757:             */
0758:            public synchronized AbstractClassMetaData getMetaDataForEntityName(
0759:                    String entityName) {
0760:                return (AbstractClassMetaData) classMetaDataByEntityName
0761:                        .get(entityName);
0762:            }
0763:
0764:            /**
0765:             * Method to access the (already known) metadata for the specified class.
0766:             * If the class is not yet known about it returns null.
0767:             * @param className Name of the class
0768:             * @return MetaData for the class
0769:             */
0770:            public AbstractClassMetaData readMetaDataForClass(String className) {
0771:                return (AbstractClassMetaData) classMetaDataByClass
0772:                        .get(className);
0773:            }
0774:
0775:            /**
0776:             * Method to access the (already known) metadata for the field/property of the specified class.
0777:             * If the class (or this field/property) is not yet known about it returns null.
0778:             * @param className Name of the class
0779:             * @param memberName Name of the field/property
0780:             * @return MetaData for the field/property
0781:             */
0782:            public AbstractMemberMetaData readMetaDataForMember(
0783:                    String className, String memberName) {
0784:                AbstractClassMetaData cmd = readMetaDataForClass(className);
0785:                return (cmd != null ? cmd.getMetaDataForMember(memberName)
0786:                        : null);
0787:            }
0788:
0789:            /**
0790:             * Internal convenience method for accessing the MetaData for a class.
0791:             * MetaData returned by this method may be uninitialised so should only really
0792:             * be used in initialisation processes.
0793:             * To be implemented by the implementing class.
0794:             * @param c The class to find MetaData for
0795:             * @return The ClassMetaData for this class (or null if not found)
0796:             **/
0797:            public abstract AbstractClassMetaData getMetaDataForClassInternal(
0798:                    Class c, ClassLoaderResolver clr);
0799:
0800:            /**
0801:             * Accessor for the subclasses of a particular class
0802:             * @param className Name of the class that we want the known subclasses for.
0803:             * @param includeDescendents Whether to include subclasses of subclasses etc
0804:             * @return Names of the subclasses. return null if there are no subclasses
0805:             */
0806:            public String[] getSubclassesForClass(String className,
0807:                    boolean includeDescendents) {
0808:                Collection subclassNames = new HashSet();
0809:                provideSubclassesForClass(className, includeDescendents,
0810:                        subclassNames);
0811:                if (subclassNames.size() > 0) {
0812:                    return (String[]) subclassNames
0813:                            .toArray(new String[subclassNames.size()]);
0814:                }
0815:
0816:                return null;
0817:            }
0818:
0819:            /**
0820:             * Provide the subclasses of a particular class to a given <code>consumer</code>
0821:             * @param className Name of the class that we want the known subclasses for.
0822:             * @param includeDescendents Whether to include subclasses of subclasses etc
0823:             * @param consumer the Collection (Set) where discovered subclasses are added
0824:             */
0825:            private void provideSubclassesForClass(String className,
0826:                    boolean includeDescendents, Collection consumer) {
0827:                Collection cmds = classMetaDataByClass.values();
0828:                Iterator cmdIter = cmds.iterator();
0829:                while (cmdIter.hasNext()) {
0830:                    AbstractClassMetaData acmd = (AbstractClassMetaData) cmdIter
0831:                            .next();
0832:                    if (acmd instanceof  ClassMetaData) {
0833:                        ClassMetaData cmd = (ClassMetaData) acmd;
0834:                        if (cmd.getPersistenceCapableSuperclass() != null
0835:                                && cmd.getPersistenceCapableSuperclass()
0836:                                        .equals(className)) {
0837:                            if (consumer.add(cmd.getFullClassName())
0838:                                    && includeDescendents) {
0839:                                //go deeper in subclasses
0840:                                provideSubclassesForClass(cmd
0841:                                        .getFullClassName(),
0842:                                        includeDescendents, consumer);
0843:                            }
0844:                        }
0845:                    }
0846:                }
0847:            }
0848:
0849:            /**
0850:             * Accessor for the list of names of classes that are declared to implement the specified interface
0851:             * (using &lt;implements&gt; in the MetaData). This will include subclasses of declared classes. Ignore abstract classes.
0852:             * The array of implementation class names will have the initial implementations first followed by
0853:             * the subclass implementations etc. So for example if we look for all implementations of I and A implements I
0854:             * and B extends A, then it will return [A, B] in that order.
0855:             * @param interfaceName Name of the interface
0856:             * @param clr The ClassLoaderResolver
0857:             * @return The names of the classes declared as implementing that interface. return null if no classes
0858:             */
0859:            public String[] getClassesImplementingInterface(
0860:                    String interfaceName, ClassLoaderResolver clr) {
0861:                Collection classes = new HashSet();
0862:                Class intfClass = clr.classForName(interfaceName);
0863:
0864:                // Loop through all known classes and find the implementations
0865:                // TODO This completely ignores the <implements> keyword info and should use it
0866:                Collection cmds = classMetaDataByClass.values();
0867:                Iterator cmdIter = cmds.iterator();
0868:                boolean isPersistentInterface = false;
0869:                while (cmdIter.hasNext()) {
0870:                    AbstractClassMetaData acmd = (AbstractClassMetaData) cmdIter
0871:                            .next();
0872:                    Class implClass = clr.classForName(acmd.getFullClassName());
0873:                    if (acmd instanceof  ClassMetaData) {
0874:                        if (!acmd.isInitialised()) {
0875:                            // Make sure that we are initialised since implementsMetaData wont be set
0876:                            acmd.initialise();
0877:                        }
0878:                        if (intfClass.isAssignableFrom(implClass)) {
0879:                            if (!((ClassMetaData) acmd)
0880:                                    .isAbstractPersistenceCapable()) {
0881:                                classes.add(implClass);
0882:                            }
0883:                        }
0884:                    } else if (acmd instanceof  InterfaceMetaData) {
0885:                        if (intfClass.isAssignableFrom(implClass)) {
0886:                            isPersistentInterface = true;
0887:                        }
0888:                    }
0889:                }
0890:
0891:                if (isPersistentInterface) {
0892:                    // JDO2 "persistent interfaces"
0893:                    // This deliberately kept separate from normal persistence since it is largely undocumented and best left alone
0894:                    //TODO this is very time consuming. got to do some cache
0895:                    classes.add(omfContext.getImplementationCreator()
0896:                            .newInstance(intfClass, this , clr).getClass());
0897:
0898:                    String[] classNames = new String[classes.size()];
0899:                    Iterator iter = classes.iterator();
0900:                    int i = 0;
0901:                    while (iter.hasNext()) {
0902:                        classNames[i++] = ((Class) iter.next()).getName();
0903:                    }
0904:                    return classNames;
0905:                } else if (classes.size() > 0) {
0906:                    // Normal persistence
0907:                    // Put the classes into a sorter so we make sure we get the initial implementations first followed
0908:                    // by any subclasses of these implementations. This is needed because when generating the schema we require
0909:                    // the subclass implementations to already have their datastore column created
0910:                    Collection classesSorted = new TreeSet(
0911:                            new InterfaceClassComparator());
0912:                    Iterator classesIter = classes.iterator();
0913:                    while (classesIter.hasNext()) {
0914:                        classesSorted.add(classesIter.next());
0915:                    }
0916:
0917:                    // Return the class names (in the same order)
0918:                    String[] classNames = new String[classesSorted.size()];
0919:                    Iterator iter = classesSorted.iterator();
0920:                    int i = 0;
0921:                    while (iter.hasNext()) {
0922:                        classNames[i++] = ((Class) iter.next()).getName();
0923:                    }
0924:                    return classNames;
0925:                }
0926:                return null;
0927:            }
0928:
0929:            /**
0930:             * Simple comparator that orders the implementations of an interface so that the initial implementations
0931:             * are first, and the subclasses later.
0932:             */
0933:            private class InterfaceClassComparator implements  Comparator {
0934:                /**
0935:                 * Default constructor.
0936:                 */
0937:                public InterfaceClassComparator() {
0938:                    // Nothing to do
0939:                }
0940:
0941:                /**
0942:                 * Method defining the ordering of objects.
0943:                 * Places all nulls at the end.
0944:                 * @param o1 First object
0945:                 * @param o2 Second object
0946:                 * @return The comparison result
0947:                 */
0948:                public int compare(Object o1, Object o2) {
0949:                    if (o1 == null && o2 == null) {
0950:                        return 0;
0951:                    } else if (o1 == null || o2 == null) {
0952:                        return Integer.MIN_VALUE;
0953:                    }
0954:
0955:                    // Just order based on hashcode
0956:                    Class cls1 = (Class) o1;
0957:                    Class cls2 = (Class) o2;
0958:                    return cls1.hashCode() - cls2.hashCode();
0959:                }
0960:            }
0961:
0962:            /**
0963:             * Load up and add any O/R mapping info for the specified class to the stored ClassMetaData (if supported).
0964:             * This implementation does nothing so if ORM files are supported then this should be overridden by subclasses.
0965:             * Is package-access so that is only accessable by MetaData classes
0966:             * @param c The class
0967:             * @param clr ClassLoader resolver
0968:             */
0969:            protected void addORMDataToClass(Class c, ClassLoaderResolver clr) {
0970:                // Default to doing nothing. Specified in subclasses if they support it
0971:                return;
0972:            }
0973:
0974:            /**
0975:             * Load up and add any annotations mapping info for the specified class to the stored ClassMetaData.
0976:             * Is package-access so that is only accessable by MetaData classes
0977:             * @param c The class
0978:             * @param cmd the metadata to add annotation to
0979:             * @param clr ClassLoader resolver
0980:             */
0981:            void addAnnotationsDataToClass(Class c, AbstractClassMetaData cmd,
0982:                    ClassLoaderResolver clr) {
0983:                // Get the MetaData for this class/interface
0984:                if (cmd.getPackageMetaData() != null
0985:                        && cmd.getPackageMetaData().getFileMetaData() != null
0986:                        && cmd.getPackageMetaData().getFileMetaData().getType() == FileMetaData.ANNOTATIONS) {
0987:                    // Our MetaData is derived from the Annotations so nothing to merge!
0988:                    return;
0989:                }
0990:
0991:                // Find if there is any annotations metadata available
0992:                FileMetaData filemd = loadAnnotationsForClass(c, clr, false,
0993:                        false);
0994:                if (filemd != null) {
0995:                    AbstractClassMetaData annotCmd = filemd.getPackage(0)
0996:                            .getClass(0);
0997:                    if (annotCmd != null) {
0998:                        // Merge the annotations MetaData into the class MetaData
0999:                        MetaDataMerger.mergeClassAnnotationsData(cmd, annotCmd);
1000:                    }
1001:                }
1002:            }
1003:
1004:            /**
1005:             * Accessor for the MetaData for an implementation of a reference type.
1006:             * Finds the metadata for the implementation of this reference.
1007:             * @param referenceClass The reference class to find MetaData for
1008:             * @param implValue Object of an implementation class, to return if possible (null=ignore)
1009:             * @param clr ClassLoader resolver
1010:             * @return The ClassMetaData for an implementation of a reference type
1011:             */
1012:            public ClassMetaData getMetaDataForImplementationOfReference(
1013:                    Class referenceClass, Object implValue,
1014:                    ClassLoaderResolver clr) {
1015:                if (referenceClass == null
1016:                        || (!referenceClass.isInterface() && referenceClass != java.lang.Object.class)) {
1017:                    return null;
1018:                }
1019:
1020:                // Check if this is a "persistent interface"
1021:                Object intfMetaData = getClassMetaDataForImplementationOfPersistentInterface(referenceClass
1022:                        .getName());
1023:                if (intfMetaData != null) {
1024:                    return (ClassMetaData) intfMetaData;
1025:                }
1026:
1027:                ClassMetaData cmd = null;
1028:
1029:                // Search for the class required
1030:                Set classMetaDataClasses = classMetaDataByClass.keySet();
1031:                Iterator classMetaDataClassesIter = classMetaDataClasses
1032:                        .iterator();
1033:                while (classMetaDataClassesIter.hasNext()) {
1034:                    String class_name = (String) classMetaDataClassesIter
1035:                            .next();
1036:                    AbstractClassMetaData acmd_cls = (AbstractClassMetaData) classMetaDataByClass
1037:                            .get(class_name);
1038:
1039:                    if (acmd_cls instanceof  ClassMetaData) {
1040:                        try {
1041:                            // Check if class is implementation of "implValue" (in the case of java.lang.Object, all will be!)
1042:                            Class cls = referenceClass.getClassLoader()
1043:                                    .loadClass(class_name);
1044:                            if (referenceClass.isAssignableFrom(cls)) {
1045:                                // Find the base class that is an implementation
1046:                                cmd = (ClassMetaData) acmd_cls;
1047:                                if (implValue != null
1048:                                        && cmd.getFullClassName().equals(
1049:                                                implValue.getClass().getName())) {
1050:                                    return cmd;
1051:                                }
1052:
1053:                                AbstractClassMetaData cmd_super class = cmd
1054:                                        .getSuperAbstractClassMetaData();
1055:                                while (cmd_super class != null) {
1056:                                    if (!referenceClass
1057:                                            .isAssignableFrom(clr
1058:                                                    .classForName(((ClassMetaData) cmd_super class)
1059:                                                            .getFullClassName()))) {
1060:                                        break;
1061:                                    }
1062:                                    // TODO Check if superclass is an implementation
1063:                                    cmd = (ClassMetaData) cmd_super class;
1064:                                    if (implValue != null
1065:                                            && cmd.getFullClassName().equals(
1066:                                                    implValue.getClass()
1067:                                                            .getName())) {
1068:                                        break;
1069:                                    }
1070:
1071:                                    // Go to next superclass
1072:                                    cmd_super class = cmd_super class
1073:                                            .getSuperAbstractClassMetaData();
1074:                                    if (cmd_super class == null) {
1075:                                        break;
1076:                                    }
1077:                                }
1078:                            }
1079:                        } catch (Exception e) {
1080:                        }
1081:                    }
1082:                }
1083:
1084:                return cmd;
1085:            }
1086:
1087:            /**
1088:             * Accessor for the MetaData for a field/property of a class. 
1089:             * Utilises getMetaDataForClass, and then finds the relevant field/property.
1090:             * @param className The name of the class owning the field/property
1091:             * @param memberName The name of the field to find MetaData for
1092:             * @param clr ClassLoaderResolver resolver for any loading of classes
1093:             * @return The metadata for this field/property (or null if not found)
1094:             */
1095:            public AbstractMemberMetaData getMetaDataForMember(
1096:                    String className, String memberName, ClassLoaderResolver clr) {
1097:                if (className == null || memberName == null) {
1098:                    return null;
1099:                }
1100:
1101:                AbstractClassMetaData cmd = getMetaDataForClass(className, clr);
1102:                return (cmd != null ? cmd.getMetaDataForMember(memberName)
1103:                        : null);
1104:            }
1105:
1106:            /**
1107:             * Accessor for the MetaData for a field/property of a class.
1108:             * Utilises getMetaDataForClass, and then finds the relevant field/property.
1109:             * @param c The class owning the field/property
1110:             * @param clr the ClassLoaderResolver
1111:             * @param memberName The name of the field/property to find MetaData for
1112:             * @return The metadata for this field/property (or null if not found)
1113:             */
1114:            public AbstractMemberMetaData getMetaDataForMember(Class c,
1115:                    ClassLoaderResolver clr, String memberName) {
1116:                if (c == null || memberName == null) {
1117:                    return null;
1118:                }
1119:
1120:                AbstractClassMetaData cmd = getMetaDataForClass(c, clr);
1121:                return (cmd != null ? cmd.getMetaDataForMember(memberName)
1122:                        : null);
1123:            }
1124:
1125:            /**
1126:             * Accessor for the MetaData for a named query for a class.
1127:             * If the class is not specified, searches for the query with this name for any class.
1128:             * Will only return metadata for queries already registered in this implementation.
1129:             * @param cls The class which has the query defined for it
1130:             * @param clr the ClassLoaderResolver
1131:             * @param queryName Name of the query
1132:             * @return The QueryMetaData for the query for this class
1133:             **/
1134:            public QueryMetaData getMetaDataForQuery(Class cls,
1135:                    ClassLoaderResolver clr, String queryName) {
1136:                if (queryName == null) {
1137:                    return null;
1138:                }
1139:
1140:                String query_key = queryName;
1141:                if (cls != null) {
1142:                    query_key = cls.getName() + "_" + queryName;
1143:                }
1144:                return (QueryMetaData) queryMetaDataByName.get(query_key);
1145:            }
1146:
1147:            /**
1148:             * Accessor for the MetaData for a named fetch plan.
1149:             * @param name Name of the fetch plan
1150:             * @return The FetchPlanMetaData for this name (if any)
1151:             **/
1152:            public FetchPlanMetaData getMetaDataForFetchPlan(String name) {
1153:                if (name == null) {
1154:                    return null;
1155:                }
1156:
1157:                return (FetchPlanMetaData) fetchPlanMetaDataByName.get(name);
1158:            }
1159:
1160:            /**
1161:             * Accessor for the MetaData for a Sequence in a package.
1162:             * This implementation simply checks what is already loaded and returns if found
1163:             * @param clr the ClassLoaderResolver
1164:             * @param seqName Name of the package (fully qualified if necessary)
1165:             * @return The SequenceMetaData for this named sequence
1166:             **/
1167:            public SequenceMetaData getMetaDataForSequence(
1168:                    ClassLoaderResolver clr, String seqName) {
1169:                if (seqName == null) {
1170:                    return null;
1171:                }
1172:
1173:                return (SequenceMetaData) sequenceMetaDataByPackageSequence
1174:                        .get(seqName);
1175:            }
1176:
1177:            /**
1178:             * Accessor for the MetaData for a TableGenerator in a package.
1179:             * This implementation simply checks what is already loaded and returns if found
1180:             * @param clr the ClassLoaderResolver
1181:             * @param genName Name of the package (fully qualified if necessary)
1182:             * @return The TableGenerator for this named generator
1183:             **/
1184:            public TableGeneratorMetaData getMetaDataForTableGenerator(
1185:                    ClassLoaderResolver clr, String genName) {
1186:                if (genName == null) {
1187:                    return null;
1188:                }
1189:
1190:                return (TableGeneratorMetaData) tableGeneratorMetaDataByPackageSequence
1191:                        .get(genName);
1192:            }
1193:
1194:            /**
1195:             * Accessor for the MetaData for a QueryResult.
1196:             * @param name Name of the query result
1197:             * @return The QueryResultMetaData under this name
1198:             **/
1199:            public QueryResultMetaData getMetaDataForQueryResult(String name) {
1200:                if (name == null) {
1201:                    return null;
1202:                }
1203:
1204:                return (QueryResultMetaData) queryResultMetaDataByName
1205:                        .get(name);
1206:            }
1207:
1208:            // ------------------------------- Persistent Interfaces ---------------------------------------
1209:
1210:            /**
1211:             * Accessor for the MetaData for an interface.
1212:             * Part of the support for "persistent-interface".
1213:             * This defaults to returning null since interfaces are only supported by JDO.
1214:             * @param c The interface to find MetaData for
1215:             * @param clr the ClassLoaderResolver
1216:             * @return The InterfaceMetaData for this interface (or null if not found)
1217:             */
1218:            public InterfaceMetaData getMetaDataForInterface(Class c,
1219:                    ClassLoaderResolver clr) {
1220:                return null;
1221:            }
1222:
1223:            /**
1224:             * Convenience method to return if the passed class name is a "persistent-interface".
1225:             * @param name Name if the interface
1226:             * @return Whether it is a "persistent-interface"
1227:             */
1228:            public boolean isPersistentInterface(String name) {
1229:                // Default to not supporting "persistent-interface"s
1230:                return false;
1231:            }
1232:
1233:            /**
1234:             * Convenience method to return if the passed class name is an implementation of the passed "persistent-interface".
1235:             * @param interfaceName Name of the persistent interface
1236:             * @param implName The implementation name
1237:             * @return Whether it is a (JPOX-generated) impl of the persistent interface
1238:             */
1239:            public boolean isPersistentInterfaceImplementation(
1240:                    String interfaceName, String implName) {
1241:                // Default to not supporting "persistent-interface"s
1242:                return false;
1243:            }
1244:
1245:            /**
1246:             * Convenience method to return if the passed class name is an implementation of a "persistent definition".
1247:             * @param implName The implementation name
1248:             * @return Whether it is a (JPOX-generated) impl of the persistent interface or abstract class
1249:             */
1250:            public boolean isPersistentDefinitionImplementation(String implName) {
1251:                return false;
1252:            }
1253:
1254:            /**
1255:             * Accessor for the implementation name for the specified "persistent-interface".
1256:             * @param interfaceName The name of the persistent interface
1257:             * @return The name of the implementation class
1258:             */
1259:            public String getImplementationNameForPersistentInterface(
1260:                    String interfaceName) {
1261:                // Default to not supporting "persistent-interface"s
1262:                return null;
1263:            }
1264:
1265:            /**
1266:             * Accessor for the metadata for the implementation of the specified "persistent-interface".
1267:             * @param interfaceName The name of the persistent interface
1268:             * @return The ClassMetaData of the implementation class
1269:             */
1270:            public ClassMetaData getClassMetaDataForImplementationOfPersistentInterface(
1271:                    String interfaceName) {
1272:                // Default to not supporting "persistent-interface"s
1273:                return null;
1274:            }
1275:
1276:            /**
1277:             * Method to register a persistent interface and its implementation with the MetaData system.
1278:             * @param imd MetaData for the interface
1279:             * @param implClass The implementation class
1280:             * @param clr ClassLoader Resolver to use
1281:             */
1282:            public void registerPersistentInterface(InterfaceMetaData imd,
1283:                    Class implClass, ClassLoaderResolver clr) {
1284:                // Default to not supporting "persistent-interface"s
1285:                return;
1286:            }
1287:
1288:            /**
1289:             * Method to register the metadata for an implementation of a persistent abstract class.
1290:             * @param cmd MetaData for the abstract class
1291:             * @param implClass The implementation class
1292:             * @param clr ClassLoader resolver
1293:             */
1294:            public void registerImplementationOfAbstractClass(
1295:                    ClassMetaData cmd, Class implClass, ClassLoaderResolver clr) {
1296:                // Default to not supporting "persistent-abstract-classes"
1297:                return;
1298:            }
1299:
1300:            // ------------------------------- Utilities -------------------------------
1301:
1302:            /**
1303:             * Method to parse all available "persistence.xml" files and return the metadata
1304:             * for the persistence unit with the specified name.
1305:             * @param unitName Name of the persistence-unit
1306:             * @return MetaData for the persistence-unit of the specified name (or null if not found)
1307:             * @throws JPOXUserException if no "persistence.xml" files are found
1308:             */
1309:            public PersistenceUnitMetaData getMetaDataForPersistenceUnit(
1310:                    String unitName) {
1311:                PersistenceFileMetaData[] files = parsePersistenceFiles();
1312:                if (files == null) {
1313:                    // No "persistence.xml" files found
1314:                    throw new JPOXUserException(LOCALISER.msg("044046"));
1315:                } else {
1316:                    for (int i = 0; i < files.length; i++) {
1317:                        PersistenceUnitMetaData[] unitmds = files[i]
1318:                                .getPersistenceUnits();
1319:                        for (int j = 0; j < unitmds.length; j++) {
1320:                            if (unitmds[j].getName().equals(unitName)) {
1321:                                // Found the required unit
1322:                                return unitmds[j];
1323:                            }
1324:                        }
1325:                    }
1326:                }
1327:                return null;
1328:            }
1329:
1330:            /**
1331:             * Method to parse the available "persistence.xml" files returning the metadata for all found.
1332:             * Searches for all files "META-INF/persistence.xml" in the CLASSPATH of the current thread.
1333:             * @return The metadata for all "persistence.xml" files
1334:             */
1335:            public PersistenceFileMetaData[] parsePersistenceFiles() {
1336:                HashSet metadata = new HashSet();
1337:                try {
1338:                    // Find all "META-INF/persistence.xml" files in the CLASSPATH of the current thread
1339:                    // TODO Use ClassLoaderResolver
1340:                    Enumeration files = Thread.currentThread()
1341:                            .getContextClassLoader().getResources(
1342:                                    "META-INF/persistence.xml");
1343:                    if (!files.hasMoreElements()) {
1344:                        return null;
1345:                    }
1346:
1347:                    metaDataParser = new MetaDataParser(this , validateMetaData);
1348:                    for (; files.hasMoreElements();) {
1349:                        // Parse the "persistence.xml"
1350:                        URL fileURL = (URL) files.nextElement();
1351:                        MetaData permd = metaDataParser.parseMetaDataURL(
1352:                                fileURL, "persistence");
1353:                        metadata.add(permd);
1354:                    }
1355:                } catch (IOException ioe) {
1356:                    // Do nothing
1357:                    JPOXLogger.METADATA.warn(StringUtils
1358:                            .getStringFromStackTrace(ioe));
1359:                }
1360:
1361:                return (PersistenceFileMetaData[]) metadata
1362:                        .toArray(new PersistenceFileMetaData[metadata.size()]);
1363:            }
1364:
1365:            /**
1366:             * Utility to parse a MetaData file.
1367:             * @param file_url URL of the file
1368:             * @return The FileMetaData for this file
1369:             */
1370:            protected abstract FileMetaData parseFile(URL file_url);
1371:
1372:            /**
1373:             * Method to take the FileMetaData and register the relevant parts of it with the assorted caches provided.
1374:             * @param fileURLString URL of the metadata file
1375:             * @param filemd The File MetaData
1376:             */
1377:            public abstract void registerFile(String fileURLString,
1378:                    FileMetaData filemd, ClassLoaderResolver clr);
1379:
1380:            /**
1381:             * Convenience method to register all sequences found in the passed file.
1382:             * @param filemd MetaData for the file
1383:             */
1384:            protected void registerSequencesForFile(FileMetaData filemd) {
1385:                // Register all sequences for the packages in this file
1386:                for (int i = 0; i < filemd.getNoOfPackages(); i++) {
1387:                    PackageMetaData pmd = filemd.getPackage(i);
1388:                    SequenceMetaData[] seqmds = pmd.getSequences();
1389:                    if (seqmds != null) {
1390:                        for (int j = 0; j < seqmds.length; j++) {
1391:                            // Register using its fully qualified name (JDO)
1392:                            sequenceMetaDataByPackageSequence.put(seqmds[j]
1393:                                    .getFullyQualifiedName(), seqmds[j]);
1394:                        }
1395:                    }
1396:                }
1397:            }
1398:
1399:            /**
1400:             * Convenience method to register all table generators found in the passed file.
1401:             * @param filemd MetaData for the file
1402:             */
1403:            protected void registerTableGeneratorsForFile(FileMetaData filemd) {
1404:                // Register all table generators for the packages in this file
1405:                for (int i = 0; i < filemd.getNoOfPackages(); i++) {
1406:                    PackageMetaData pmd = filemd.getPackage(i);
1407:                    TableGeneratorMetaData[] tgmds = pmd.getTableGenerators();
1408:                    if (tgmds != null) {
1409:                        for (int j = 0; j < tgmds.length; j++) {
1410:                            // Register using its fully qualified name (JDO)
1411:                            tableGeneratorMetaDataByPackageSequence.put(
1412:                                    tgmds[j].getFullyQualifiedName(), tgmds[j]);
1413:                        }
1414:                    }
1415:                }
1416:            }
1417:
1418:            /**
1419:             * Convenience method to register all table generators found in the passed file.
1420:             * @param filemd MetaData for the file
1421:             */
1422:            protected void registerQueryResultMetaDataForFile(
1423:                    FileMetaData filemd) {
1424:                // Register all query result mappings for the file
1425:                QueryResultMetaData[] fqrmds = filemd.getQueryResultMetaData();
1426:                if (fqrmds != null) {
1427:                    for (int i = 0; i < fqrmds.length; i++) {
1428:                        queryResultMetaDataByName.put(fqrmds[i].getName(),
1429:                                fqrmds[i]);
1430:                    }
1431:                }
1432:
1433:                // Register all query result mappings for the classes in the file
1434:                for (int i = 0; i < filemd.getNoOfPackages(); i++) {
1435:                    PackageMetaData pmd = filemd.getPackage(i);
1436:                    for (int j = 0; j < pmd.getNoOfClasses(); j++) {
1437:                        AbstractClassMetaData cmd = pmd.getClass(j);
1438:                        QueryResultMetaData[] qrmds = cmd
1439:                                .getQueryResultMetaData();
1440:                        if (qrmds != null) {
1441:                            for (int k = 0; k < qrmds.length; k++) {
1442:                                queryResultMetaDataByName.put(qrmds[k]
1443:                                        .getName(), qrmds[k]);
1444:                            }
1445:                        }
1446:                    }
1447:                }
1448:            }
1449:
1450:            /**
1451:             * Convenience method to register all queries found in the passed file.
1452:             * @param filemd MetaData for the file
1453:             */
1454:            protected void registerQueriesForFile(FileMetaData filemd) {
1455:                // Register all queries for this file
1456:                // Store queries against "queryname"
1457:                QueryMetaData[] queries = filemd.getQueries();
1458:                if (queries != null) {
1459:                    for (int i = 0; i < queries.length; i++) {
1460:                        String scope = queries[i].getScope();
1461:                        String key = queries[i].getName();
1462:                        if (scope != null) {
1463:                            key = scope + "_" + key;
1464:                        }
1465:                        queryMetaDataByName.put(key, queries[i]);
1466:                    }
1467:                }
1468:
1469:                for (int i = 0; i < filemd.getNoOfPackages(); i++) {
1470:                    PackageMetaData pmd = filemd.getPackage(i);
1471:
1472:                    // Register all classes (and their queries) into the respective lookup maps
1473:                    for (int j = 0; j < pmd.getNoOfClasses(); j++) {
1474:                        // Store queries against "classname_queryname"
1475:                        ClassMetaData cmd = pmd.getClass(j);
1476:                        QueryMetaData[] classQueries = cmd.getQueries();
1477:                        if (classQueries != null) {
1478:                            for (int k = 0; k < classQueries.length; k++) {
1479:                                String scope = classQueries[k].getScope();
1480:                                String key = classQueries[k].getName();
1481:                                if (scope != null) {
1482:                                    key = scope + "_" + key;
1483:                                }
1484:                                queryMetaDataByName.put(key, classQueries[k]);
1485:                            }
1486:                        }
1487:                    }
1488:
1489:                    // Register all interfaces (and their queries) into the respective lookup maps
1490:                    for (int j = 0; j < pmd.getNoOfInterfaces(); j++) {
1491:                        // Store queries against "classname_queryname"
1492:                        InterfaceMetaData intfmd = pmd.getInterface(j);
1493:                        QueryMetaData[] interfaceQueries = intfmd.getQueries();
1494:                        if (interfaceQueries != null) {
1495:                            for (int k = 0; k < interfaceQueries.length; k++) {
1496:                                String scope = interfaceQueries[k].getScope();
1497:                                String key = interfaceQueries[k].getName();
1498:                                if (scope != null) {
1499:                                    key = scope + "_" + key;
1500:                                }
1501:                                queryMetaDataByName.put(key,
1502:                                        interfaceQueries[k]);
1503:                            }
1504:                        }
1505:                    }
1506:                }
1507:            }
1508:
1509:            /**
1510:             * Convenience method to register all FetchPlans found in the passed file.
1511:             * @param filemd MetaData for the file
1512:             */
1513:            protected void registerFetchPlansForFile(FileMetaData filemd) {
1514:                // Register all queries for this file
1515:                // Store queries against "queryname"
1516:                FetchPlanMetaData[] fetchPlans = filemd.getFetchPlans();
1517:                if (fetchPlans != null) {
1518:                    for (int i = 0; i < fetchPlans.length; i++) {
1519:                        fetchPlanMetaDataByName.put(fetchPlans[i].getName(),
1520:                                fetchPlans[i]);
1521:                    }
1522:                }
1523:            }
1524:
1525:            /**
1526:             * Convenience method to populate all classes/interfaces in a Meta-Data file.
1527:             * @param filemd The MetaData file
1528:             * @param clr Class Loader to use in population
1529:             * @param primary the primary ClassLoader to use (or null)
1530:             */
1531:            protected void populateFileMetaData(FileMetaData filemd,
1532:                    ClassLoaderResolver clr, ClassLoader primary) {
1533:                for (int i = 0; i < filemd.getNoOfPackages(); i++) {
1534:                    PackageMetaData pmd = filemd.getPackage(i);
1535:                    for (int j = 0; j < pmd.getNoOfClasses(); j++) {
1536:                        AbstractClassMetaData cmd = pmd.getClass(j);
1537:                        if (!cmd.isPopulated() && !cmd.isInitialised()) {
1538:                            cmd.populate(clr, primary);
1539:                        }
1540:                    }
1541:                    for (int j = 0; j < pmd.getNoOfInterfaces(); j++) {
1542:                        AbstractClassMetaData cmd = pmd.getInterface(j);
1543:                        if (!cmd.isPopulated() && !cmd.isInitialised()) {
1544:                            cmd.populate(clr, primary);
1545:                        }
1546:                    }
1547:                }
1548:            }
1549:
1550:            /**
1551:             * Initialise all classes/interfaces in a Meta-Data file.
1552:             * @param filemd the FileMetaData
1553:             * @param clr ClassLoader resolver to use
1554:             * @param primary the primary ClassLoader to use (or null)
1555:             */
1556:            protected void initialiseFileMetaData(FileMetaData filemd,
1557:                    ClassLoaderResolver clr, ClassLoader primary) {
1558:                for (int i = 0; i < filemd.getNoOfPackages(); i++) {
1559:                    PackageMetaData pmd = filemd.getPackage(i);
1560:                    for (int j = 0; j < pmd.getNoOfClasses(); j++) {
1561:                        ClassMetaData cmd = pmd.getClass(j);
1562:                        try {
1563:                            initialiseClassMetaData(cmd, clr.classForName(cmd
1564:                                    .getFullClassName(), primary), clr);
1565:                        } catch (JPOXException jpex) {
1566:                            throw jpex;
1567:                        } catch (RuntimeException re) {
1568:                            // Do nothing
1569:                        }
1570:                    }
1571:
1572:                    for (int j = 0; j < pmd.getNoOfInterfaces(); j++) {
1573:                        InterfaceMetaData imd = pmd.getInterface(j);
1574:                        try {
1575:                            initialiseInterfaceMetaData(imd, clr, primary);
1576:                        } catch (JPOXException jpex) {
1577:                            throw jpex;
1578:                        } catch (RuntimeException re) {
1579:                            // Do nothing
1580:                        }
1581:                    }
1582:                }
1583:            }
1584:
1585:            /**
1586:             * Utility to initialise the MetaData for a class, using the specified
1587:             * class. This assigns defaults to tags that haven't been assigned.
1588:             * If the class that is being used to populate the MetaData is not
1589:             * enhanced, this will throw a JPOXUserException informing them of this. 
1590:             * @param cmd The classes metadata
1591:             * @param cls The class to use as a basis for initialisation
1592:             * @param clr ClassLoader resolver to use
1593:             * @throws JPOXUserException if the class is not enhanced
1594:             */
1595:            protected void initialiseClassMetaData(ClassMetaData cmd,
1596:                    Class cls, ClassLoaderResolver clr) {
1597:                synchronized (cmd) {
1598:                    if (!enhancing
1599:                            && cmd.getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE
1600:                            && !getOMFContext().getApiAdapter().isPersistable(
1601:                                    cls)) {
1602:                        throw new JPOXUserException(LOCALISER.msg("044059", cls
1603:                                .getName()));
1604:                    }
1605:                    if (!cmd.isPopulated() && !cmd.isInitialised()) {
1606:                        cmd.populate(clr, cls.getClassLoader());
1607:                    }
1608:                    if (!cmd.isInitialised()) {
1609:                        cmd.initialise();
1610:                    }
1611:                }
1612:            }
1613:
1614:            /**
1615:             * Utility to initialise the MetaData for a interface, using the specified
1616:             * class. This assigns defaults to tags that haven't been assigned.
1617:             * If the class that is being used to populate the MetaData is not
1618:             * enhanced, this will throw a JPOXUserException informing them of this. 
1619:             * @param imd The interface metadata
1620:             * @param clr The loader of the interface
1621:             * @param primary the primary ClassLoader to use (or null)
1622:             */
1623:            protected void initialiseInterfaceMetaData(InterfaceMetaData imd,
1624:                    ClassLoaderResolver clr, ClassLoader primary) {
1625:                synchronized (imd) {
1626:                    if (!imd.isPopulated() && !imd.isInitialised()) {
1627:                        imd.populate(clr, primary);
1628:                    }
1629:                    if (!imd.isInitialised()) {
1630:                        imd.initialise();
1631:                    }
1632:                }
1633:            }
1634:
1635:            /**
1636:             * Method to load the annotations for the specified class and return the FileMetaData containing
1637:             * the class. The FileMetaData, PackageMetaData will be dummy records.
1638:             * @param cls The class
1639:             * @param clr ClassLoader resolver
1640:             * @param register Whether to register the data
1641:             * @param populate Whether to populate the data
1642:             * @return The FileMetaData
1643:             */
1644:            protected FileMetaData loadAnnotationsForClass(Class cls,
1645:                    ClassLoaderResolver clr, boolean register, boolean populate) {
1646:                if (annotationManager != null) {
1647:                    if (isClassWithoutPersistenceInfo(cls.getName())) {
1648:                        return null;
1649:                    }
1650:
1651:                    String clsPackageName = ClassUtils
1652:                            .getPackageNameForClass(cls);
1653:                    if (clsPackageName == null) {
1654:                        // Unknown type with no package, so perhaps so multiple array (int[][] or something)
1655:                        return null;
1656:                    }
1657:
1658:                    // Check for annotations (use dummy file/package so we have a place for it)
1659:                    FileMetaData filemd = new FileMetaData(null, this , null,
1660:                            null);
1661:                    filemd.setType(FileMetaData.ANNOTATIONS);
1662:                    PackageMetaData pmd = new PackageMetaData(filemd,
1663:                            clsPackageName, null, null);
1664:                    filemd.addPackage(pmd);
1665:                    AbstractClassMetaData cmd = annotationManager
1666:                            .getMetaDataForClass(cls, pmd, clr);
1667:                    if (cmd != null) {
1668:                        if (register) {
1669:                            // register before populating to avoid recursive loops when loading referenced classes
1670:                            registerFile("annotations:" + cls.getName(),
1671:                                    filemd, clr);
1672:
1673:                            if (populate) {
1674:                                // Populate all classes in this file we've just parsed (i.e only 1!)
1675:                                populateFileMetaData(filemd, clr, cls
1676:                                        .getClassLoader());
1677:                            }
1678:                        }
1679:                        return filemd;
1680:                    }
1681:                }
1682:                return null;
1683:            }
1684:
1685:            // ------------------------------ Utilities --------------------------------
1686:
1687:            /**
1688:             * Utility to return all ClassMetaData that is referenced from the supplier
1689:             * class.
1690:             * @param cmd The origin class's MetaData.
1691:             * @param dba_vendor_id The Vendor id of the database adapter in use.
1692:             *                      (Used in handling "views" support)
1693:             * @param clr ClassLoaderResolver resolver for loading any classes.
1694:             * @return List of ClassMetaData referenced by the origin
1695:             */
1696:            public List getReferencedClassMetaData(AbstractClassMetaData cmd,
1697:                    String dba_vendor_id, ClassLoaderResolver clr) {
1698:                if (cmd == null) {
1699:                    return null;
1700:                }
1701:
1702:                List orderedCMDs = new ArrayList();
1703:                Set referencedCMDs = new HashSet();
1704:
1705:                // Use the ClassMetaData to tell us about its classes
1706:                cmd.getReferencedClassMetaData(orderedCMDs, referencedCMDs,
1707:                        dba_vendor_id, clr);
1708:
1709:                return orderedCMDs;
1710:            }
1711:
1712:            /**
1713:             * Register to persistent class load
1714:             */
1715:            private class MetaDataRegisterClassListener implements 
1716:                    RegisterClassListener {
1717:                public void registerClass(RegisterClassEvent arg0) {
1718:                    // register the class / interface in metadata
1719:                    getMetaDataForClassInternal(arg0.getRegisteredClass(),
1720:                            omfContext.getClassLoaderResolver(arg0
1721:                                    .getRegisteredClass().getClassLoader()));
1722:                }
1723:            }
1724:
1725:            /**
1726:             * Get the event listeners
1727:             * @return the event listeners
1728:             */
1729:            public List getListeners() {
1730:                return listeners;
1731:            }
1732:
1733:            /**
1734:             * Method to set that the Manager is enhancing classes.
1735:             * This implies using slightly weaker checks during read/populate/initialise of MetaData.
1736:             */
1737:            public void setEnhancing() {
1738:                this .enhancing = true;
1739:            }
1740:
1741:            /**
1742:             * Method to set that the Manager is not enhancing classes.
1743:             * This implies reverting to the normal checks during read/populate/initialise of MetaData.
1744:             */
1745:            public void unsetEnhancing() {
1746:                this .enhancing = false;
1747:            }
1748:
1749:            /**
1750:             * Accessor for a factory for MetaData objects.
1751:             * @return The factory of objects
1752:             */
1753:            public MetaDataFactory getMetaDataFactory() {
1754:                if (metaDataFactory == null) {
1755:                    metaDataFactory = new DefaultMetaDataFactory();
1756:                }
1757:                return metaDataFactory;
1758:            }
1759:
1760:            /**
1761:             * Method to set the Factory for MetaData objects.
1762:             * This is used to create Class, Field, Property, Interface objects.
1763:             * @param factory The factory
1764:             */
1765:            public void setMetaDataFactory(MetaDataFactory factory) {
1766:                this.metaDataFactory = factory;
1767:            }
1768:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.