Source Code Cross Referenced for StoreManager.java in  » Database-ORM » JPOX » org » jpox » store » 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.store 
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:        2007 Xuan Baldauf - Contrib of notifyMainMemoryCopyIsInvalid(), findObject() (needed by DB4O plugin).
0018:            ...
0019:         **********************************************************************/package org.jpox.store;
0020:
0021:        import java.io.PrintStream;
0022:        import java.io.Writer;
0023:        import java.sql.Timestamp;
0024:        import java.util.ArrayList;
0025:        import java.util.Collection;
0026:        import java.util.Date;
0027:        import java.util.HashSet;
0028:        import java.util.Iterator;
0029:        import java.util.List;
0030:
0031:        import org.jpox.ClassLoaderResolver;
0032:        import org.jpox.OMFContext;
0033:        import org.jpox.ObjectManager;
0034:        import org.jpox.ObjectManagerFactoryImpl;
0035:        import org.jpox.StateManager;
0036:        import org.jpox.api.ApiAdapter;
0037:        import org.jpox.exceptions.ClassNotResolvedException;
0038:        import org.jpox.exceptions.JPOXDataStoreException;
0039:        import org.jpox.exceptions.JPOXException;
0040:        import org.jpox.exceptions.JPOXObjectNotFoundException;
0041:        import org.jpox.exceptions.JPOXOptimisticException;
0042:        import org.jpox.exceptions.JPOXUserException;
0043:        import org.jpox.identity.OID;
0044:        import org.jpox.identity.OIDFactory;
0045:        import org.jpox.management.ManagementServer;
0046:        import org.jpox.management.runtime.StoreManagerRuntime;
0047:        import org.jpox.metadata.AbstractClassMetaData;
0048:        import org.jpox.metadata.AbstractMemberMetaData;
0049:        import org.jpox.metadata.IdentityStrategy;
0050:        import org.jpox.metadata.IdentityType;
0051:        import org.jpox.metadata.InheritanceStrategy;
0052:        import org.jpox.metadata.MetaDataManager;
0053:        import org.jpox.metadata.SequenceMetaData;
0054:        import org.jpox.metadata.VersionMetaData;
0055:        import org.jpox.metadata.VersionStrategy;
0056:        import org.jpox.store.exceptions.DatastoreInitialisationException;
0057:        import org.jpox.store.exceptions.NoTableManagedException;
0058:        import org.jpox.store.poid.PoidManager;
0059:        import org.jpox.store.scostore.Store;
0060:        import org.jpox.util.ClassUtils;
0061:        import org.jpox.util.JPOXLogger;
0062:        import org.jpox.util.Localiser;
0063:        import org.jpox.util.MacroString;
0064:        import org.jpox.util.StringUtils;
0065:
0066:        /**
0067:         * An abstract representation of a Store Manager.
0068:         * Manages the persistence of objects to the store.
0069:         * Will be implemented for the type of datastore (RDBMS, ODBMS, OLAP) in question. 
0070:         * The store manager's responsibilities include:
0071:         * <ul>
0072:         * <li>Creating and/or validating datastore tables according to the persistent classes being 
0073:         * accessed by the application.</li>
0074:         * <li>Serving as the primary intermediary between StateManagers and the database.</li>
0075:         * <li>Serving as the base Extent and Query factory.</li>
0076:         * </ul>
0077:         * <p>
0078:         * A store manager's knowledge of its contents is typically not complete. It knows about
0079:         * the classes that it has encountered in its lifetime. The PersistenceManager can make the
0080:         * StoreManager aware of a class, and can check if the StoreManager knows about a particular class.
0081:         * The Auto-Start mechanism provides a way of inheriting knowledge from the last time the store
0082:         * was used.
0083:         *
0084:         * @version $Revision: 1.180 $
0085:         */
0086:        public abstract class StoreManager {
0087:            /** Localiser for messages. */
0088:            protected static final Localiser LOCALISER = Localiser
0089:                    .getInstance("org.jpox.store.Localisation");
0090:
0091:            /** Key for this StoreManager e.g "rdbms", "db4o" */
0092:            protected final String storeManagerKey;
0093:
0094:            /** Adapter for the datastore being used. */
0095:            protected DatastoreAdapter dba;
0096:
0097:            /** Whether this datastore is read only. */
0098:            protected final boolean readOnlyDatastore;
0099:
0100:            /** What should happen if read-only and an update is invoked. */
0101:            protected final String readOnlyDatastoreAction;
0102:
0103:            /** Whether this datastore is fixed (no mods to datastore classes allowed). */
0104:            protected final boolean fixedDatastore;
0105:
0106:            /** Auto-Start mechanism to use. */
0107:            protected AutoStartMechanism starter = null;
0108:
0109:            /** Whether the AutoStart mechanism is initialised */
0110:            protected boolean starterInitialised = false;
0111:
0112:            /** ObjectManagerFactory context. */
0113:            protected final OMFContext omfContext;
0114:
0115:            /** Manager for identity generation. */
0116:            protected final PoidManager poidManager;
0117:
0118:            /** Factory for identifiers for this datastore. Really should be on MappedStoreManager. */
0119:            protected IdentifierFactory identifierFactory;
0120:
0121:            /** StoreManager Runtime. Used when providing management of services. */
0122:            protected StoreManagerRuntime storeManagerRuntime;
0123:
0124:            /** Manager for the data definition in the datastore. */
0125:            protected StoreDataManager storeDataMgr = new StoreDataManager();
0126:
0127:            /** Name of the AutoStart mechanism. */
0128:            protected String autoStartMechanism = null;
0129:
0130:            /**
0131:             * Constructor for a new StoreManager. Stores the basic information required for the datastore management.
0132:             * @param key Key for this StoreManager
0133:             * @param clr the ClassLoaderResolver
0134:             * @param omf The corresponding ObjectManagerFactory.
0135:             * @see StoreManagerFactory
0136:             */
0137:            protected StoreManager(String key, ClassLoaderResolver clr,
0138:                    ObjectManagerFactoryImpl omf) {
0139:                this .storeManagerKey = key;
0140:                this .omfContext = omf.getOMFContext();
0141:                this .readOnlyDatastore = omf.getReadOnlyDatastore();
0142:                this .readOnlyDatastoreAction = omf.getReadOnlyDatastoreAction();
0143:                this .fixedDatastore = omf.getFixedDatastore();
0144:
0145:                // Register this StoreManager with the OMFContext
0146:                omfContext.setStoreManager(this );
0147:
0148:                this .poidManager = new PoidManager();
0149:
0150:                if (omfContext.getManagement() != null) {
0151:                    // register MBean in MbeanServer
0152:                    ManagementServer mgntServer = omfContext.getManagement()
0153:                            .getManagementServer();
0154:                    this .storeManagerRuntime = new StoreManagerRuntime();
0155:                    String mbeanName = omfContext.getDomainName()
0156:                            + ":InstanceName="
0157:                            + omfContext.getInstanceName()
0158:                            + ",Type="
0159:                            + ClassUtils
0160:                                    .getClassNameForClass(storeManagerRuntime
0161:                                            .getClass())
0162:                            + ",Name=StoreManagerRuntime";
0163:                    mgntServer.registerMBean(this .storeManagerRuntime,
0164:                            mbeanName);
0165:                }
0166:            }
0167:
0168:            /**
0169:             * Release of resources
0170:             */
0171:            public void close() {
0172:                poidManager.clear();
0173:                storeDataMgr.clear();
0174:                starterInitialised = false;
0175:                starter = null;
0176:                dba = null;
0177:            }
0178:
0179:            /**
0180:             * Method to return a datastore sequence for this datastore matching the passed sequence MetaData.
0181:             * @param om The Object Manager
0182:             * @param seqmd SequenceMetaData
0183:             * @return The Sequence
0184:             */
0185:            public abstract JPOXSequence getJPOXSequence(ObjectManager om,
0186:                    SequenceMetaData seqmd);
0187:
0188:            /**
0189:             * Method to return a JPOX connection for the ObjectManager.
0190:             * @param om ObjectManager
0191:             * @return The JPOX Connection
0192:             */
0193:            public abstract JPOXConnection getJPOXConnection(ObjectManager om);
0194:
0195:            /**
0196:             * Accessor for the POIDManager for obtaining sequences.
0197:             * @return The POID manager for this datastore
0198:             */
0199:            public PoidManager getPoidManager() {
0200:                return poidManager;
0201:            }
0202:
0203:            /**
0204:             * Accessor for the API adapter.
0205:             * @return API adapter
0206:             */
0207:            public ApiAdapter getApiAdapter() {
0208:                return omfContext.getApiAdapter();
0209:            }
0210:
0211:            /**
0212:             * Accessor for the key for this store manager.
0213:             * @return StoreManager key
0214:             */
0215:            public String getStoreManagerKey() {
0216:                return storeManagerKey;
0217:            }
0218:
0219:            // -------------------------------- Management of Classes --------------------------------
0220:
0221:            /**
0222:             * Method to register some data with the store.
0223:             * This will also register the data with the starter process.
0224:             * @param data The StoreData to add
0225:             */
0226:            protected void registerStoreData(StoreData data) {
0227:                storeDataMgr.registerStoreData(data);
0228:
0229:                // Keep the AutoStarter in step with our managed classes/fields
0230:                if (starter != null && starterInitialised) {
0231:                    starter.addClass(data);
0232:                }
0233:            }
0234:
0235:            /**
0236:             * Method to deregister all existing store data so that we are managing nothing.
0237:             */
0238:            protected void deregisterAllStoreData() {
0239:                storeDataMgr.clear();
0240:                starterInitialised = false;
0241:
0242:                // Keep the AutoStarter in step with our managed classes/fields
0243:                clearAutoStarter();
0244:            }
0245:
0246:            /**
0247:             * Method to output the datastore information to the specified PrintStream.
0248:             * @param ps PrintStream
0249:             * @throws Exception If an error occurs obtaining the datastore info
0250:             */
0251:            public abstract void outputDatastoreInformation(PrintStream ps)
0252:                    throws Exception;
0253:
0254:            /**
0255:             * Method to output the schema information to the specified PrintStream.
0256:             * @param ps PrintStream
0257:             * @throws Exception If an error occurs obtaining the schema info
0258:             */
0259:            public abstract void outputSchemaInformation(PrintStream ps)
0260:                    throws Exception;
0261:
0262:            // -------------------------------- Auto Starter ------------------------------------
0263:
0264:            /**
0265:             * Method to initialise the auto-start mechanism, loading up the classes
0266:             * from its store into memory so that we start from where we got to last time.
0267:             * @param mechanism Auto-Start mechanism
0268:             * @param mode Mode of operation
0269:             * @param clr The ClassLoaderResolver
0270:             * @throws DatastoreInitialisationException
0271:             */
0272:            protected void initialiseAutoStart(String mechanism, String mode,
0273:                    ClassLoaderResolver clr)
0274:                    throws DatastoreInitialisationException {
0275:                if (starterInitialised) {
0276:                    return;
0277:                }
0278:
0279:                autoStartMechanism = mechanism;
0280:
0281:                String autoStarterClassName = getOMFContext()
0282:                        .getPluginManager().getAttributeValueForExtension(
0283:                                "org.jpox.autostart", "name", mechanism,
0284:                                "class-name");
0285:                if (autoStarterClassName != null) {
0286:                    Class[] argsClass = new Class[] {
0287:                            org.jpox.store.StoreManager.class,
0288:                            org.jpox.ClassLoaderResolver.class };
0289:                    Object[] args = new Object[] { this , clr };
0290:                    try {
0291:                        starter = (AutoStartMechanism) getOMFContext()
0292:                                .getPluginManager().createExecutableExtension(
0293:                                        "org.jpox.autostart", "name",
0294:                                        mechanism, "class-name", argsClass,
0295:                                        args);
0296:                    } catch (Exception e) {
0297:                        JPOXLogger.PERSISTENCE.error(StringUtils
0298:                                .getStringFromStackTrace(e));
0299:                    }
0300:                    starter.setMode(mode);
0301:                }
0302:                if (starter == null) {
0303:                    starterInitialised = true;
0304:                    return;
0305:                }
0306:
0307:                boolean illegalState = false;
0308:                try {
0309:                    if (!starter.isOpen()) {
0310:                        starter.open();
0311:                    }
0312:                    Collection existingData = starter.getAllClassData();
0313:                    if (existingData != null && existingData.size() > 0) {
0314:                        List classesNeedingAdding = new ArrayList();
0315:                        Iterator existingDataIter = existingData.iterator();
0316:                        while (existingDataIter.hasNext()) {
0317:                            StoreData data = (StoreData) existingDataIter
0318:                                    .next();
0319:                            if (data.isFCO()) {
0320:                                // Catch classes that don't exist (e.g in use by a different app)
0321:                                Class classFound = null;
0322:                                try {
0323:                                    classFound = clr.classForName(data
0324:                                            .getName());
0325:                                } catch (ClassNotResolvedException cnre) {
0326:                                    if (data.getInterfaceName() != null) {
0327:                                        try {
0328:                                            getOMFContext()
0329:                                                    .getImplementationCreator()
0330:                                                    .newInstance(
0331:                                                            clr
0332:                                                                    .classForName(data
0333:                                                                            .getInterfaceName()),
0334:                                                            getMetaDataManager(),
0335:                                                            clr);
0336:                                            classFound = clr.classForName(data
0337:                                                    .getName());
0338:                                        } catch (ClassNotResolvedException cnre2) {
0339:                                            // Do nothing
0340:                                        }
0341:                                    }
0342:                                    // Thrown if class not found
0343:                                }
0344:
0345:                                if (classFound != null) {
0346:                                    JPOXLogger.PERSISTENCE.info(LOCALISER.msg(
0347:                                            "032003", data.getName()));
0348:                                    classesNeedingAdding.add(data.getName());
0349:                                    if (data.getMetaData() == null) {
0350:                                        // StoreData doesnt have its metadata set yet so load it
0351:                                        // This ensures that the MetaDataManager always knows about these classes
0352:                                        AbstractClassMetaData acmd = getMetaDataManager()
0353:                                                .getMetaDataForClass(
0354:                                                        classFound, clr);
0355:                                        if (acmd != null) {
0356:                                            data.setMetaData(acmd);
0357:                                        } else {
0358:                                            String msg = LOCALISER.msg(
0359:                                                    "034004", data.getName());
0360:                                            if (starter
0361:                                                    .getMode()
0362:                                                    .equals(
0363:                                                            AutoStartMechanism.MODE_CHECKED)) {
0364:                                                JPOXLogger.PERSISTENCE
0365:                                                        .error(msg);
0366:                                                throw new DatastoreInitialisationException(
0367:                                                        msg);
0368:                                            } else if (starter
0369:                                                    .getMode()
0370:                                                    .equals(
0371:                                                            AutoStartMechanism.MODE_IGNORED)) {
0372:                                                JPOXLogger.PERSISTENCE
0373:                                                        .warn(msg);
0374:                                            } else if (starter
0375:                                                    .getMode()
0376:                                                    .equals(
0377:                                                            AutoStartMechanism.MODE_QUIET)) {
0378:                                                JPOXLogger.PERSISTENCE
0379:                                                        .warn(msg);
0380:                                                JPOXLogger.PERSISTENCE
0381:                                                        .warn(LOCALISER.msg(
0382:                                                                "034001",
0383:                                                                data.getName()));
0384:                                                starter.deleteClass(data
0385:                                                        .getName());
0386:                                            }
0387:                                        }
0388:                                    }
0389:                                } else {
0390:                                    String msg = LOCALISER.msg("034000", data
0391:                                            .getName());
0392:                                    if (starter.getMode().equals(
0393:                                            AutoStartMechanism.MODE_CHECKED)) {
0394:                                        JPOXLogger.PERSISTENCE.error(msg);
0395:                                        throw new DatastoreInitialisationException(
0396:                                                msg);
0397:                                    } else if (starter.getMode().equals(
0398:                                            AutoStartMechanism.MODE_IGNORED)) {
0399:                                        JPOXLogger.PERSISTENCE.warn(msg);
0400:                                    } else if (starter.getMode().equals(
0401:                                            AutoStartMechanism.MODE_QUIET)) {
0402:                                        JPOXLogger.PERSISTENCE.warn(msg);
0403:                                        JPOXLogger.PERSISTENCE.warn(LOCALISER
0404:                                                .msg("034001", data.getName()));
0405:                                        starter.deleteClass(data.getName());
0406:                                    }
0407:                                }
0408:                            }
0409:                        }
0410:                        String[] classesToLoad = new String[classesNeedingAdding
0411:                                .size()];
0412:                        Iterator classesNeedingAddingIter = classesNeedingAdding
0413:                                .iterator();
0414:                        int n = 0;
0415:                        while (classesNeedingAddingIter.hasNext()) {
0416:                            classesToLoad[n++] = (String) classesNeedingAddingIter
0417:                                    .next();
0418:                        }
0419:
0420:                        // Load the classes
0421:                        try {
0422:                            addClasses(classesToLoad, clr);
0423:                        } catch (Exception e) {
0424:                            // Exception while adding so some of the (referenced) classes dont exist
0425:                            JPOXLogger.PERSISTENCE.warn(LOCALISER.msg("034002",
0426:                                    e));
0427:                            //if an exception happens while loading AutoStart data, them we disable it, since
0428:                            //it was unable to load the data from AutoStart. The memory state of AutoStart does
0429:                            //not represent the database, and if we don't disable it, we could
0430:                            //think that the autostart store is empty, and we would try to insert new entries in
0431:                            //the autostart store that are already in there
0432:                            illegalState = true;
0433:
0434:                            // TODO Go back and add classes one-by-one to eliminate the class(es) with the problem
0435:                        }
0436:                    }
0437:                } finally {
0438:                    if (starter.isOpen()) {
0439:                        starter.close();
0440:                    }
0441:                    if (illegalState) {
0442:                        JPOXLogger.PERSISTENCE.warn(LOCALISER.msg("034003"));
0443:                        starter = null;
0444:                    }
0445:                }
0446:
0447:                starterInitialised = true;
0448:            }
0449:
0450:            /**
0451:             * Method to clear the Auto-Starter status.
0452:             */
0453:            protected void clearAutoStarter() {
0454:                // AutoStarter - Delete all supported classes
0455:                if (starter != null) {
0456:                    try {
0457:                        if (!starter.isOpen()) {
0458:                            starter.open();
0459:                        }
0460:                        starter.deleteAllClasses();
0461:                    } finally {
0462:                        if (starter.isOpen()) {
0463:                            starter.close();
0464:                        }
0465:                    }
0466:                }
0467:            }
0468:
0469:            /**
0470:             * Accessor for the {@link AutoStartMechanism}
0471:             * @return may return null if auto start mechanism is not initialized
0472:             */
0473:            public AutoStartMechanism getAutoStartMechanism() {
0474:                return starter;
0475:            }
0476:
0477:            // ------------------------------- Class Management -----------------------------------
0478:
0479:            /**
0480:             * Accessor for whether the specified class is managed currently
0481:             * @param className The name of the class
0482:             * @return Whether it is managed
0483:             */
0484:            public boolean managesClass(String className) {
0485:                return storeDataMgr.managesClass(className);
0486:            }
0487:
0488:            /**
0489:             * Method to add a class to the managed list for this datastore manager.
0490:             * @param className Name of the class
0491:             * @param clr The ClassLoaderResolver
0492:             */
0493:            public void addClass(String className, ClassLoaderResolver clr) {
0494:                addClasses(new String[] { className }, clr, null, false);
0495:            }
0496:
0497:            /**
0498:             * Add classes to the persistence model for the datastore.
0499:             * In the case of an RDBMS, this will map these classes to RDBMS tables.
0500:             * In the case of XML, this will map these classes to XML datafiles. 
0501:             * <p>
0502:             * This method is primarily useful for applications that wish to perform all
0503:             * of their datastore initialization up front, rather than wait for the JPOX
0504:             * runtime to do it on-demand.
0505:             * @param classes The class(es) to be added.
0506:             * @param clr The ClassLoaderResolver
0507:             * @param writer Optional writer when you just want the DDL for persisting the specified classes
0508:             * @param completeDdl whether complete DDL will be created when writing DDL to a file, or only for missing elements
0509:             * @exception org.jpox.store.exceptions.DatastoreValidationException
0510:             *      If there is some mismatch between the current datastore contents and
0511:             *      those necessary to enable persistence of the given classes.
0512:             */
0513:            public abstract void addClasses(String[] classes,
0514:                    ClassLoaderResolver clr, Writer writer, boolean completeDdl);
0515:
0516:            /**
0517:             * Add classes to the persistence model for the datastore.
0518:             * In the case of an RDBMS, this will map these classes to RDBMS tables.
0519:             * In the case of XML, this will map these classes to XML datafiles.
0520:             * <p>
0521:             * This method is primarily useful for applications that wish to perform all
0522:             * of their datastore initialization up front, rather than wait for the JPOX
0523:             * runtime to do it on-demand.
0524:             * @param classNames The class(es) to be added.
0525:             * @param clr The ClassLoaderResolver
0526:             * @exception org.jpox.store.exceptions.DatastoreValidationException
0527:             *      If there is some mismatch between the current datastore contents and
0528:             *      those necessary to enable persistence of the given classes.
0529:             */
0530:            public void addClasses(String[] classNames, ClassLoaderResolver clr) {
0531:                addClasses(classNames, clr, null, false);
0532:            }
0533:
0534:            /**
0535:             * Drops all tables in the datastore.
0536:             * This empties the datastore of all datastore objects managed by JPOX.
0537:             * All objects not managed by JPOX are left untouched.
0538:             * @param clr The ClassLoaderResolver
0539:             */
0540:            public abstract void removeAllClasses(ClassLoaderResolver clr);
0541:
0542:            /**
0543:             * Method to return the class(es) that has a table managing the persistence of
0544:             * the fields of the supplied class. For the 3 inheritance strategies, the following
0545:             * occurs :-
0546:             * <UL>
0547:             * <LI>new-table : will return the same ClassMetaData</LI>
0548:             * <LI>subclass-table : will return all subclasses that have a table managing its fields</LI>
0549:             * <LI>superclass-table : will return the next superclass that has a table</LI>
0550:             * </UL> 
0551:             * @param cmd The supplied class.
0552:             * @param clr ClassLoader resolver
0553:             * @return The ClassMetaData's managing the fields of the supplied class
0554:             */
0555:            public AbstractClassMetaData[] getClassesManagingTableForClass(
0556:                    AbstractClassMetaData cmd, ClassLoaderResolver clr) {
0557:                // Null input, so just return null;
0558:                if (cmd == null) {
0559:                    return null;
0560:                }
0561:
0562:                if (cmd.getInheritanceMetaData().getStrategyValue() == InheritanceStrategy.COMPLETE_TABLE
0563:                        || cmd.getInheritanceMetaData().getStrategyValue() == InheritanceStrategy.NEW_TABLE) {
0564:                    // Class manages a table so return the classes metadata.
0565:                    return new AbstractClassMetaData[] { cmd };
0566:                } else if (cmd.getInheritanceMetaData().getStrategyValue() == InheritanceStrategy.SUBCLASS_TABLE) {
0567:                    // Check the subclasses that we have metadata for and make sure they are managed before proceeding
0568:                    String[] subclasses = getMetaDataManager()
0569:                            .getSubclassesForClass(cmd.getFullClassName(), true);
0570:                    if (subclasses != null) {
0571:                        for (int i = 0; i < subclasses.length; i++) {
0572:                            if (!storeDataMgr.managesClass(subclasses[i])) {
0573:                                addClass(subclasses[i], clr);
0574:                            }
0575:                        }
0576:                    }
0577:
0578:                    // Find subclasses who manage the tables winto which our class is persisted
0579:                    HashSet managingClasses = new HashSet();
0580:                    Iterator managedClassesIter = storeDataMgr
0581:                            .getManagedStoreData().iterator();
0582:                    while (managedClassesIter.hasNext()) {
0583:                        StoreData data = (StoreData) managedClassesIter.next();
0584:                        if (data.isFCO()
0585:                                && ((AbstractClassMetaData) data.getMetaData())
0586:                                        .getSuperAbstractClassMetaData() != null
0587:                                && ((AbstractClassMetaData) data.getMetaData())
0588:                                        .getSuperAbstractClassMetaData()
0589:                                        .getFullClassName().equals(
0590:                                                cmd.getFullClassName())) {
0591:                            AbstractClassMetaData[] super Cmds = getClassesManagingTableForClass(
0592:                                    (AbstractClassMetaData) data.getMetaData(),
0593:                                    clr);
0594:                            if (super Cmds != null) {
0595:                                for (int i = 0; i < super Cmds.length; i++) {
0596:                                    managingClasses.add(super Cmds[i]);
0597:                                }
0598:                            }
0599:                        }
0600:                    }
0601:
0602:                    Iterator managingClassesIter = managingClasses.iterator();
0603:                    AbstractClassMetaData managingCmds[] = new AbstractClassMetaData[managingClasses
0604:                            .size()];
0605:                    int i = 0;
0606:                    while (managingClassesIter.hasNext()) {
0607:                        managingCmds[i++] = (AbstractClassMetaData) (managingClassesIter
0608:                                .next());
0609:                    }
0610:                    return managingCmds;
0611:                } else if (cmd.getInheritanceMetaData().getStrategyValue() == InheritanceStrategy.SUPERCLASS_TABLE) {
0612:                    // Fields managed by superclass, so recurse to that
0613:                    return getClassesManagingTableForClass(cmd
0614:                            .getSuperAbstractClassMetaData(), clr);
0615:                }
0616:                return null;
0617:            }
0618:
0619:            /**
0620:             * Convenience method to ensure that the class defined by the passed OID/SingleFIeldIdentity is 
0621:             * managed by the store.
0622:             * @param id OID
0623:             * @param clr ClassLoader resolver
0624:             * @return The class name of the class associated to this identity
0625:             * @throws JPOXUserException if the identity is assigned to the wrong class
0626:             */
0627:            public String manageClassForIdentity(Object id,
0628:                    ClassLoaderResolver clr) {
0629:                String className = null;
0630:
0631:                if (id instanceof  OID) {
0632:                    // Check that the implied class is managed
0633:                    className = ((OID) id).getPcClass();
0634:                    AbstractClassMetaData cmd = getMetaDataManager()
0635:                            .getMetaDataForClass(className, clr);
0636:                    if (cmd.getIdentityType() != IdentityType.DATASTORE) {
0637:                        throw new JPOXUserException(LOCALISER.msg("038001", id,
0638:                                cmd.getFullClassName()));
0639:                    }
0640:
0641:                } else if (getApiAdapter().isSingleFieldIdentity(id)) {
0642:                    className = getApiAdapter()
0643:                            .getTargetClassNameForSingleFieldIdentity(id);
0644:                    AbstractClassMetaData cmd = getMetaDataManager()
0645:                            .getMetaDataForClass(className, clr);
0646:                    if (cmd.getIdentityType() != IdentityType.APPLICATION
0647:                            || !cmd.getObjectidClass().equals(
0648:                                    id.getClass().getName())) {
0649:                        throw new JPOXUserException(LOCALISER.msg("038001", id,
0650:                                cmd.getFullClassName()));
0651:                    }
0652:                } else {
0653:                    throw new JPOXException(
0654:                            "StoreManager.manageClassForIdentity called for id="
0655:                                    + id
0656:                                    + " yet should only be called for datastore-identity/SingleFieldIdentity");
0657:                }
0658:
0659:                // If the class is not yet managed, manage it
0660:                if (!managesClass(className)) {
0661:                    addClass(className, clr);
0662:                }
0663:
0664:                return className;
0665:            }
0666:
0667:            /**
0668:             * Method returning whether the datastore has a "datastore class" equivalent that the StoreManager
0669:             * uses to represent it. For datastores like RDBMS this will return "true" since we have a "table".
0670:             * For object datastores this is typically "false" since the objects are stored in some internal form
0671:             * not visible via its API.
0672:             * @return Whether datastore classes are used by the StoreManager
0673:             */
0674:            public boolean usesDatastoreClass() {
0675:                return false;
0676:            }
0677:
0678:            // ------------------------------ PersistenceManager interface -----------------------------------
0679:
0680:            /**
0681:             * Interface to getting an Extent for a class.
0682:             * @param om The Object Manager
0683:             * @param c  The class requiring the Extent
0684:             * @param subclasses Whether to include subclasses of 'c'
0685:             * @return The Extent.
0686:             */
0687:            public abstract Extent getExtent(ObjectManager om, Class c,
0688:                    boolean subclasses);
0689:
0690:            /**
0691:             * Accessor for whether this query language is supported.
0692:             * @param language The language
0693:             * @return Whether it is supported.
0694:             * @see org.jpox.store.StoreManager#supportsQueryLanguage(java.lang.String)
0695:             */
0696:            public abstract boolean supportsQueryLanguage(String language);
0697:
0698:            /**
0699:             * Returns the class corresponding to the given object identity. 
0700:             * If the object is an OID (datastore-identity), return the PC class specified in the identity.
0701:             * If the object is SingleFieldIdentity, return the PC class specified in the identity
0702:             * If the object is an AppID PK, return the PC class that uses it.
0703:             * If the object is a SCOID, return the SCO class. 
0704:             * If the object is a PersistenceCapable class, return the class. 
0705:             * @param id The identity of some object.
0706:             * @param clr ClassLoader resolver
0707:             * @param om Object Manager
0708:             * @return For datastore identity, return the class of the corresponding
0709:             * object. For application identity, return the class of the corresponding
0710:             * object or null if object does not exist.
0711:             * @exception ClassCastException If the type of ID is not recognized ({@link OID}
0712:             * or {@link SCOID}).
0713:             */
0714:            public String getClassNameForObjectID(Object id,
0715:                    ClassLoaderResolver clr, ObjectManager om) {
0716:                if (id instanceof  SCOID) {
0717:                    // Object is a SCOID
0718:                    return ((SCOID) id).getSCOClass();
0719:                } else if (id instanceof  OID) {
0720:                    // Object is an OID
0721:                    return ((OID) id).getPcClass();
0722:                } else if (getApiAdapter().isSingleFieldIdentity(id)) {
0723:                    // Using SingleFieldIdentity so can assume that object is of the target class
0724:                    return getApiAdapter()
0725:                            .getTargetClassNameForSingleFieldIdentity(id);
0726:                } else {
0727:                    // Application identity with user PK class
0728:                    // Find all of the application identity PK classes of this type
0729:                    Collection c = storeDataMgr.getByPrimaryKeyClass(id
0730:                            .getClass().getName());
0731:                    if (c != null) {
0732:                        Iterator iter = c.iterator();
0733:                        while (iter.hasNext()) {
0734:                            // Just return the class name of the first one using this id - could be any in this tree
0735:                            // TODO Provide a way of finding the precise type - e.g cont.get(object with this id)
0736:                            StoreData store_data = (StoreData) iter.next();
0737:                            return store_data.getName();
0738:                        }
0739:                    }
0740:                    return null;
0741:                }
0742:            }
0743:
0744:            /**
0745:             * Check if the strategy is attributed by the database when the
0746:             * PersistenceCapable object is inserted into the database
0747:             * @param identityStrategy the identityStrategy
0748:             * @param datastoreIdentityField Whether this is for the surrogate datastore identity field
0749:             * @return if the object for the strategy is attributed by the database
0750:             */
0751:            public boolean isStrategyDatastoreAttributed(
0752:                    IdentityStrategy identityStrategy,
0753:                    boolean datastoreIdentityField) {
0754:                if (identityStrategy == null) {
0755:                    return false;
0756:                }
0757:
0758:                /*if (identityStrategy == IdentityStrategy.NATIVE && dba.supportsAutoIncrementFields())
0759:                {
0760:                    // If the user leaves it to us and the DBA supports autoincrement then we use it
0761:                    // which means attributing the id in the datastore.
0762:                    return true;
0763:                }*/
0764:
0765:                // "identity" is processed in the datastore
0766:                if (identityStrategy == IdentityStrategy.IDENTITY) {
0767:                    // TODO "identity" could imply using a SEQUENCE, so we need to allow for this here
0768:                    return true;
0769:                }
0770:
0771:                return false;
0772:            }
0773:
0774:            /**
0775:             * Method to retrieve the value for a strategy for a particular field.
0776:             * @param om The Object Manager
0777:             * @param table The datastore table
0778:             * @param cmd AbstractClassMetaData for the class
0779:             * @param absoluteFieldNumber The field number
0780:             * @return The value
0781:             */
0782:            public abstract Object getStrategyValue(ObjectManager om,
0783:                    DatastoreClass table, AbstractClassMetaData cmd,
0784:                    int absoluteFieldNumber);
0785:
0786:            /**
0787:             * Returns a new, unique ID for an object of the given class.
0788:             * @param om The Object Manager
0789:             * @param className Name of the class of the object.
0790:             * @param pc The persistable object. Used for application-identity
0791:             * @return A new object ID.
0792:             * @throws JPOXUserException if the class has no available table in the datastore
0793:             */
0794:            public Object newObjectID(ObjectManager om, String className,
0795:                    Object pc) {
0796:                AbstractClassMetaData cmd = getMetaDataManager()
0797:                        .getMetaDataForClass(className,
0798:                                om.getClassLoaderResolver());
0799:                if (cmd.getIdentityType() == IdentityType.DATASTORE) {
0800:                    DatastoreClass t = null;
0801:                    if (usesDatastoreClass()) {
0802:                        t = getDatastoreClass(className, om
0803:                                .getClassLoaderResolver());
0804:                        if (t == null
0805:                                && cmd.getInheritanceMetaData()
0806:                                        .getStrategyValue() == InheritanceStrategy.SUBCLASS_TABLE) {
0807:                            throw new JPOXUserException(LOCALISER.msg("032013",
0808:                                    className));
0809:                        }
0810:
0811:                        // Go up to overall superclass to find id for that class.
0812:                        boolean has_super class = true;
0813:                        while (has_super class) {
0814:                            DatastoreClass super t = t.getSuperDatastoreClass();
0815:                            if (super t != null) {
0816:                                t = super t;
0817:                            } else {
0818:                                has_super class = false;
0819:                            }
0820:                        }
0821:                    }
0822:
0823:                    // Populate any strategy value for the "datastore-identity" element
0824:                    Object nextIdentifier = getStrategyValue(om, t, cmd, -1);
0825:                    return OIDFactory.getInstance(om, cmd.getFullClassName(),
0826:                            nextIdentifier);
0827:                } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
0828:                    return getApiAdapter().getNewApplicationIdentityObjectId(
0829:                            pc, cmd); // All values will have been populated before arriving here
0830:                } else {
0831:                    // All "nondurable" cases (views, JPOXSQL) will come through here
0832:                    return new SCOID(className);
0833:                }
0834:            }
0835:
0836:            /**
0837:             * Inserts a persistent object into the database.
0838:             * @param sm The state manager of the object to be inserted.
0839:             * @throws JPOXDataStoreException when an error occurs in the datastore communication
0840:             */
0841:            public abstract void insertObject(StateManager sm);
0842:
0843:            /**
0844:             * Fetches a persistent object from the database.
0845:             * @param sm The state manager of the object to be fetched.
0846:             * @param fieldNumbers The numbers of the fields to be fetched.
0847:             * @throws JPOXObjectNotFoundException if the object doesnt exist
0848:             * @throws JPOXDataStoreException when an error occurs in the datastore communication
0849:             */
0850:            public abstract void fetchObject(StateManager sm,
0851:                    int fieldNumbers[]);
0852:
0853:            /**
0854:             * Updates a persistent object in the datastore.
0855:             * @param sm The state manager of the object to be updated.
0856:             * @param fieldNumbers The numbers of the fields to be updated.
0857:             * @throws JPOXDataStoreException when an error occurs in the datastore communication
0858:             */
0859:            public abstract void updateObject(StateManager sm,
0860:                    int fieldNumbers[]);
0861:
0862:            /**
0863:             * Deletes a persistent object from the datastore.
0864:             * @param sm The state manager of the object to be deleted.
0865:             * @throws JPOXDataStoreException when an error occurs in the datastore communication
0866:             */
0867:            public abstract void deleteObject(StateManager sm);
0868:
0869:            /**
0870:             * Locates this object in the datastore.
0871:             * @param sm The StateManager for the object to be found
0872:             * @throws JPOXObjectNotFoundException if the object doesnt exist
0873:             * @throws JPOXDataStoreException when an error occurs in the datastore communication
0874:             */
0875:            public abstract void locateObject(StateManager sm);
0876:
0877:            /**
0878:             * Method to find a persistable object with the specified id from the datastore, if the StoreManager supports
0879:             * this operation (optional). This allows for datastores that perform the instantiation of objects directly
0880:             * (such as ODBMS). With other types of datastores (e.g RDBMS) this method returns null. If the StoreManager
0881:             * supports this operation yet the object is not found an exception should be thrown.
0882:             * @param om the ObjectManager which will manage the object
0883:             * @param id the id of the object in question.
0884:             * @return a persistable object with a valid object state (for example: hollow) or null, 
0885:             *     indicating that the implementation leaves the instantiation work to JPOX.
0886:             */
0887:            public abstract Object findObject(ObjectManager om, Object id);
0888:
0889:            /**
0890:             * Perform an optimistic version check on the passed object, against the passed version in the datastore.
0891:             * @param sm StateManager of the object to check
0892:             * @param versionDatastore Version of the object in the datastore
0893:             * @param versionMetaData VersionMetaData to use for checking
0894:             * @throws JPOXUserException thrown when an invalid strategy is specified
0895:             * @throws JPOXOptimisticException thrown when the version check fails
0896:             */
0897:            public void performVersionCheck(StateManager sm,
0898:                    Object versionDatastore, VersionMetaData versionMetaData) {
0899:                // Extract the version of the object (that we are updating)
0900:                Object versionObject = sm.getTransactionalVersion(sm
0901:                        .getObject());
0902:                if (versionObject == null) {
0903:                    return;
0904:                }
0905:
0906:                if (versionMetaData == null) {
0907:                    // No version specification so no check needed
0908:                    JPOXLogger.JDO
0909:                            .info(sm.getClassMetaData().getFullClassName()
0910:                                    + " has no version metadata so no check of version is required, since this will not have the version flag in its table");
0911:                    return;
0912:                }
0913:
0914:                boolean valid;
0915:                if (versionMetaData.getVersionStrategy() == VersionStrategy.DATE_TIME) {
0916:                    valid = ((Timestamp) versionObject).getTime() == ((Timestamp) versionDatastore)
0917:                            .getTime();
0918:                } else if (versionMetaData.getVersionStrategy() == VersionStrategy.VERSION_NUMBER) {
0919:                    valid = ((Number) versionObject).longValue() == ((Number) versionDatastore)
0920:                            .longValue();
0921:                } else if (versionMetaData.getVersionStrategy() == VersionStrategy.STATE_IMAGE) {
0922:                    // TODO Support state-image strategy
0923:                    throw new JPOXUserException(LOCALISER.msg("032017", sm
0924:                            .getClassMetaData().getFullClassName(),
0925:                            versionMetaData.getVersionStrategy()));
0926:                } else {
0927:                    throw new JPOXUserException(LOCALISER.msg("032017", sm
0928:                            .getClassMetaData().getFullClassName(),
0929:                            versionMetaData.getVersionStrategy()));
0930:                }
0931:
0932:                if (!valid) {
0933:                    String msg = LOCALISER.msg("032016", StringUtils
0934:                            .toJVMIDString(sm.getObject()), sm
0935:                            .getInternalObjectId(), "" + versionDatastore, ""
0936:                            + versionObject);
0937:                    JPOXLogger.PERSISTENCE.error(msg);
0938:                    throw new JPOXOptimisticException(msg, sm.getObject());
0939:                }
0940:            }
0941:
0942:            /**
0943:             * Utility to return the names of the classes that are known subclasses of the provided
0944:             * class. Actually uses the MetaDataManager for determining what is a subclass
0945:             * since the MetaData is often registered before being needed by the Store.
0946:             * @param className Class for which we search for subclasses.
0947:             * @param includeDescendents Whether to include subclasses of subclasses etc
0948:             * @param clr The ClassLoaderResolver
0949:             * @return Set of classes that are subclasses of the input class.
0950:             */
0951:            public HashSet getSubClassesForClass(String className,
0952:                    boolean includeDescendents, ClassLoaderResolver clr) {
0953:                HashSet subclasses = new HashSet();
0954:
0955:                String[] subclassNames = getMetaDataManager()
0956:                        .getSubclassesForClass(className, includeDescendents);
0957:                if (subclassNames != null) {
0958:                    // Load up the table for any classes that are not yet loaded
0959:                    for (int i = 0; i < subclassNames.length; i++) {
0960:                        if (!storeDataMgr.managesClass(subclassNames[i])) {
0961:                            // We have no knowledge of this class so load it now
0962:                            addClass(subclassNames[i], clr);
0963:                        }
0964:                        subclasses.add(subclassNames[i]);
0965:                    }
0966:                }
0967:
0968:                return subclasses;
0969:            }
0970:
0971:            // ------------------------------- Accessors ------------------------------------
0972:
0973:            /**
0974:             * Accessor for the identifier factory.
0975:             * @return Returns the identifier factory.
0976:             */
0977:            public IdentifierFactory getIdentifierFactory() {
0978:                return identifierFactory;
0979:            }
0980:
0981:            /**
0982:             * Accessor for the context in which this RDBMSManager is running
0983:             * @return Returns the context.
0984:             */
0985:            public OMFContext getOMFContext() {
0986:                return omfContext;
0987:            }
0988:
0989:            /**
0990:             * Gets the MetaDataManager to use for this store.
0991:             * @return Returns the MetaDataManager.
0992:             */
0993:            public MetaDataManager getMetaDataManager() {
0994:                return omfContext.getMetaDataManager();
0995:            }
0996:
0997:            /**
0998:             * Gets the DatastoreAdapter to use for this store.
0999:             * @return Returns the DatastoreAdapter
1000:             */
1001:            public DatastoreAdapter getDatastoreAdapter() {
1002:                return dba;
1003:            }
1004:
1005:            /**
1006:             * Get the date/time of the datastore.
1007:             * @return Date/time of the datastore
1008:             */
1009:            public abstract Date getDatastoreDate();
1010:
1011:            /**
1012:             * Returns the primary datastore container serving as backing for the given class. 
1013:             * If the class is not yet known to the store manager, {@link #addClass}is called
1014:             * to add it. Classes which have inheritance strategy of "new-table" and
1015:             * "superclass-table" will return a table here, whereas "subclass-table" will
1016:             * return null since it doesn't have a table as such.
1017:             * <p>
1018:             * @param className Name of the class whose table is be returned.
1019:             * @param clr The ClassLoaderResolver
1020:             * @return The corresponding class table.
1021:             * @exception NoTableManagedException If the given class has no table managed in the database.
1022:             */
1023:            public DatastoreClass getDatastoreClass(String className,
1024:                    ClassLoaderResolver clr) {
1025:                DatastoreClass ct = null;
1026:                if (className == null) {
1027:                    JPOXLogger.PERSISTENCE.error(LOCALISER.msg("032015"));
1028:                    return null;
1029:                }
1030:
1031:                StoreData sd = storeDataMgr.get(className);
1032:                if (sd != null && sd instanceof  TableStoreData) {
1033:                    ct = (DatastoreClass) ((TableStoreData) sd)
1034:                            .getDatastoreContainerObject();
1035:                    if (ct != null) {
1036:                        // Class known about
1037:                        return ct;
1038:                    }
1039:                }
1040:
1041:                // Class not known so consider adding it to our list of supported classes.
1042:                // Currently we only consider PC classes
1043:                boolean toBeAdded = false;
1044:                if (clr != null) {
1045:                    Class cls = clr.classForName(className);
1046:                    ApiAdapter api = getApiAdapter();
1047:                    if (cls != null && !cls.isInterface()
1048:                            && api.isPersistable(cls)) {
1049:                        toBeAdded = true;
1050:                    }
1051:                } else {
1052:                    toBeAdded = true;
1053:                }
1054:
1055:                boolean classKnown = false;
1056:                if (toBeAdded) {
1057:                    // Add the class to our supported list
1058:                    addClass(className, clr);
1059:
1060:                    // Retry
1061:                    synchronized (storeDataMgr) {
1062:                        sd = storeDataMgr.get(className);
1063:                        if (sd != null && sd instanceof  TableStoreData) {
1064:                            classKnown = true;
1065:                            ct = (DatastoreClass) ((TableStoreData) sd)
1066:                                    .getDatastoreContainerObject();
1067:                        }
1068:                    }
1069:                }
1070:
1071:                // Throw an exception if class still not known and no table
1072:                // Note : "subclass-table" inheritance strategies will return null from this method
1073:                if (!classKnown && ct == null) {
1074:                    throw new NoTableManagedException(className);
1075:                }
1076:
1077:                return ct;
1078:            }
1079:
1080:            /**
1081:             * Returns the JDO table having the given SQL identifier.
1082:             * Returns 'null' if no such table is (yet) known to the store manager.
1083:             * @param name The identifier name of the table.
1084:             * @return The corresponding JDO table, or 'null'
1085:             */
1086:            public synchronized DatastoreClass getDatastoreClass(
1087:                    DatastoreIdentifier name) {
1088:                Iterator iterator = storeDataMgr.getManagedStoreData()
1089:                        .iterator();
1090:                while (iterator.hasNext()) {
1091:                    StoreData sd = (StoreData) iterator.next();
1092:                    if (sd instanceof  TableStoreData) {
1093:                        TableStoreData tsd = (TableStoreData) sd;
1094:                        if (tsd.hasTable()
1095:                                && tsd.getDatastoreIdentifier().equals(name)) {
1096:                            return (DatastoreClass) tsd
1097:                                    .getDatastoreContainerObject();
1098:                        }
1099:                    }
1100:                }
1101:                return null;
1102:            }
1103:
1104:            /**
1105:             * Utility to navigate the inheritance hierarchy to find the base class that defines the primary keys
1106:             * for this tree. This will either go up to the next class in the hierarchy that has a table
1107:             * OR go up to the base class, whichever is first.
1108:             * @param cmd AbstractClassMetaData for this class
1109:             * @param clr The ClassLoaderResolver
1110:             * @return The AbstractClassMetaData for the class defining the primary keys
1111:             */
1112:            public AbstractClassMetaData getClassWithPrimaryKeyForClass(
1113:                    AbstractClassMetaData cmd, ClassLoaderResolver clr) {
1114:                if (cmd == null) {
1115:                    return null;
1116:                }
1117:
1118:                // Base class will have primary key fields
1119:                if (cmd.getSuperAbstractClassMetaData() == null) {
1120:                    return cmd;
1121:                }
1122:                // Class has its own table so has the PK fields already
1123:                else if (getDatastoreClass(cmd.getFullClassName(), clr) != null) {
1124:                    return cmd;
1125:                }
1126:
1127:                return getClassWithPrimaryKeyForClass(cmd
1128:                        .getSuperAbstractClassMetaData(), clr);
1129:            }
1130:
1131:            /**
1132:             * Notifies this store manager that the main memory (RAM, heap) copy of the PC object  of the supplied
1133:             * StateManager may not be regarded as valid anymore.
1134:             * (The most common case is that the state of the PC becomes HOLLOW).
1135:             * This is especially important for object databases employing implicit storing
1136:             * from the main memory to the database (like DB4O).
1137:             * These databases may stop tracking the main memory copy and linking it with its on-disk copy,
1138:             * thus releasing memory.
1139:             * More importantly, these databases then know that the object should be reloaded when it
1140:             * is (maybe even implicitly) accessed again.
1141:             *
1142:             * To be clear: There may be multiple copies of the data of one PC object (from the user perspective),
1143:             * namely a copy in main memory (on the Java heap) and a copy in the database (usually on disk).
1144:             * As there may be multiple copies, some of these copies may be outdated or invalid. In case such
1145:             * a copy is to be accessed, its contents should not be used. Rather than that, the outdated copy should
1146:             * be overwritten by an authorative copy.
1147:             *
1148:             * This method marks the main memory copy of the object (on the Java heap) to be outdated in that sense.
1149:             */
1150:            public void notifyObjectIsOutdated(StateManager sm) {
1151:            }
1152:
1153:            /**
1154:             * Resolves an identifier macro. The public fields <var>clazz </var>,
1155:             * <var>fieldName </var>, and <var>subfieldName </var> of the given macro
1156:             * are taken as inputs, and the public <var>value </var> field is set to the
1157:             * SQL identifier of the corresponding database table or column.
1158:             * @param im The macro to resolve.
1159:             * @param clr The ClassLoaderResolver
1160:             */
1161:            public abstract void resolveIdentifierMacro(
1162:                    MacroString.IdentifierMacro im, ClassLoaderResolver clr);
1163:
1164:            public abstract Store getStore(ClassLoaderResolver clr,
1165:                    AbstractMemberMetaData fmd, Class type);
1166:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.