/**********************************************************************
Copyright (c) 2006 Erik Bengtson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributors:
2006 Andy Jefferson - changed to use constructor and initialiseXXX methods
2007 Xuan Baldauf - added method newStateManagerForHollowPreConstructed(), needed for DB4O plugin
2007 Andy Jefferson - removed all passed in PersistenceCapable
...
**********************************************************************/
package org.jpox.state;
import org.jpox.ClassLoaderResolver;
import org.jpox.ObjectManager;
import org.jpox.ObjectManagerFactoryImpl;
import org.jpox.StateManager;
import org.jpox.exceptions.ClassNotResolvedException;
import org.jpox.exceptions.JPOXUserException;
import org.jpox.metadata.AbstractClassMetaData;
import org.jpox.store.FieldValues;
import org.jpox.util.Localiser;
/**
* Factory of StateManagers.
*
* @version $Revision: 1.27 $
*/
public class StateManagerFactory
{
/** Localiser for messages. */
protected static final Localiser LOCALISER = Localiser.getInstance("org.jpox.Localisation",
ObjectManagerFactoryImpl.class.getClassLoader());
/**
* Constructs a state manager to manage a hollow instance having the given object ID.
* This constructor is used for creating new instances of existing persistent objects.
* @param om the persistence manager controlling this state manager.
* @param pcClass the class of the new instance to be created.
* @param id the JDO identity of the object.
*/
public static StateManager newStateManagerForHollow(ObjectManager om, Class pcClass, Object id)
{
Initialization stateManagerInitialization = new Initialization(om,pcClass);
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForHollow(id, null, stateManagerInitialization.getPCClass());
return sm;
}
/**
* Constructs a state manager to manage a hollow instance having the given object ID.
* The instance is already supplied.
* @param om the persistence manager controlling this state manager.
* @param id the JDO identity of the object.
* @param pc The object that is hollow that we are going to manage
*/
public static StateManager newStateManagerForHollowPreConstructed(ObjectManager om, Object id, Object pc)
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForHollowPreConstructed(id, pc);
return sm;
}
/**
* Constructs a state manager to manage a recently populated hollow instance having the
* given object ID and the given field values. This constructor is used for
* creating new instances of persistent objects obtained e.g. via a Query or backed by a view.
* @param om the object manager controlling this state manager.
* @param pcClass the class of the new instance to be created.
* @param id the JDO identity of the object.
* @param fv the initial field values of the object.
*/
public static StateManager newStateManagerForHollowPopulated(ObjectManager om, Class pcClass, Object id, FieldValues fv)
{
Initialization stateManagerInitialization = new Initialization(om,pcClass);
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForHollow(id, fv, stateManagerInitialization.getPCClass());
return sm;
}
/**
* Constructs a state manager to manage the specified persistent instance having the given object ID.
* @param om the persistence manager controlling this state manager.
* @param id the JDO identity of the object.
* @param pc The object that is persistent that we are going to manage
*/
public static StateManager newStateManagerForPersistentClean(ObjectManager om, Object id, Object pc)
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForPersistentClean(id, pc);
return sm;
}
/**
* Constructs a state manager to manage a hollow (or pclean) instance having the given FieldValues.
* This constructor is used for creating new instances of existing persistent objects using application identity.
* @param om the object manager controlling this state manager.
* @param pcClass the class of the new instance to be created.
* @param fv the initial field values of the object.
*/
public static StateManager newStateManagerForHollowPopulatedAppId(ObjectManager om, Class pcClass, FieldValues fv)
{
Initialization stateManagerInitialization = new Initialization(om,pcClass);
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForHollowAppId(fv,stateManagerInitialization.getPCClass());
return sm;
}
/**
* Constructs a state manager to manage a persistable instance that will
* be EMBEDDED/SERIALISED into another persistable object. The instance will not be
* assigned an identity in the process since it is a SCO.
* @param om The object manager controlling this state manager.
* @param pc The persistable to manage (see copyPc also)
* @param copyPc Whether the SM should manage a copy of the passed PC or that one
*/
public static StateManager newStateManagerForEmbedded(ObjectManager om, Object pc, boolean copyPc)
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForEmbedded(pc, copyPc);
return sm;
}
/**
* Constructs a state manager to manage a transient instance that is
* becoming newly persistent. A new object ID for the
* instance is obtained from the store manager and the object is inserted
* in the data store.
* This constructor is used for assigning state managers to existing
* instances that are transitioning to a persistent state.
* @param om the object manager controlling this state manager.
* @param pc the instance being make persistent.
* @param preInsertChanges Any changes to make before inserting
*/
public static StateManager newStateManagerForPersistentNew(ObjectManager om, Object pc, FieldValues preInsertChanges)
{
Initialization stateManagerInitialization = new Initialization(om, pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForPersistentNew(pc, preInsertChanges);
return sm;
}
/**
* Constructs a state manager to manage a Transactional Transient instance.
* A new object ID for the instance is obtained from the store manager and
* the object is inserted in the data store.
* This constructor is used for assigning state managers to Transient
* instances that are transitioning to a transient clean state.
* @param om the object manager controlling this state manager.
* @param pc the instance being make persistent.
*/
public static StateManager newStateManagerForTransactionalTransient(ObjectManager om, Object pc)
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForTransactionalTransient(pc);
return sm;
}
/**
* Constructor for creating SM instances to manage persistable objects in detached state.
* @param om ObjectManager
* @param pc the detached object
* @param id the JDO identity of the object.
* @param version the detached version
* @since 1.1
*/
public static StateManager newStateManagerForDetached(ObjectManager om, Object pc, Object id, Object version)
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForDetached(pc, id, version);
return sm;
}
/**
* Constructor for creating SM instances to manage persistable objects that are not persistent yet
* are about to be deleted. Consequently the initial lifecycle state will be P_NEW, but will soon
* move to P_NEW_DELETED.
* @param om ObjectManager
* @param pc the object being deleted from persistence
* @since 1.2
*/
public static StateManager newStateManagerForPNewToBeDeleted(ObjectManager om, Object pc)
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForPNewToBeDeleted(pc);
return sm;
}
/**
* Constructor to create a StateManager for a persistable object, assigning the
* specified id to the object. This is used when getting objects out of the L2 Cache,
* where they have no StateManager assigned, and returning them as associated with a
* particular PM.
* @param om Object Manager managing this object
* @param pc The persistable object from the cache
* @param id Id to assign to the persistable object
* @param loaded The list of loaded fields (when put in the cache)
*/
public static StateManager newStateManagerForCachedPC(ObjectManager om, Object pc, Object id, boolean loaded[])
{
Initialization stateManagerInitialization = new Initialization(om,pc.getClass());
StateManager sm = om.getApiAdapter().newStateManager(om, stateManagerInitialization.getClassMetaData());
sm.initialiseForCachedPC(pc, id, loaded, stateManagerInitialization.getPCClass());
return sm;
}
protected static class Initialization
{
/** Class of the object being managed. This is only stored for some initialise methods that also need the class. */
protected Class pcClass;
/** the metadata for the class. */
protected AbstractClassMetaData cmd;
/**
* Constructor.
* @param myOM ObjectManager
* @param pcClass The class of the object that this will manage the state for
*/
protected Initialization(ObjectManager myOM, Class pcClass)
{
ClassLoaderResolver clr = myOM.getClassLoaderResolver();
if (myOM.getOMFContext().getTypeManager().isReferenceType(pcClass))
{
// TODO interfaces
// in this case JPOX supports only one level for interfaces. in case of many levels, JPOX supports only one branch
cmd = myOM.getMetaDataManager().getMetaDataForImplementationOfReference(pcClass, null, clr);
// calling the CLR will make sure the class is initialized
this.pcClass = clr.classForName(cmd.getFullClassName(), pcClass.getClassLoader(), true);
}
else
{
try
{
// calling the CLR will make sure the class is initialized
this.pcClass = clr.classForName(pcClass.getName(), pcClass.getClassLoader(), true);
cmd = myOM.getMetaDataManager().getMetaDataForClass(pcClass, clr);
}
catch (ClassNotResolvedException e)
{
throw new JPOXUserException(LOCALISER.msg("026015", pcClass.getName())).setFatal();
}
}
if (cmd == null)
{
throw new JPOXUserException(LOCALISER.msg("026012", pcClass)).setFatal();
}
}
protected Class getPCClass()
{
return pcClass;
}
protected AbstractClassMetaData getClassMetaData()
{
return cmd;
}
}
}