/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2005 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S.Chassande-Barrioz.
*
*/
package org.objectweb.speedo.pm.jdo.lib;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jdo.JDODataStoreException;
import javax.jdo.JDOException;
import javax.jdo.JDOUnsupportedOptionException;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.datastore.DataStoreCache;
import javax.jdo.listener.InstanceLifecycleListener;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.Interface;
import org.objectweb.jorm.api.PClassMapping;
import org.objectweb.jorm.api.PException;
import org.objectweb.perseus.cache.api.CacheEntry;
import org.objectweb.perseus.cache.api.CacheEntryFilter;
import org.objectweb.perseus.cache.api.CacheException;
import org.objectweb.perseus.cache.api.FixableCacheEntry;
import org.objectweb.perseus.persistence.api.PersistenceException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.mapper.api.ConnectionSpecFactory;
import org.objectweb.speedo.mim.api.HomeItf;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.speedo.pm.jdo.api.JDOPOManagerFactoryItf;
import org.objectweb.speedo.pm.jdo.api.JDOPOManagerItf;
import org.objectweb.speedo.pm.lib.AbstractPOManagerFactory;
import org.objectweb.util.monolog.api.BasicLevel;
/**
* The JDOPOManagerFactory is a factory of JDOPOManagerItf.
*
* @see org.objectweb.speedo.pm.api.POManagerItf
* @see org.objectweb.speedo.pm.api.POManagerSwitchItf
* @see org.objectweb.speedo.pm.jdo.lib.JDOPOManager
* @see org.objectweb.speedo.pm.jdo.lib.JDOPOManagerFactory
* @see org.objectweb.speedo.pm.lib.POManagerInstanciatorImpl
* @see org.objectweb.speedo.pm.lib.POManagerSwitchImpl
*
* @author S.Chassande-Barrioz
*/
public class JDOPOManagerFactory
extends AbstractPOManagerFactory
implements JDOPOManagerFactoryItf,
PersistenceManagerFactory {
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 5483892775367751203L;
public final static String CONNECTION_SPEC_FACTORY =
"org.objectweb.speedo.connectionSpecFactory";
private final static String optionArray[] = {
SpeedoProperties.JDO_OPTION_TRANSIENT_TRANSACTIONAL,
//not yet supportded JDO_OPTION_NON_TRANSACTIONAL_READ,
//not yet supportded ed JDO_OPTION_NON_TRANSACTIONAL_WRITE,
SpeedoProperties.JDO_OPTION_RETAIN_VALUES,
//not yet supportded JDO_OPTION_RESTORE_VALUES,
SpeedoProperties.JDO_OPTION_OPTIMISTIC,
SpeedoProperties.JDO_OPTION_APPLICATION_IDENTITY,
SpeedoProperties.JDO_OPTION_DATASTORE_IDENTITY,
SpeedoProperties.JDO_OPTION_NON_DURABLE_IDENTITY,
SpeedoProperties.JDO_OPTION_ARRAY_LIST,
SpeedoProperties.JDO_OPTION_HASH_MAP,
SpeedoProperties.JDO_OPTION_HASH_TABLE,
SpeedoProperties.JDO_OPTION_LINKED_LIST,
SpeedoProperties.JDO_OPTION_TREE_MAP,
SpeedoProperties.JDO_OPTION_TREE_SET,
SpeedoProperties.JDO_OPTION_VECTOR,
SpeedoProperties.JDO_OPTION_ARRAY,
SpeedoProperties.JDO_OPTION_MAP,
SpeedoProperties.JDO_OPTION_LIST,
SpeedoProperties.JDO_OPTION_NULL_COLLECTION,
SpeedoProperties.JDO_QUERY_JDOQL
};
private List registeredClasses = new ArrayList();
public JDOPOManagerFactory() {
super(Personality.JDO);
//JDOImplHelper.getInstance().addRegisterClassListener(this);
}
public POManagerItf getPOManager() {
return (POManagerItf) getPersistenceManager();
}
// IMPLEMENTATION OF THE DataStoreCache INTERFACE //
//------------------------------------------------//
public void evict(Object oid) {
try {
tpm.evict(null, oid, false);
} catch (PersistenceException e) {
throw new JDOException("Error during the eviction of an entry: ", e);
}
}
public void evictAll(Class clazz, boolean subClasses) {
final List classesToEvict = getClasses(clazz, subClasses);
try {
unbindManager.unbind(new CacheEntryFilter() {
public boolean accept(CacheEntry ce) {
Object o = ce.getCeObject();
return o != null && classesToEvict.contains(o.getClass());
}
}, false);
} catch (CacheException e) {
throw new JDOException("Error during the eviction of entries of the class '"
+ clazz.getName() + "' with"
+ (subClasses ? "" : "out") + " sub classes: ", e);
}
}
private List getClasses(Class clazz, boolean subClasses) {
List classes = new ArrayList();
classes.add(clazz);
if (subClasses) {
PClassMapping[] subpcms;
try {
subpcms = jormFactory.getPClassMapping(clazz).getSubPCMs();
} catch (PException e1) {
return classes;
}
for (int i = 0; i < subpcms.length; i++) {
ClassLoader cl = subpcms[i].getClass().getClassLoader();
if (cl == null) {
cl = getClass().getClassLoader();
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
}
try {
Class subclass = cl.loadClass(subpcms[i].getClassName());
classes.add(subclass);
} catch (ClassNotFoundException e) {
logger.log(BasicLevel.WARN,
"Impossible to load the class '"
+ subpcms[i].getClassName() + "': ", e);
continue;
}
}
}
return classes;
}
public void evictAll(Collection oids) {
try {
unbindManager.unbind(oids, false);
} catch (CacheException e) {
throw new JDOException("Error during the eviction of an entry: ", e);
}
}
public void evictAll(Object[] oids) {
evictAll(Arrays.asList(oids));
}
public void evictAll() {
try {
unbindManager.unbindUnfixed(false);
} catch (CacheException e) {
throw new JDOException("Error during the eviction of an entry: ", e);
}
}
public void pin(Object oid) {
FixableCacheEntry ce = (FixableCacheEntry) cacheManager.lookup(oid);
if (ce != null && ce.getCeFixCount() == 0) {
try {
cacheManager.fix(ce);
} catch (CacheException e) {
logger.log(BasicLevel.WARN, "Impossible to pin the persistent class: ", e);
}
} //else TODO: pin forever an oid by creating the CacheEntry
}
public void pinAll(Class clazz, boolean subClasses) {
final List classesToPin = getClasses(clazz, subClasses);
try {
cacheManager.unfix(new CacheEntryFilter() {
public boolean accept(CacheEntry ce) {
Object o = ce.getCeObject();
return ((FixableCacheEntry) ce).getCeFixCount() == 0
&& o != null && classesToPin.contains(o.getClass());
}
});
} catch (CacheException e) {
throw new JDOException("Error during the eviction of entries of the class '"
+ clazz.getName() + "' with"
+ (subClasses ? "" : "out") + " sub classes: ", e);
}
// TODO: pin forever
}
public void pinAll(Collection oids) {
for (Iterator iter = oids.iterator(); iter.hasNext();) {
pin(iter.next());
}
}
public void pinAll(Object[] oids) {
pinAll(Arrays.asList(oids));
}
public void unpin(Object oid) {
FixableCacheEntry ce = (FixableCacheEntry) cacheManager.lookup(oid);
if (ce != null && ce.getCeFixCount() == 0) {
try {
cacheManager.unfix(ce);
} catch (CacheException e) {
logger.log(BasicLevel.WARN, "Impossible to pin the persistent class: ", e);
}
}
}
public void unpinAll(Class clazz, boolean subClasses) {
final List classesToUnpin = getClasses(clazz, subClasses);
try {
cacheManager.unfix(new CacheEntryFilter() {
public boolean accept(CacheEntry ce) {
Object o = ce.getCeObject();
return ((FixableCacheEntry) ce).getCeFixCount() == 1
&& o != null && classesToUnpin.contains(o.getClass());
}
});
} catch (CacheException e) {
throw new JDOException("Error during the eviction of entries of the class '"
+ clazz.getName() + "' with"
+ (subClasses ? "" : "out") + " sub classes: ", e);
}
// TODO: unpin forever
}
public void unpinAll(Collection oids) {
for (Iterator iter = oids.iterator(); iter.hasNext();) {
unpin(iter.next());
}
}
public void unpinAll(Object[] oids) {
unpinAll(Arrays.asList(oids));
}
// IMPLEMENTATION OF THE PersistentManagerFactory INTERFACE //
//----------------------------------------------------------//
/** Get an instance of PersistenceManager from this factory. The instance has
* default values for options.
* Invokes <code>init</code> at the first call.
*
* @return a PersistenceManager instance with default options.
*/
public PersistenceManager getPersistenceManager() {
return getPersistenceManager(null);
}
public void close() {
//TODO: implements the close method on the PMF
}
/** Get an instance of PersistenceManager from this factory. The instance has
* default values for options. The parameters userid and password are used
* when obtaining datastore connections from the connection pool.
* Invokes <code>init</code> at the first call.
*
* @param userid the userid for the connection
* @param password the password for the connection
* @return a PersistenceManager instance with default options.
*/
public PersistenceManager getPersistenceManager(String userid, String password) {
Object cs = null;
if (csf == null) {
String cn = connectionProperties.getProperty(CONNECTION_SPEC_FACTORY);
if (cn != null && cn.length() > 0) {
try {
csf = (ConnectionSpecFactory) Class.forName(cn).newInstance();
cs = csf.getConnectionSpec(this, userid, password);
} catch (Exception e) {
logger.log(BasicLevel.ERROR,
"Impossible to instanciate the ConnectionSpecFactory: "
+ cn, e);
}
}
} else {
cs = csf.getConnectionSpec(this, userid, password);
}
return getPersistenceManager(cs);
}
public synchronized PersistenceManager getPersistenceManager(Object cs) {
if (!started) {
imbricatedAuthorized = Boolean.valueOf(
connectionProperties.getProperty(
SpeedoProperties.IMRICATED_PM_ALLOWED, "false"))
.booleanValue();
start();
}
if (imbricatedAuthorized) {
JDOPOManagerItf pm = (JDOPOManagerItf) pms.lookup(getThis());
if (pm != null) {
pm.getSemaphore().P();
try {
if ((cs == null && pm.getConnectionSpec() == null)
|| (cs != null && cs.equals(pm.getConnectionSpec()))) {
if (!pm.isPOMClosed()) {
logger.log(BasicLevel.INFO, "reuse the same PersistenceManager (Imbricated)");
pm.addUse();
return pm;
}
}
} finally {
pm.getSemaphore().V();
}
}
}
try {
// Gets a PM from the pool
Object pr = managedPM.getResource(null);
logger.log(BasicLevel.DEBUG, "get a persistenceManager from the pool");
Component ci = ((Interface) pr).getFcItfOwner();
JDOPOManagerItf pm = (JDOPOManagerItf) ci.getFcInterface("po-manager");
pm.open(cs);
bindPM2Thread(pm);
pm.addUse();
return pm;
} catch (Exception e) {
throw new JDODataStoreException(
"Cannot provides a PersistenceManager ", new Exception[]{e});
}
}
public DataStoreCache getDataStoreCache() {
return this;
}
public boolean isClosed() {
//TODO: implement the isclosed method on PMF
return false;
}
public String getMapping() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_MAPPING, "no user name defined");
}
public void setMapping(String arg0) {
connectionProperties.setProperty(SpeedoProperties.JDO_OPTION_MAPPING, arg0);
}
/** Set the user name for the data store connection.
* @param userName the user name for the data store connection.
*/
public void setConnectionUserName(String userName) {
connectionProperties.setProperty(SpeedoProperties.JDO_OPTION_CONNECTION_USER_NAME, userName);
}
/** Get the user name for the data store connection.
* @return the user name for the data store connection.
*/
public String getConnectionUserName() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_USER_NAME, "no user name defined");
}
/** Set the password for the data store connection.
* @param password the password for the data store connection.
*/
public void setConnectionPassword(String password) {
connectionProperties.setProperty(SpeedoProperties.JDO_OPTION_CONNECTION_PASSWORD, password);
}
/** Get the password for the data store connection.
* @return password the password for the data store connection.
*/
protected String getConnectionPassword() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_PASSWORD);
}
/** Set the URL for the data store connection.
* @param URL the URL for the data store connection.
*/
public void setConnectionURL(String URL) {
connectionProperties.setProperty(SpeedoProperties.JDO_OPTION_CONNECTION_URL, URL);
}
/** Get the URL for the data store connection.
* @return the URL for the data store connection.
*/
public String getConnectionURL() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_URL);
}
/** Set the driver name for the data store connection.
* @param driverName the driver name for the data store connection.
*/
public void setConnectionDriverName(String driverName) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(SpeedoProperties.JDO_OPTION_CONNECTION_DRIVER_NAME, driverName);
}
/** Get the driver name for the data store connection.
* @return the driver name for the data store connection.
*/
public String getConnectionDriverName() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_DRIVER_NAME);
}
/** Set the name for the data store connection factory.
* @param connectionFactoryName the name of the data store connection factory.
*/
public void setConnectionFactoryName(String connectionFactoryName) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY_NAME, connectionFactoryName);
}
/** Get the name for the data store connection factory.
* @return the name of the data store connection factory.
*/
public String getConnectionFactoryName() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY_NAME);
}
/** Set the data store connection factory. JDO implementations
* will support specific connection factories. The connection
* factory interfaces are not part of the JDO specification.
* @param connectionFactory the data store connection factory.
*/
public void setConnectionFactory(Object connectionFactory) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
throw new JDOUnsupportedOptionException("Cannot set a Connection Factory, use <> instead");
}
/** Get the data store connection factory.
* @return the data store connection factory.
*/
public Object getConnectionFactory() {
return mapper.getConnectionFactory();
}
/** Set the name for the second data store connection factory. This is
* needed for managed environments to get nontransactional connections for
* optimistic transactions.
* @param connectionFactoryName the name of the data store connection factory.
*/
public void setConnectionFactory2Name(String connectionFactoryName) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY2_NAME, connectionFactoryName);
}
/** Get the name for the second data store connection factory. This is
* needed for managed environments to get nontransactional connections for
* optimistic transactions.
* @return the name of the data store connection factory.
*/
public String getConnectionFactory2Name() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY2_NAME);
}
/** Set the second data store connection factory. This is
* needed for managed environments to get nontransactional connections for
* optimistic transactions. JDO implementations
* will support specific connection factories. The connection
* factory interfaces are not part of the JDO specification.
* @param connectionfactory the data store connection factory.
*/
public void setConnectionFactory2(Object connectionfactory) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
throw new JDOUnsupportedOptionException(
"Cannot set a second Connection Factory");
}
/** Get the second data store connection factory. This is
* needed for managed environments to get nontransactional connections for
* optimistic transactions.
* @return the data store connection factory.
*/
public Object getConnectionFactory2() {
return mapper.getConnectionFactory();
}
/** Set the default Multithreaded setting for all PersistenceManager instances
* obtained from this factory.
*
* @param flag the default Multithreaded setting.
*/
public void setMultithreaded(boolean flag) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_MULTITREADED, new Boolean(flag).toString());
}
/** Get the default Multithreaded setting for all PersistenceManager instances
* obtained from this factory.
*
* @return the default Multithreaded setting.
*/
public boolean getMultithreaded() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_MULTITREADED, "").equals("true");
}
/** Set the default Optimistic setting for all PersistenceManager instances
* obtained from this factory.
*
* @param flag the default Optimistic setting.
*/
public void setOptimistic(boolean flag) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_OPTIMISTIC, new Boolean(flag).toString());
}
/** Get the default Optimistic setting for all PersistenceManager instances
* obtained from this factory.
*
* @return the default Optimistic setting.
*/
public boolean getOptimistic() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_OPTIMISTIC,"").equals("true");
}
/** Set the default RetainValues setting for all PersistenceManager instances
* obtained from this factory.
*
* @param flag the default RetainValues setting.
*/
public void setRetainValues(boolean flag) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_RETAIN_VALUES, new Boolean(flag).toString());
}
/** Get the default RetainValues setting for all PersistenceManager instances
* obtained from this factory.
*
* @return the default RetainValues setting.
*/
public boolean getRetainValues() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_RETAIN_VALUES, "").equals("true");
}
/** Set the default NontransactionalRead setting for all PersistenceManager instances
* obtained from this factory.
*
* @param flag the default NontransactionalRead setting.
*/
public void setNontransactionalRead(boolean flag) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_READ, new Boolean(flag).toString());
}
/** Get the default NontransactionalRead setting for all PersistenceManager instances
* obtained from this factory.
*
* @return the default NontransactionalRead setting.
*/
public boolean getNontransactionalRead() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_READ).equals("true");
}
/** Set the default NontransactionalWrite setting for all PersistenceManager instances
* obtained from this factory.
*
* @param flag the default NontransactionalWrite setting.
*/
public void setNontransactionalWrite(boolean flag) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_WRITE, new Boolean(flag).toString());
}
/** Get the default NontransactionalWrite setting for all PersistenceManager instances
* obtained from this factory.
*
* @return the default NontransactionalWrite setting.
*/
public boolean getNontransactionalWrite() {
return connectionProperties.getProperty(SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_WRITE).equals("true");
}
/** Set the default IgnoreCache setting for all PersistenceManager instances
* obtained from this factory.
*
* @param flag the default IgnoreCache setting.
*/
public void setIgnoreCache(boolean flag) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(
SpeedoProperties.JDO_OPTION_IGNORE_CACHE, new Boolean(flag).toString());
}
/** Get the default IgnoreCache setting for all PersistenceManager instances
* obtained from this factory.
*
* @return the default IngoreCache setting.
*/
public boolean getIgnoreCache() {
return "true".equalsIgnoreCase(connectionProperties
.getProperty(SpeedoProperties.JDO_OPTION_IGNORE_CACHE));
}
/** Get the MaxPool setting for the PersistenceManager
* pool for this factory.
* @return the MaxPool setting.
*/
public int getMaxPool() {
String v = connectionProperties.getProperty(SpeedoProperties.PM_POOL_MAX);
if (v != null && v.length()>0) {
return Integer.parseInt(v);
} else {
return GETMAXPOOL;
}
}
/** Set the MaxPool setting for the PersistenceManager
* pool for this factory.
* @param maxPool the MaxPool setting.
*/
public void setMaxPool(int maxPool) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(SpeedoProperties.PM_POOL_MAX, Integer.toString(maxPool));
}
/** Get the MinPool setting for the PersistenceManager
* pool for this factory.
* @return the MinPool setting.
*/
public int getMinPool() {
return Integer.parseInt(connectionProperties.getProperty(SpeedoProperties.PM_POOL_MIN));
}
/** Set the MinPool setting for the PersistenceManager
* pool for this factory.
* @param minPool the MinPool setting.
*/
public void setMinPool(int minPool) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(SpeedoProperties.PM_POOL_MIN, Integer.toString(minPool));
}
/** Get the MsWait setting for the PersistenceManager
* pool for this factory.
* @return the MsWait setting.
*/
public int getMsWait() {
return Integer.parseInt(connectionProperties.getProperty(SpeedoProperties.PM_POOL_TIMEOUT));
}
/** Set the MsWait setting for the PersistenceManager
* pool for this factory.
* @param msWait the MsWait setting.
*/
public void setMsWait(int msWait) {
if (started) {
throw new JDOUserException("It is forbidden to modify property after a getPersistenceManager() call");
}
connectionProperties.setProperty(SpeedoProperties.PM_POOL_TIMEOUT, Integer.toString(msWait));
}
/** The application can determine from the results of this
* method which optional features, and which query languages
* are supported by the JDO implementation.
* <P>Each supported JDO optional feature is represented by a
* String with one of the following values:
*
* <P>javax.jdo.option.TransientTransactional
* <P>javax.jdo.option.NontransactionalRead
* <P>javax.jdo.option.NontransactionalWrite
* <P>javax.jdo.option.RetainValues
* <P>javax.jdo.option.Optimistic
* <P>javax.jdo.option.ApplicationIdentity
* <P>javax.jdo.option.DatastoreIdentity
* <P>javax.jdo.option.NonDatastoreIdentity
* <P>javax.jdo.option.ArrayList
* <P>javax.jdo.option.HashMap
* <P>javax.jdo.option.Hashtable
* <P>javax.jdo.option.LinkedList
* <P>javax.jdo.option.TreeMap
* <P>javax.jdo.option.TreeSet
* <P>javax.jdo.option.Vector
* <P>javax.jdo.option.Map
* <P>javax.jdo.option.List
* <P>javax.jdo.option.Array
* <P>javax.jdo.option.NullCollection
*
*<P>The standard JDO query language is represented by a String:
*<P>javax.jdo.query.JDOQL
* @return the List of String representing the supported Options
*/
public Collection supportedOptions() {
return Collections.unmodifiableList(Arrays.asList(optionArray));
}
public void setRestoreValues(boolean b) {
}
public boolean getRestoreValues() {
return false;
}
private Map class2listeners;
private Map listener2classes;
public synchronized void addInstanceLifecycleListener(
InstanceLifecycleListener l,
Class[] classes) {
//Register the listener
if (class2listeners == null) {
class2listeners = new HashMap();
listener2classes = new HashMap();
}
List classesCol = (List) listener2classes.get(l);
if (classesCol == null) {
classesCol = new ArrayList();
listener2classes.put(l, classesCol);
}
classesCol.addAll(Arrays.asList(classes));
for (int i = 0; i < classes.length; i++) {
List listenersCol = (List) class2listeners.get(classes[i]);
if (listenersCol == null) {
listenersCol = new ArrayList();
class2listeners.put(classes[i], listenersCol);
}
listenersCol.add(l);
HomeItf sh = null;
try {
sh = (HomeItf) jormFactory.getPClassMapping(classes[i]);
} catch (PException e) {
}
if (sh == null) {
logger.log(BasicLevel.WARN, "Class '" + classes[i].getName()
+ "' is not recongnized as a persistent class. The listener will not receiver event, but it is registerd.");
} else {
sh.addInstanceLifeCycleListener(l);
}
}
}
public synchronized void removeInstanceLifecycleListener(InstanceLifecycleListener l) {
List classes = (List) listener2classes.remove(l);
if (classes != null) {
for (Iterator iter = classes.iterator(); iter.hasNext();) {
Class clazz = (Class) iter.next();
List listenersCol = (List) class2listeners.get(clazz);
if (listenersCol != null) {
if (listenersCol.remove(l)) {
HomeItf sh = null;
try {
sh = (HomeItf) jormFactory.getPClassMapping(clazz);
} catch (PException e) {
}
if (sh != null) {
sh.removeInstanceLifeCycleListener(l);
}
}
}
}
}
}
/* (non-Javadoc)
* @see javax.jdo.PersistenceManagerFactory#getDetachAllOnCommit()
*/
public boolean getDetachAllOnCommit() {
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see javax.jdo.PersistenceManagerFactory#setDetachAllOnCommit(boolean)
*/
public void setDetachAllOnCommit(boolean arg0) {
// TODO Auto-generated method stub
}
}