001: /**********************************************************************
002: Copyright (c) 2006 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015: Contributors:
016: 2006 Andy Jefferson - changed to use constructor and initialiseXXX methods
017: 2007 Xuan Baldauf - added method newStateManagerForHollowPreConstructed(), needed for DB4O plugin
018: 2007 Andy Jefferson - removed all passed in PersistenceCapable
019: ...
020: **********************************************************************/package org.jpox.state;
021:
022: import org.jpox.ClassLoaderResolver;
023: import org.jpox.ObjectManager;
024: import org.jpox.StateManager;
025: import org.jpox.exceptions.ClassNotResolvedException;
026: import org.jpox.exceptions.JPOXUserException;
027: import org.jpox.metadata.AbstractClassMetaData;
028: import org.jpox.store.FieldValues;
029: import org.jpox.util.Localiser;
030:
031: /**
032: * Factory of StateManagers.
033: *
034: * @version $Revision: 1.27 $
035: */
036: public class StateManagerFactory {
037: /** Localiser for messages. */
038: protected static final Localiser LOCALISER = Localiser
039: .getInstance("org.jpox.Localisation");
040:
041: /**
042: * Constructs a state manager to manage a hollow instance having the given object ID.
043: * This constructor is used for creating new instances of existing persistent objects.
044: * @param om the persistence manager controlling this state manager.
045: * @param pcClass the class of the new instance to be created.
046: * @param id the JDO identity of the object.
047: */
048: public static StateManager newStateManagerForHollow(
049: ObjectManager om, Class pcClass, Object id) {
050: Initialization stateManagerInitialization = new Initialization(
051: om, pcClass);
052: StateManager sm = om.getApiAdapter().newStateManager(om,
053: stateManagerInitialization.getClassMetaData());
054: sm.initialiseForHollow(id, null, stateManagerInitialization
055: .getPCClass());
056: return sm;
057: }
058:
059: /**
060: * Constructs a state manager to manage a hollow instance having the given object ID.
061: * The instance is already supplied.
062: * @param om the persistence manager controlling this state manager.
063: * @param id the JDO identity of the object.
064: * @param pc The object that is hollow that we are going to manage
065: */
066: public static StateManager newStateManagerForHollowPreConstructed(
067: ObjectManager om, Object id, Object pc) {
068: Initialization stateManagerInitialization = new Initialization(
069: om, pc.getClass());
070: StateManager sm = om.getApiAdapter().newStateManager(om,
071: stateManagerInitialization.getClassMetaData());
072: sm.initialiseForHollowPreConstructed(id, pc);
073: return sm;
074: }
075:
076: /**
077: * Constructs a state manager to manage a recently populated hollow instance having the
078: * given object ID and the given field values. This constructor is used for
079: * creating new instances of persistent objects obtained e.g. via a Query or backed by a view.
080: * @param om the object manager controlling this state manager.
081: * @param pcClass the class of the new instance to be created.
082: * @param id the JDO identity of the object.
083: * @param fv the initial field values of the object.
084: */
085: public static StateManager newStateManagerForHollowPopulated(
086: ObjectManager om, Class pcClass, Object id, FieldValues fv) {
087: Initialization stateManagerInitialization = new Initialization(
088: om, pcClass);
089: StateManager sm = om.getApiAdapter().newStateManager(om,
090: stateManagerInitialization.getClassMetaData());
091: sm.initialiseForHollow(id, fv, stateManagerInitialization
092: .getPCClass());
093: return sm;
094: }
095:
096: /**
097: * Constructs a state manager to manage the specified persistent instance having the given object ID.
098: * @param om the persistence manager controlling this state manager.
099: * @param id the JDO identity of the object.
100: * @param pc The object that is persistent that we are going to manage
101: */
102: public static StateManager newStateManagerForPersistentClean(
103: ObjectManager om, Object id, Object pc) {
104: Initialization stateManagerInitialization = new Initialization(
105: om, pc.getClass());
106: StateManager sm = om.getApiAdapter().newStateManager(om,
107: stateManagerInitialization.getClassMetaData());
108: sm.initialiseForPersistentClean(id, pc);
109: return sm;
110: }
111:
112: /**
113: * Constructs a state manager to manage a hollow (or pclean) instance having the given FieldValues.
114: * This constructor is used for creating new instances of existing persistent objects using application identity.
115: * @param om the object manager controlling this state manager.
116: * @param pcClass the class of the new instance to be created.
117: * @param fv the initial field values of the object.
118: */
119: public static StateManager newStateManagerForHollowPopulatedAppId(
120: ObjectManager om, Class pcClass, FieldValues fv) {
121: Initialization stateManagerInitialization = new Initialization(
122: om, pcClass);
123: StateManager sm = om.getApiAdapter().newStateManager(om,
124: stateManagerInitialization.getClassMetaData());
125: sm.initialiseForHollowAppId(fv, stateManagerInitialization
126: .getPCClass());
127: return sm;
128: }
129:
130: /**
131: * Constructs a state manager to manage a persistable instance that will
132: * be EMBEDDED/SERIALISED into another persistable object. The instance will not be
133: * assigned an identity in the process since it is a SCO.
134: * @param om The object manager controlling this state manager.
135: * @param pc The persistable to manage (see copyPc also)
136: * @param copyPc Whether the SM should manage a copy of the passed PC or that one
137: */
138: public static StateManager newStateManagerForEmbedded(
139: ObjectManager om, Object pc, boolean copyPc) {
140: Initialization stateManagerInitialization = new Initialization(
141: om, pc.getClass());
142: StateManager sm = om.getApiAdapter().newStateManager(om,
143: stateManagerInitialization.getClassMetaData());
144: sm.initialiseForEmbedded(pc, copyPc);
145: return sm;
146: }
147:
148: /**
149: * Constructs a state manager to manage a transient instance that is
150: * becoming newly persistent. A new object ID for the
151: * instance is obtained from the store manager and the object is inserted
152: * in the data store.
153: * This constructor is used for assigning state managers to existing
154: * instances that are transitioning to a persistent state.
155: * @param om the object manager controlling this state manager.
156: * @param pc the instance being make persistent.
157: * @param preInsertChanges Any changes to make before inserting
158: */
159: public static StateManager newStateManagerForPersistentNew(
160: ObjectManager om, Object pc, FieldValues preInsertChanges) {
161: Initialization stateManagerInitialization = new Initialization(
162: om, pc.getClass());
163: StateManager sm = om.getApiAdapter().newStateManager(om,
164: stateManagerInitialization.getClassMetaData());
165: sm.initialiseForPersistentNew(pc, preInsertChanges);
166: return sm;
167: }
168:
169: /**
170: * Constructs a state manager to manage a Transactional Transient instance.
171: * A new object ID for the instance is obtained from the store manager and
172: * the object is inserted in the data store.
173: * This constructor is used for assigning state managers to Transient
174: * instances that are transitioning to a transient clean state.
175: * @param om the object manager controlling this state manager.
176: * @param pc the instance being make persistent.
177: */
178: public static StateManager newStateManagerForTransactionalTransient(
179: ObjectManager om, Object pc) {
180: Initialization stateManagerInitialization = new Initialization(
181: om, pc.getClass());
182: StateManager sm = om.getApiAdapter().newStateManager(om,
183: stateManagerInitialization.getClassMetaData());
184: sm.initialiseForTransactionalTransient(pc);
185: return sm;
186: }
187:
188: /**
189: * Constructor for creating SM instances to manage persistable objects in detached state.
190: * @param om ObjectManager
191: * @param pc the detached object
192: * @param id the JDO identity of the object.
193: * @param version the detached version
194: * @since 1.1
195: */
196: public static StateManager newStateManagerForDetached(
197: ObjectManager om, Object pc, Object id, Object version) {
198: Initialization stateManagerInitialization = new Initialization(
199: om, pc.getClass());
200: StateManager sm = om.getApiAdapter().newStateManager(om,
201: stateManagerInitialization.getClassMetaData());
202: sm.initialiseForDetached(pc, id, version);
203: return sm;
204: }
205:
206: /**
207: * Constructor for creating SM instances to manage persistable objects that are not persistent yet
208: * are about to be deleted. Consequently the initial lifecycle state will be P_NEW, but will soon
209: * move to P_NEW_DELETED.
210: * @param om ObjectManager
211: * @param pc the object being deleted from persistence
212: * @since 1.2
213: */
214: public static StateManager newStateManagerForPNewToBeDeleted(
215: ObjectManager om, Object pc) {
216: Initialization stateManagerInitialization = new Initialization(
217: om, pc.getClass());
218: StateManager sm = om.getApiAdapter().newStateManager(om,
219: stateManagerInitialization.getClassMetaData());
220: sm.initialiseForPNewToBeDeleted(pc);
221: return sm;
222: }
223:
224: /**
225: * Constructor to create a StateManager for a persistable object, assigning the
226: * specified id to the object. This is used when getting objects out of the L2 Cache,
227: * where they have no StateManager assigned, and returning them as associated with a
228: * particular PM.
229: * @param om Object Manager managing this object
230: * @param pc The persistable object from the cache
231: * @param id Id to assign to the persistable object
232: * @param loaded The list of loaded fields (when put in the cache)
233: */
234: public static StateManager newStateManagerForCachedPC(
235: ObjectManager om, Object pc, Object id, boolean loaded[]) {
236: Initialization stateManagerInitialization = new Initialization(
237: om, pc.getClass());
238: StateManager sm = om.getApiAdapter().newStateManager(om,
239: stateManagerInitialization.getClassMetaData());
240: sm.initialiseForCachedPC(pc, id, loaded,
241: stateManagerInitialization.getPCClass());
242: return sm;
243: }
244:
245: protected static class Initialization {
246: /** Class of the object being managed. This is only stored for some initialise methods that also need the class. */
247: protected Class pcClass;
248:
249: /** the metadata for the class. */
250: protected AbstractClassMetaData cmd;
251:
252: /**
253: * Constructor.
254: * @param myOM ObjectManager
255: * @param pcClass The class of the object that this will manage the state for
256: */
257: protected Initialization(ObjectManager myOM, Class pcClass) {
258: ClassLoaderResolver clr = myOM.getClassLoaderResolver();
259: if (myOM.getOMFContext().getTypeManager().isReferenceType(
260: pcClass)) {
261: // TODO interfaces
262: // in this case JPOX supports only one level for interfaces. in case of many levels, JPOX supports only one branch
263: cmd = myOM.getMetaDataManager()
264: .getMetaDataForImplementationOfReference(
265: pcClass, null, clr);
266:
267: // calling the CLR will make sure the class is initialized
268: this .pcClass = clr.classForName(cmd.getFullClassName(),
269: pcClass.getClassLoader(), true);
270: } else {
271: try {
272: // calling the CLR will make sure the class is initialized
273: this .pcClass = clr.classForName(pcClass.getName(),
274: pcClass.getClassLoader(), true);
275:
276: cmd = myOM.getMetaDataManager()
277: .getMetaDataForClass(pcClass, clr);
278: } catch (ClassNotResolvedException e) {
279: throw new JPOXUserException(LOCALISER.msg("026015",
280: pcClass.getName())).setFatal();
281: }
282: }
283: if (cmd == null) {
284: throw new JPOXUserException(LOCALISER.msg("026012",
285: pcClass)).setFatal();
286: }
287: }
288:
289: protected Class getPCClass() {
290: return pcClass;
291: }
292:
293: protected AbstractClassMetaData getClassMetaData() {
294: return cmd;
295: }
296: }
297: }
|