0001: /**
0002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
0003: * I/O sub-system.
0004: * Copyright (C) 2001-2005 France Telecom R&D
0005: *
0006: * This library is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2 of the License, or (at your option) any later version.
0010: *
0011: * This library is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Lesser General Public
0017: * License along with this library; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0019: *
0020: *
0021: *
0022: * Contact: speedo@objectweb.org
0023: *
0024: * Authors: S.Chassande-Barrioz.
0025: *
0026: */package org.objectweb.speedo.pm.jdo.lib;
0027:
0028: import org.objectweb.fractal.api.control.BindingController;
0029: import org.objectweb.jorm.api.PException;
0030: import org.objectweb.perseus.persistence.api.NoDSIPersistenceException;
0031: import org.objectweb.perseus.persistence.api.PersistenceException;
0032: import org.objectweb.perseus.persistence.api.RolledBackPersistenceException;
0033: import org.objectweb.speedo.api.ExceptionHelper;
0034: import org.objectweb.speedo.api.SpeedoRuntimeException;
0035: import org.objectweb.speedo.metadata.SpeedoVersion;
0036: import org.objectweb.speedo.mim.api.DetachedLifeCycle;
0037: import org.objectweb.speedo.mim.api.FetchPlanItf;
0038: import org.objectweb.speedo.mim.api.HomeItf;
0039: import org.objectweb.speedo.mim.api.LifeCycle;
0040: import org.objectweb.speedo.mim.api.PersistentObjectItf;
0041: import org.objectweb.speedo.mim.api.StateItf;
0042: import org.objectweb.speedo.mim.jdo.api.JDOPersistentObjectItf;
0043: import org.objectweb.speedo.mim.jdo.lib.JDOFetchPlan;
0044: import org.objectweb.speedo.pm.jdo.api.JDOPOManagerItf;
0045: import org.objectweb.speedo.pm.lib.AbstractPOManager;
0046: import org.objectweb.speedo.query.api.QueryDefinition;
0047: import org.objectweb.speedo.query.jdo.JDOExtent;
0048: import org.objectweb.speedo.query.jdo.JDOQuery;
0049: import org.objectweb.speedo.query.jdo.JDOQueryDefinitionImpl;
0050: import org.objectweb.speedo.workingset.jdo.api.JDOTransactionItf;
0051: import org.objectweb.util.monolog.api.BasicLevel;
0052:
0053: import java.util.ArrayList;
0054: import java.util.Arrays;
0055: import java.util.Collection;
0056: import java.util.Collections;
0057: import java.util.HashMap;
0058: import java.util.Iterator;
0059: import java.util.Map;
0060: import java.util.Set;
0061:
0062: import javax.jdo.Extent;
0063: import javax.jdo.FetchPlan;
0064: import javax.jdo.JDODataStoreException;
0065: import javax.jdo.JDOException;
0066: import javax.jdo.JDOUnsupportedOptionException;
0067: import javax.jdo.JDOUserException;
0068: import javax.jdo.PersistenceManagerFactory;
0069: import javax.jdo.Query;
0070: import javax.jdo.datastore.JDOConnection;
0071: import javax.jdo.datastore.Sequence;
0072: import javax.jdo.listener.DeleteCallback;
0073: import javax.jdo.listener.InstanceLifecycleListener;
0074:
0075: /**
0076: * Is a fractal component exporting the POManagerItf interface. This
0077: * implementation delegates most of the JDO methods (javax.jdo.PersistenceManager)
0078: * to the underlying TransactionPersistenceManager, the perseus component
0079: * managing the concurrency, the caching and the loading aspect.
0080: * In order to represents a working set (transtional or not) this PM is linked
0081: * forever to an org.objectweb.speedo.workingset.jdo.api.JDOTransactionItf instance. The
0082: * status of this JDOTransactionItf instance changes when this PM is allocated
0083: * or closed, or when transaction demarcations are done through the
0084: * javax.jdo.Transaction interface.
0085: * This implementation uses a QueryManager for allocating CompiledQuery
0086: * instance. Concerning the javax.jdo.Query implementation, this PM uses
0087: * org.objectweb.speedo.query.lib.SpeedoQuery which are created each time
0088: * (No pooling mechanism).
0089: * The last dependencies is the JormFactory and a P
0090: *
0091: *
0092: * @see javax.jdo.PersistenceManager
0093: * @see org.objectweb.perseus.persistence.api.TransactionalPersistenceManager
0094: * @see org.objectweb.speedo.mapper.api.JormFactory
0095: * @see org.objectweb.speedo.pm.api.POManagerFactoryItf
0096: * @see org.objectweb.speedo.query.api.QueryManager
0097: * @see org.objectweb.speedo.query.api.CompiledQuery
0098: * @see org.objectweb.speedo.workingset.jdo.api.JDOTransactionItf
0099: *
0100: * @author S.Chassande-Barrioz
0101: */
0102: public class JDOPOManager extends AbstractPOManager implements
0103: JDOPOManagerItf, BindingController {
0104:
0105: /**
0106: * The user object
0107: */
0108: private Object userObject = null;
0109:
0110: /**
0111: * indicates if the cache must be ignore on queries
0112: */
0113: boolean ignoreCache = true;
0114:
0115: private HashMap userObjects = new HashMap();
0116:
0117: public JDOPOManager() {
0118: super ();
0119: }
0120:
0121: public Query createQuery(Object o) {
0122: JDOQuery sq = new JDOQuery();
0123: sq.withPrefetch(prefetchOnQuery);
0124: sq.setPOManager(this );
0125: //initialize the fetch plan of the speedo query
0126: sq.setFetchPlan(getFetchPlan());
0127: sq.setQueryManager(queryManager);
0128: sq.setIgnoreCache(ignoreCache);
0129: sq.setLogger(loggerFactory.getLogger(logger.getName()
0130: + ".query"));
0131: if (o != null && o instanceof JDOQueryDefinitionImpl) {
0132: sq.defineWith((JDOQueryDefinitionImpl) o);
0133: }
0134: return sq;
0135: }
0136:
0137: // IMPLEMENTATION OF THE JDOConnection INTERFACE //
0138: //-----------------------------------------------//
0139:
0140: public Object getNativeConnection() {
0141: try {
0142: if (((JDOTransactionItf) tx).getOptimistic()) {
0143: return new DSConnectionFilter(tx.getConnectionHolder()
0144: .getCHConnectionForRead(), true);
0145: } else {
0146: return new DSConnectionFilter(tx.getConnectionHolder()
0147: .getCHConnectionForWrite(), false);
0148: }
0149: } catch (PersistenceException e) {
0150: throw new JDODataStoreException(
0151: "Impossible to allocate a native connection:", e);
0152: }
0153: }
0154:
0155: // IMPLEMENTATION OF THE PersistentManager INTERFACE //
0156: //---------------------------------------------------//
0157: public boolean isClosed() {
0158: return isPOMClosed();
0159: }
0160:
0161: public void addInstanceLifecycleListener(
0162: InstanceLifecycleListener l, Class[] classes) {
0163: // TODO: support lifeCycle listener (add)
0164: }
0165:
0166: public void removeInstanceLifecycleListener(
0167: InstanceLifecycleListener classes) {
0168: // TODO: support lifeCycle listener (remove)
0169: }
0170:
0171: public void flush() {
0172: try {
0173: speedoFlush();
0174: } catch (PersistenceException e) {
0175: throw new JDODataStoreException(
0176: "Impossible to flush the working set");
0177: }
0178: }
0179:
0180: public JDOConnection getDataStoreConnection() {
0181: return this ;
0182: }
0183:
0184: public FetchPlanItf speedoGetFetchPlan() {
0185: if (fetchPlan == null) {
0186: fetchPlan = new JDOFetchPlan();
0187: }
0188: return fetchPlan;
0189:
0190: }
0191:
0192: public FetchPlan getFetchPlan() {
0193: return (FetchPlan) speedoGetFetchPlan();
0194: }
0195:
0196: /**
0197: * Fetches the Null PName associated to the PBinder of the persistent class
0198: */
0199: public java.lang.Class getObjectIdClass(Class cls) {
0200: bindPMThread();
0201: if (cls == null) {
0202: return null;
0203: }
0204: try {
0205: return jf.getPBinder(cls).getNull().getClass();
0206: } catch (PException e) {
0207: Exception ie = ExceptionHelper.getNested(e);
0208: logger.log(BasicLevel.ERROR,
0209: "Error during the fetching of the manager of the class "
0210: + cls.getName(), ie);
0211: throw new JDOException("", ie);
0212: }
0213: }
0214:
0215: /**
0216: * This method closes the PersistenceManager.
0217: * @exception javax.jdo.JDOUserException if the transaction associated to
0218: * the persistence manager is active.
0219: * @exception javax.jdo.JDOFatalDataStoreException if there is a problem while
0220: * releasing the persistence manager.
0221: */
0222: public void close() {
0223: closePOManager();
0224: }
0225:
0226: /**
0227: * Return the JDOTransactionItf instance associated with a PersistenceManager.
0228: * @return the JDOTransactionItf associated with this
0229: * PersistenceManager.
0230: */
0231: public javax.jdo.Transaction currentTransaction() {
0232: bindPMThread();
0233: return ((JDOTransactionItf) tx);
0234: }
0235:
0236: /**
0237: * Mark an instance as no longer needed in the cache.
0238: * @param o the instance to evict from the cache.
0239: */
0240: public void evict(Object o) {
0241: if (o == null)
0242: return;
0243: assertIsOpen();
0244: bindPMThread();
0245: JDOPersistentObjectItf sp = (JDOPersistentObjectItf) o;
0246: if (tx.isActive() && sp.jdoIsDirty())
0247: throw new JDOUserException("Impossible to evict a dirty "
0248: + "instance attached to an active transaction");
0249: try {
0250: tpm.evict(tx, sp.getCeIdentifier(), false);
0251: } catch (PersistenceException e) {
0252: throw new JDOUserException(
0253: "Impossible to evict the persistent object from the cache",
0254: e);
0255: }
0256: }
0257:
0258: /** Mark an array of instances as no longer needed in the cache.
0259: * @see #evict(java.lang.Object pc)
0260: * @param pcs the array of instances to evict from the cache.
0261: * @exception javax.jdo.JDOUserException if some instances cannot be removed.
0262: */
0263: public void evictAll(Object[] pcs) {
0264: Throwable[] th = new Throwable[pcs.length];
0265: int lg = 0;
0266: for (int i = 0; i < pcs.length; i++) {
0267: try {
0268: if (pcs[i] != null) {
0269: evict(pcs[i]);
0270: }
0271: } catch (Throwable e) {
0272: th[lg] = e;
0273: lg++;
0274: }
0275: }
0276: if (lg > 0) {
0277: Throwable[] tfin = new Throwable[lg];
0278: System.arraycopy(th, 0, tfin, 0, lg);
0279: throw new JDOUserException("Impossible to evict", tfin);
0280: }
0281: }
0282:
0283: /** Mark a Set of instances as no longer needed in the cache.
0284: * @see #evict(java.lang.Object pc)
0285: * @param pcs the Set of instance to evict from the cache.
0286: */
0287: public void evictAll(Collection pcs) {
0288: evictAll(pcs.toArray());
0289: }
0290:
0291: /** Mark all persistent-nontransactional instances as no longer needed
0292: * in the cache. It transitions all persistent-nontransactional instances to
0293: * hollow. Transactional instances are subject to eviction based on the
0294: * RetainValues setting.
0295: * @see #evict(java.lang.Object pc)
0296: */
0297: public void evictAll() {
0298: assertIsOpen();
0299: try {
0300: tpm.evictAll(tx, false);
0301: } catch (PersistenceException e) {
0302: throw new JDOException(
0303: "Error during the eviction of all cache entries: ",
0304: ExceptionHelper.getNested(e));
0305: }
0306: }
0307:
0308: /** Refresh the state of the instance from the data store.
0309: * <P>In an optimistic transaction, the state of instances in the cache
0310: * might not match the state in the data store. This method is used to
0311: * reload the state of the instance from the data store so that a subsequent
0312: * commit is more likely to succeed.
0313: * <P>Outside a transaction, this method will refresh nontransactional
0314: * state.
0315: * @param o the instance to refresh.
0316: */
0317: public void refresh(Object o) {
0318: if (o == null)
0319: return;
0320: PersistentObjectItf sp = (PersistentObjectItf) o;
0321: assertIsOpen();
0322: bindPMThread();
0323: assertIsPO(sp, "refresh");
0324: assertPOManager(sp);
0325: if (!sp.speedoIsActive())
0326: throw new JDOUserException(
0327: "Refresh on a transient instance.");
0328: speedoRefresh(sp, new HashMap(), new ArrayList());
0329: }
0330:
0331: public void speedoRefresh(PersistentObjectItf sp, Map map,
0332: Collection fgHints) {
0333: try {
0334: if (map != null && !map.containsKey(sp.getPName())) {
0335: map.put(sp.getPName(), sp);
0336: tpm.refresh(tx, sp);
0337: StateItf sa = (StateItf) tpm
0338: .readIntention(tx, sp, null);
0339: sa.refresh(this , map, fgHints);
0340: }
0341: } catch (PersistenceException e) {
0342: throw new JDOException(
0343: "Impossible to refresh a persistent instance", e);
0344: }
0345: }
0346:
0347: /** Refresh the state of an array of instances from the data store.
0348: * @see #refresh(java.lang.Object pc)
0349: * @param pcs the array of instances to refresh.
0350: * object.
0351: */
0352: public void refreshAll(Object[] pcs) {
0353: Throwable[] th = new Throwable[pcs.length];
0354: int lg = 0;
0355: for (int i = 0; i < pcs.length; i++) {
0356: try {
0357: if (pcs[i] != null) {
0358: refresh(pcs[i]);
0359: }
0360: } catch (Throwable e) {
0361: th[lg] = e;
0362: lg++;
0363: }
0364: }
0365: if (lg > 0) {
0366: Throwable[] tfin = new Throwable[lg];
0367: System.arraycopy(th, 0, tfin, 0, lg);
0368: throw new JDOUserException("Impossible to refresh", tfin);
0369: }
0370: }
0371:
0372: /** Refresh the state of a Set of instances from the data store.
0373: * @see #refresh(java.lang.Object pc)
0374: * @param pcs the Set of instances to refresh.
0375: */
0376: public void refreshAll(Collection pcs) {
0377: refreshAll(pcs.toArray());
0378: }
0379:
0380: /** Refresh the state of all applicable instances from the data store.
0381: * <P>If called with an active transaction, all transactional instances
0382: * will be refreshed. If called outside an active transaction, all
0383: * nontransactional instances will be refreshed.
0384: * @see #refresh(java.lang.Object pc)
0385: */
0386: public void refreshAll() {
0387: assertIsOpen();
0388: if (!tx.isActive()) {
0389: return;
0390: }
0391: Set entries = tx.entries();
0392: int size = entries.size();
0393: if (size == 0) {
0394: return;
0395: }
0396: Object[] sps = new Object[size];
0397: Iterator it = entries.iterator();
0398: int i = 0;
0399: while (it.hasNext() && i < sps.length) {
0400: org.objectweb.perseus.persistence.api.State s = (org.objectweb.perseus.persistence.api.State) it
0401: .next();
0402: sps[i] = s.getCacheEntry();
0403: i++;
0404: }
0405: refreshAll(sps);
0406: }
0407:
0408: public void refreshAll(JDOException arg0) {
0409: //TODO: review the refreshAll(JDOException) behavior
0410: refreshAll();
0411: }
0412:
0413: /**
0414: * Create a new Query with no elements.
0415: * @return the new Query.
0416: */
0417: public Query newQuery() {
0418: assertIsOpen();
0419: bindPMThread();
0420: return createQuery(null);
0421: }
0422:
0423: public Query newQuery(String query) {
0424: assertIsOpen();
0425: bindPMThread();
0426: //TODO: Implements newQuery(String)
0427: return createQuery(null);
0428: }
0429:
0430: public Query newNamedQuery(Class klass, String name) {
0431: try {
0432: QueryDefinition qd = ((HomeItf) jf.getPClassMapping(klass))
0433: .getNamedQuery(name);
0434: return createQuery(qd);
0435: } catch (PException e) {
0436: Exception ie = ExceptionHelper.getNested(e);
0437: logger.log(BasicLevel.ERROR,
0438: "Error during the fetching of the manager of the class "
0439: + klass.getName(), ie);
0440: throw new JDOException(
0441: "Error during the fetching of the manager of the class ",
0442: ie);
0443: }
0444: }
0445:
0446: /**
0447: * Create a new Query using elements from another Query.
0448: * The other Query must have been created by the same JDO implementation.
0449: * It might be active in a different PersistenceManager or might have been
0450: * serialized and restored.
0451: * <P>All of the settings of the other Query are copied to this Query,
0452: * except for the candidate Set or Extent.
0453: * @return the new Query
0454: * @param compiled another Query from the same JDO implementation
0455: */
0456: public Query newQuery(Object compiled) {
0457: assertIsOpen();
0458: bindPMThread();
0459: return createQuery(compiled);
0460: }
0461:
0462: /**
0463: * Create a new Query using the specified language.
0464: * @param language the language of the query parameter
0465: * @param query the query, which is of a form determined by the language
0466: * @return the new Query
0467: */
0468: public Query newQuery(String language, Object query) {
0469: assertIsOpen();
0470: bindPMThread();
0471: if (language.compareTo("java.jdo.query.toVerify") == 0) {
0472: return createQuery(query);
0473: } else
0474: throw new JDOUnsupportedOptionException("Language \""
0475: + language + "\""
0476: + " is not supported by this jdo implementation");
0477: }
0478:
0479: /**
0480: * Create a new Query specifying the Class of the candidate instances.
0481: * @param cls the Class of the candidate instances
0482: * @return the new Query
0483: */
0484: public Query newQuery(Class cls) {
0485: assertIsOpen();
0486: bindPMThread();
0487: Query q = createQuery(null);
0488: q.setClass(cls);
0489: if (getObjectIdClass(cls) == null)
0490: throw new JDOUnsupportedOptionException(
0491: "There is a problem with the specified class");
0492: return q;
0493: }
0494:
0495: public Query newQuery(Extent extent) {
0496: assertIsOpen();
0497: bindPMThread();
0498: JDOQuery q = (JDOQuery) createQuery(null);
0499: Class c = extent.getCandidateClass();
0500: q.setIncludeSubClasses(extent.hasSubclasses());
0501: q.setClass(c);
0502: if (getObjectIdClass(c) == null)
0503: throw new JDOUnsupportedOptionException(
0504: "There is a problem with the specified class");
0505: return q;
0506: }
0507:
0508: public Query newQuery(Extent extent, String filter) {
0509: assertIsOpen();
0510: bindPMThread();
0511: Query q = newQuery(extent);
0512: q.setFilter(filter);
0513: return q;
0514: }
0515:
0516: /**
0517: * Create a new Query with the Class of the candidate instances and
0518: * candidate Set.
0519: * @param cls the Class of results
0520: * @param cln the Set of candidate instances
0521: * @return the new Query
0522: */
0523: public Query newQuery(Class cls, Collection cln) {
0524: assertIsOpen();
0525: bindPMThread();
0526: Query q = createQuery(null);
0527: q.setClass(cls);
0528: q.setCandidates(cln);
0529: return q;
0530: }
0531:
0532: /**
0533: * Create a new Query with the Class of the candidate instances and filter.
0534: * @param cls the Class of results
0535: * @param filter the filter for candidate instances
0536: * @return the new Query
0537: */
0538: public Query newQuery(Class cls, String filter) {
0539: assertIsOpen();
0540: bindPMThread();
0541: Query q = createQuery(null);
0542: q.setClass(cls);
0543: q.setFilter(filter);
0544: return q;
0545: }
0546:
0547: /**
0548: * Create a new Query with the Class of the candidate instances,
0549: * candidate Set, and filter.
0550: * @param cls the Class of candidate instances
0551: * @param cln the Set of candidate instances
0552: * @param filter the filter for candidate instances
0553: * @return the new Query
0554: */
0555: public Query newQuery(Class cls, Collection cln, String filter) {
0556: assertIsOpen();
0557: bindPMThread();
0558: Query q = createQuery(null);
0559: q.setClass(cls);
0560: q.setCandidates(cln);
0561: q.setFilter(filter);
0562: return q;
0563: }
0564:
0565: /** Not implemented. The PersistenceManager manages a collection of
0566: * instances in the data store based on the class of the instances. This
0567: * method returns a Extent of instances in the data store that might be
0568: * iterated or given to a Query. The Extent itself might not reference any
0569: * instances, but only hold the class name and an
0570: * indicator whether subclasses are included in the Extent.
0571: * @param persistenceCapableClass Class of instances
0572: * @param subclasses whether to include instances of subclasses
0573: * @return an Extent of the specified Class
0574: */
0575: public Extent getExtent(Class persistenceCapableClass,
0576: boolean subclasses) {
0577: assertIsOpen();
0578: bindPMThread();
0579: return new JDOExtent(persistenceCapableClass, subclasses, this ,
0580: jf, prefetchOnExtent, logger);
0581: }
0582:
0583: public Extent getExtent(Class arg0) {
0584: return getExtent(arg0, true);
0585: }
0586:
0587: /** This method locates a persistent instance in the cache of instances
0588: * managed by this PersistenceManager. The getObjectById method attempts
0589: * to find an instance in the cache with the specified JDO identity.
0590: * The oid parameter object might have been returned by an earlier call
0591: * to getObjectId or getTransactionalObjectId, or might have been
0592: * constructed by the application.
0593: * @see #getObjectId(java.lang.Object pc)
0594: * @see #getTransactionalObjectId(java.lang.Object pc)
0595: * @return the PersistenceCapable instance with the specified
0596: * ObjectId
0597: * @param oid an ObjectId
0598: * @param validate if the existence of the instance is to be validated. The
0599: * flag is ignored in this implementation.
0600: */
0601: public Object getObjectById(Object oid, boolean validate) {
0602: assertIsOpen();
0603: bindPMThread();
0604: return speedoGetObjectById(oid, validate);
0605: }
0606:
0607: public Object getObjectById(Class arg0, Object oid) {
0608: assertIsOpen();
0609: bindPMThread();
0610: return speedoGetObjectById(newObjectIdInstance(arg0, oid),
0611: false);
0612: }
0613:
0614: public Object getObjectById(Object oid) {
0615: assertIsOpen();
0616: bindPMThread();
0617: return speedoGetObjectById(oid, false);
0618: }
0619:
0620: public Collection getObjectsById(Collection arg0, boolean validate) {
0621: if (arg0 == null) {
0622: return Collections.EMPTY_LIST;
0623: }
0624: assertIsOpen();
0625: bindPMThread();
0626: ArrayList al = new ArrayList(arg0.size());
0627: for (Iterator it = arg0.iterator(); it.hasNext();) {
0628: Object oid = it.next();
0629: if (oid == null) {
0630: al.add(null);
0631: continue;
0632: }
0633: try {
0634: al.add(speedoGetObjectById(oid, validate));
0635: } catch (Exception e) {
0636: al.add(null);
0637: }
0638: }
0639: return al;
0640: }
0641:
0642: public Collection getObjectsById(Collection arg0) {
0643: return getObjectsById(arg0, true);
0644: }
0645:
0646: public Object[] getObjectsById(Object[] arg0, boolean arg1) {
0647: if (arg0 == null) {
0648: return new Object[0];
0649: }
0650: assertIsOpen();
0651: bindPMThread();
0652: Object[] objs = new Object[arg0.length];
0653: for (int i = 0; i < arg0.length; i++) {
0654: Object oid = arg0[i];
0655: if (oid == null) {
0656: objs[i] = null;
0657: continue;
0658: }
0659: try {
0660: objs[i] = speedoGetObjectById(oid, arg1);
0661: } catch (Exception e) {
0662: objs[i] = null;
0663: }
0664: }
0665: return objs;
0666: }
0667:
0668: public Object[] getObjectsById(Object[] arg0) {
0669: return getObjectsById(arg0, true);
0670: }
0671:
0672: public Object speedoGetObjectById(Object oid, boolean validate) {
0673: if (oid == null)
0674: return null;
0675: try {
0676: try {
0677: return super .speedoGetObject(oid, null, validate);
0678: } catch (SpeedoRuntimeException e) {
0679: throw (Exception) e.getCause();
0680: }
0681: } catch (NoDSIPersistenceException e) {
0682: throw new JDOUserException(
0683: "No data store instance matching to the specified identifier: "
0684: + oid, ExceptionHelper.getNested(e));
0685: } catch (RolledBackPersistenceException e) {
0686: throw ((JDOTransactionItf) tx).rollBackOnInternalError(e);
0687: } catch (Exception e) {
0688: Exception ie = ExceptionHelper.getNested(e);
0689: logger.log(BasicLevel.ERROR,
0690: "Impossible to fetch a persistent object with the identifier: "
0691: + oid, ie);
0692: throw new JDOException("", ie);
0693: }
0694: }
0695:
0696: /** The ObjectId returned by this method represents the JDO identity of
0697: * the instance. The ObjectId is a copy (clone) of the internal state
0698: * of the instance, and changing it does not affect the JDO identity of
0699: * the instance.
0700: * @see #getTransactionalObjectId(java.lang.Object pc)
0701: * @see #getObjectById(java.lang.Object oid, boolean validate)
0702: * @param pc the PersistenceCapable instance
0703: * @return the ObjectId of the instance
0704: */
0705: public Object getObjectId(Object pc) {
0706: assertIsOpen();
0707: bindPMThread();
0708: //the object must be persistence capable. otherwise, it doesn't have an
0709: //objectid
0710: try {
0711: assertIsPO(pc, "");
0712: } catch (Exception e) {
0713: return null;
0714: }
0715: PersistentObjectItf sp = (PersistentObjectItf) pc;
0716: if (!sp.speedoIsActive())
0717: throw new JDOUserException("Object non persistent.");
0718: assertPOManager(sp);
0719: try {
0720: return pnc.encodeAbstract(sp.getPName());
0721: } catch (PException e) {
0722: throw new JDOException(
0723: "Problem while encoding persistent name.",
0724: new Exception[] { ExceptionHelper.getNested(e) });
0725: }
0726: }
0727:
0728: public Object getEncodedPName(PersistentObjectItf po) {
0729: return getObjectId(po);
0730: }
0731:
0732: /** Not implemented. The ObjectId returned by this method represents the JDO
0733: * identity of the instance. The ObjectId is a copy (clone) of the internal
0734: * state of the instance, and changing it does not affect the JDO identity
0735: * of the instance.
0736: * <P>If the object identity is being changed in the transaction, by the
0737: * application modifying one or more of the application key fields,
0738: * then this method returns the current identity in the transaction.
0739: * <P>If there is no transaction in progress, or if none of the key fields
0740: * is being modified, then this method will return the same value as
0741: * getObjectId.
0742: * @see #getObjectId(java.lang.Object pc)
0743: * @see #getObjectById(java.lang.Object oid, boolean validate)
0744: * @param o a PersistenceCapable instance
0745: * @return the ObjectId of the instance
0746: */
0747: public Object getTransactionalObjectId(Object o) {
0748: assertIsOpen();
0749: bindPMThread();
0750: throw new JDOUnsupportedOptionException("Not implemented.");
0751: }
0752:
0753: /** Make the transient instance persistent in this PersistenceManager.
0754: * This method must be called in an active transaction.
0755: * The PersistenceManager assigns an ObjectId to the instance and
0756: * transitions it to persistent-new.
0757: * The instance will be managed in the Extent associated with its Class.
0758: * The instance will be put into the data store at commit.
0759: * The closure of instances of PersistenceCapable classes
0760: * reachable from persistent
0761: * fields will be made persistent at commit. [This is known as
0762: * persistence by reachability.]
0763: * @param o a transient instance of a Class that implements
0764: * PersistenceCapable
0765: */
0766: public Object makePersistent(Object o) {
0767: assertIsOpen();
0768: bindPMThread();
0769: assertIsPO(o, "");
0770: if (o == null)
0771: return null;
0772: JDOPersistentObjectItf jdopo = (JDOPersistentObjectItf) o;
0773: if (jdopo.speedoGetReferenceState().getDetachedStatus() == DetachedLifeCycle.DETACHED_NONE) {
0774: return speedoMakePersistent((PersistentObjectItf) o, null);
0775: } else {
0776: return speedoAttachCopy(o, new HashMap());
0777: }
0778: }
0779:
0780: public Object speedoMakePersistent(PersistentObjectItf po, Map map) {
0781: JDOPersistentObjectItf jdopo = (JDOPersistentObjectItf) po;
0782: if (jdopo.jdoIsPersistent())
0783: return po;
0784: if (!jdopo.speedoIsActive()) {
0785: if (jdopo.speedoGetReferenceState().getDetachedStatus() != DetachedLifeCycle.DETACHED_NONE) {
0786: return null;
0787: }
0788: }
0789: synchronized (jdopo) {
0790: if (jdopo.jdoIsPersistent())
0791: return po;
0792: try {
0793: return speedoPersist(po, map);
0794: } catch (Exception e) {
0795: try {
0796: jdopo.init(null);
0797: } catch (PException e1) {
0798: logger.log(BasicLevel.WARN,
0799: "Error during unbinding:", e1);
0800: }
0801: if (e instanceof RolledBackPersistenceException) {
0802: throw ((JDOTransactionItf) tx)
0803: .rollBackOnInternalError(e);
0804: } else {
0805: throw new JDODataStoreException(
0806: "Problem while making persistent.",
0807: new Exception[] { ExceptionHelper
0808: .getNested(e) });
0809: }
0810: }
0811: }
0812: }
0813:
0814: /** Make an array of instances persistent.
0815: * @param pcs an array of transient instances
0816: * @exception javax.jdo.JDOUserException if an object cannot be made persistent.
0817: * @see #makePersistent(java.lang.Object pc)
0818: */
0819: public Object[] makePersistentAll(Object[] pcs) {
0820: if (pcs == null || pcs.length == 0)
0821: return null;
0822: assertIsOpen();
0823: bindPMThread();
0824: Exception[] th = new Exception[pcs.length];
0825: //the list of returned persistent objects
0826: Object[] pos = new Object[pcs.length];
0827: int lg = 0;
0828: //HashMap in case of detach
0829: HashMap map = new HashMap(1);
0830: for (int i = 0; i < pcs.length; i++) {
0831: try {
0832: assertIsPO(pcs[i], "");
0833: if (true) {
0834: pos[i] = speedoMakePersistent(
0835: (PersistentObjectItf) pcs[i], null);
0836: } else {
0837: pos[i] = speedoAttachCopy(pcs[i], map);
0838: }
0839: } catch (Exception e) {
0840: th[lg] = e;
0841: lg++;
0842: }
0843: }
0844: if (lg > 0) {
0845: Exception[] tfin = new Exception[lg];
0846: System.arraycopy(th, 0, tfin, 0, lg);
0847: throw new JDOUserException(
0848: "Impossible to make persistent : ", tfin);
0849: } else {
0850: return pos;
0851: }
0852: }
0853:
0854: /** Make a Set of instances persistent.
0855: * @param pcs a Set of transient instances
0856: * @see #makePersistent(java.lang.Object pc)
0857: */
0858: public Collection makePersistentAll(Collection pcs) {
0859: if (pcs == null || pcs.size() == 0)
0860: return null;
0861: Object[] pos = makePersistentAll(pcs.toArray());
0862: return Arrays.asList(pos);
0863: }
0864:
0865: /** Delete the persistent instance from the data store.
0866: * This method must be called in an active transaction.
0867: * The data store object will be removed at commit.
0868: * Unlike makePersistent, which makes the closure of the instance
0869: * persistent, the closure of the instance is not deleted from the data
0870: * store.
0871: * This method has no effect if the instance is already deleted in the
0872: * current transaction.
0873: * @param o a persistent instance
0874: * @exception javax.jdo.JDOUserException if the instance is transient or managed by
0875: * another PersistenceManager.
0876: */
0877: public void deletePersistent(Object o) {
0878: assertIsOpen();
0879: bindPMThread();
0880: speedoDeletePersistent(o);
0881: }
0882:
0883: public void speedoDeletePersistent(Object o) {
0884: JDOPersistentObjectItf sp = (JDOPersistentObjectItf) o;
0885: // Verify the instance is managed by this persistence manager
0886: assertPOManager(sp);
0887: // Verify the transaction is active
0888: if (!tx.isActive()) {
0889: throw new JDOUserException("DeletePersistent "
0890: + "must be called in an active transaction");
0891: }
0892: StateItf sa = null;
0893: try {
0894: if (!sp.jdoIsPersistent()) {
0895: throw new JDOUserException(
0896: "DeletePersistent on an instance non persistent.");
0897: }
0898: if (sp.jdoIsDeleted()) {
0899: return;
0900: }
0901: sp.speedoGetHome().sendEvent(HomeItf.PRE_REMOVE, sp, null);
0902: sa = (StateItf) tpm.unexport(tx, sp);
0903: sp.speedoGetHome().sendEvent(HomeItf.POST_REMOVE, sp, null);
0904: } catch (RolledBackPersistenceException e) {
0905: throw ((JDOTransactionItf) tx).rollBackOnInternalError(e);
0906: } catch (PersistenceException e) {
0907: throw new JDOException("", ExceptionHelper.getNested(e));
0908: }
0909: //remove the multivalued fields and cascade delete
0910: sa.deletePersistent(this );
0911: if (logger.isLoggable(BasicLevel.DEBUG)) {
0912: logger.log(BasicLevel.DEBUG,
0913: "Delete a persistent instance, identifier="
0914: + sp.getPName());
0915: }
0916: }
0917:
0918: public void speedoDeletePersistent(Object oid, Class pc) {
0919: // Verify the transaction is active
0920: if (!tx.isActive()) {
0921: throw new JDOUserException("DeletePersistent "
0922: + "must be called in an active transaction");
0923: }
0924: boolean mustLoad = DeleteCallback.class.isAssignableFrom(pc);
0925: if (!mustLoad) {
0926: HomeItf home;
0927: try {
0928: home = (HomeItf) jf.getPClassMapping(pc);
0929: } catch (PException e) {
0930: throw new JDOException("", e);
0931: }
0932: mustLoad = home.hasInstanceLifeCycleListeners();
0933: if (!mustLoad) {
0934: //TODO: manage cascade delete
0935: }
0936: }
0937: if (mustLoad) {
0938: PersistentObjectItf po = (PersistentObjectItf) speedoGetObjectById(
0939: oid, false);
0940: speedoDeletePersistent(po);
0941: return;
0942: }
0943: //no listener or callback
0944: //TODO
0945:
0946: }
0947:
0948: public void deleteByQuery(QueryDefinition qd) {
0949: }
0950:
0951: /** Delete an array of instances from the data store.
0952: * @param pcs a Set of persistent instances
0953: * @see #deletePersistent(java.lang.Object pc)
0954: */
0955: public void deletePersistentAll(Object[] pcs) {
0956: if (pcs == null)
0957: return;
0958: assertIsOpen();
0959: bindPMThread();
0960: Throwable[] th = new Throwable[pcs.length];
0961: int lg = 0;
0962: for (int i = 0; i < pcs.length; i++) {
0963: try {
0964: speedoDeletePersistent(pcs[i]);
0965: } catch (Throwable e) {
0966: th[lg] = e;
0967: lg++;
0968: }
0969: }
0970: if (lg > 0) {
0971: Throwable[] tfin = new Throwable[lg];
0972: System.arraycopy(th, 0, tfin, 0, lg);
0973: throw new JDOUserException(
0974: "Impossible to delete persistent : ", tfin);
0975: }
0976: }
0977:
0978: /** Delete a Set of instances from the data store.
0979: * @param pcs a Set of persistent instances
0980: * @see #deletePersistent(java.lang.Object pc)
0981: */
0982: public void deletePersistentAll(Collection pcs) {
0983: if (pcs == null)
0984: return;
0985: deletePersistentAll(pcs.toArray());
0986: }
0987:
0988: /** Make an instance transient, removing it from management by this
0989: * PersistenceManager.
0990: * <P>The instance loses its JDO identity and it is no longer associated
0991: * with any PersistenceManager. The state of fields is preserved unchanged.
0992: * @param o the instance to make transient.
0993: * @exception javax.jdo.JDOUserException if the instance is dirty.
0994: */
0995: public void makeTransient(Object o) {
0996: assertIsOpen();
0997: bindPMThread();
0998: if (o == null || !(o instanceof JDOPersistentObjectItf)
0999: || !((JDOPersistentObjectItf) o).jdoIsPersistent()) {
1000: return;
1001: }
1002: JDOPersistentObjectItf sp = (JDOPersistentObjectItf) o;
1003: synchronized (sp) {
1004: if (sp.jdoIsDirty()) {
1005: throw new JDOUserException(
1006: "Try to make transient a dirty instance.");
1007: }
1008: try {
1009: tpm.unbind(tx, sp);
1010: } catch (PersistenceException e) {
1011: throw new JDOUserException(
1012: "Impossible to make transient the persistent instance: ",
1013: ExceptionHelper.getNested(e));
1014: }
1015: }
1016: }
1017:
1018: /** Make an array of instances transient, removing them from management by
1019: * this PersistenceManager.
1020: * @see #makeTransient(java.lang.Object pc)
1021: * @param pcs the instances to make transient.
1022: */
1023: public void makeTransientAll(Object[] pcs) {
1024: if (pcs == null)
1025: return;
1026: Throwable[] th = new Throwable[pcs.length];
1027: int lg = 0;
1028: for (int i = 0; i < pcs.length; i++) {
1029: try {
1030: makeTransient(pcs[i]);
1031: } catch (Throwable e) {
1032: th[lg] = e;
1033: lg++;
1034: }
1035: }
1036: if (lg > 0) {
1037: Throwable[] tfin = new Throwable[lg];
1038: System.arraycopy(th, 0, tfin, 0, lg);
1039: throw new JDOUserException(
1040: "Impossible to make transient: ", tfin);
1041: }
1042: }
1043:
1044: /** Make a Set of instances transient, removing them from management
1045: * by this PersistenceManager.
1046: * <P>The instances lose their JDO identity and they are no longer
1047: * associated with any PersistenceManager. The state of fields is preserved
1048: * unchanged.
1049: * @param pcs the instances to make transient.
1050: */
1051: public void makeTransientAll(Collection pcs) {
1052: if (pcs == null)
1053: return;
1054: makeTransientAll(pcs.toArray());
1055: }
1056:
1057: /** Make an instance subject to transactional boundaries.
1058: * @see javax.jdo.PersistenceManager#makeTransactional
1059: * @param o the instance to make transactional.
1060: */
1061: public void makeTransactional(Object o) {
1062: //TODO: support the makeTransactional method
1063: throw new JDOUnsupportedOptionException("not yet implemented");
1064: }
1065:
1066: /** Make an array of instances subject to transactional boundaries.
1067: * @param pcs the array of instances to make transactional.
1068: * @see #makeTransactional(java.lang.Object pc)
1069: */
1070: public void makeTransactionalAll(Object[] pcs) {
1071: if (pcs == null || pcs.length == 0)
1072: return;
1073: Throwable[] th = new Throwable[pcs.length];
1074: int lg = 0;
1075: for (int i = 0; i < pcs.length; i++) {
1076: try {
1077: makeTransactional(pcs[i]);
1078: } catch (Throwable e) {
1079: th[lg] = e;
1080: lg++;
1081: }
1082: }
1083: if (lg > 0) {
1084: Throwable[] tfin = new Throwable[lg];
1085: System.arraycopy(th, 0, tfin, 0, lg);
1086: throw new JDOUserException(
1087: "Impossible to make transactional : ", tfin);
1088: }
1089: }
1090:
1091: /** Make a Set of instances subject to transactional boundaries.
1092: * @param pcs the Set of instances to make transactional.
1093: * @see #makeTransactional(java.lang.Object pc)
1094: */
1095: public void makeTransactionalAll(Collection pcs) {
1096: if (pcs == null || pcs.size() == 0)
1097: return;
1098: makeTransactionalAll(pcs.toArray());
1099: }
1100:
1101: public void makeNontransactional(Object o) {
1102: JDOPersistentObjectItf sp = (JDOPersistentObjectItf) o;
1103: //preconditions
1104: assertIsOpen();
1105: bindPMThread();
1106: assertIsPO(sp, "");
1107: assertPOManager(sp);
1108: if (sp.jdoIsDirty())
1109: throw new JDOUserException(
1110: "Try to make non-transactional a dirty instance.");
1111: sp.speedoGetState().speedoChangeStatus(
1112: LifeCycle.ACTION_MAKENONTRANSACTIONAL);
1113: }
1114:
1115: public void makeNontransactionalAll(Object[] pcs) {
1116: if (pcs == null || pcs.length == 0)
1117: return;
1118: ArrayList th = new ArrayList(pcs.length);
1119: for (int i = 0; i < pcs.length; i++) {
1120: try {
1121: makeNontransactional(pcs[i]);
1122: } catch (Throwable e) {
1123: th.add(e);
1124: }
1125: }
1126: if (th.size() > 0) {
1127: throw new JDOUserException(
1128: "Impossible to make non transactional : ",
1129: (Throwable[]) th.toArray(new Throwable[0]));
1130: }
1131: }
1132:
1133: public void makeNontransactionalAll(Collection pcs) {
1134: if (pcs == null || pcs.size() == 0)
1135: return;
1136: makeNontransactionalAll(pcs.toArray());
1137: }
1138:
1139: public void setUserObject(Object o) {
1140: bindPMThread();
1141: userObject = o;
1142: }
1143:
1144: /** The application can manage the PersistenceManager instances
1145: * more easily by having an application object associated with each
1146: * PersistenceManager instance.
1147: * @return the user object associated with this PersistenceManager
1148: * @see #setUserObject
1149: */
1150: public Object getUserObject() {
1151: bindPMThread();
1152: return userObject;
1153: }
1154:
1155: public PersistenceManagerFactory getPersistenceManagerFactory() {
1156: return (PersistenceManagerFactory) pmf;
1157: }
1158:
1159: /** Set the Multithreaded flag for this PersistenceManager. Applications
1160: * that use multiple threads to invoke methods or access fields from
1161: * instances managed by this PersistenceManager must set this flag to true.
1162: * Instances managed by this PersistenceManager include persistent or
1163: * transactional instances of PersistenceCapable classes, as well as
1164: * helper instances such as Query, JDOTransactionItf, or Extent.
1165: * @param flag the Multithreaded setting.
1166: */
1167: public void setMultithreaded(boolean flag) {
1168: semaphore.init(flag);
1169: }
1170:
1171: /** Get the current Multithreaded flag for this PersistenceManager.
1172: * This option is ignored by the implementation.
1173: * @see #setMultithreaded
1174: * @return the Multithreaded setting.
1175: */
1176: public boolean getMultithreaded() {
1177: return semaphore.on;
1178: }
1179:
1180: /** Set the ignoreCache parameter for queries.
1181: * @param flag the ignoreCache setting.
1182: */
1183: public void setIgnoreCache(boolean flag) {
1184: ignoreCache = flag;
1185: }
1186:
1187: /** Get the ignoreCache setting for queries.
1188: * @return the ignoreCache setting.
1189: * @see #setIgnoreCache
1190: */
1191: public boolean getIgnoreCache() {
1192: return ignoreCache;
1193: }
1194:
1195: public Object newObjectIdInstance(Class aClass, Object s) {
1196: assertIsOpen();
1197: bindPMThread();
1198: try {
1199: return pnc.decodeAbstract(s, aClass);
1200: } catch (PException e) {
1201: throw new JDOUserException(
1202: "Invalid persistent object identifier " + s
1203: + " for the class " + aClass,
1204: new Exception[] { e });
1205: }
1206: }
1207:
1208: public void retrieve(Object o) {
1209: assertIsOpen();
1210: bindPMThread();
1211: assertIsPO(o, "retrieve(Object)");
1212: speedoRetrieve((PersistentObjectItf) o, new HashMap(),
1213: new ArrayList());
1214: }
1215:
1216: public void speedoRetrieve(PersistentObjectItf sp, Map map,
1217: Collection fgHints) {
1218: try {
1219: if (map != null && !map.containsKey(sp.getPName())) {
1220: map.put(sp.getPName(), sp);
1221: tpm.refresh(tx, sp);
1222: StateItf sa = (StateItf) tpm
1223: .readIntention(tx, sp, null);
1224: sa.retrieve(this , map, fgHints);
1225: }
1226: } catch (PersistenceException e) {
1227: throw new JDOException(
1228: "Impossible to retrieve a persistent instance", e);
1229: }
1230: }
1231:
1232: public void retrieveAll(Collection pcs) {
1233: assertIsOpen();
1234: bindPMThread();
1235: if (pcs == null) {
1236: return;
1237: }
1238: for (Iterator it = pcs.iterator(); it.hasNext();) {
1239: Object o = it.next();
1240: assertIsPO(o, "retrieve(Collection)");
1241: speedoRetrieve((PersistentObjectItf) o, new HashMap(),
1242: new ArrayList());
1243: }
1244: }
1245:
1246: public void retrieveAll(Object[] pcs) {
1247: assertIsOpen();
1248: bindPMThread();
1249: if (pcs == null) {
1250: return;
1251: }
1252: for (int i = 0; i < pcs.length; i++) {
1253: assertIsPO(pcs[i], "retrieve(Collection)");
1254: if (((PersistentObjectItf) pcs[i])
1255: .speedoGetReferenceState() != null)
1256: speedoRetrieve((PersistentObjectItf) pcs[i],
1257: new HashMap(), new ArrayList());
1258: }
1259: }
1260:
1261: public void retrieveAll(Collection collection, boolean b) {
1262: retrieveAll(collection);
1263: }
1264:
1265: public void retrieveAll(Object[] objects, boolean b) {
1266: retrieveAll(objects);
1267: }
1268:
1269: /**
1270: * Make a detached copy of the persitent object o and return it.
1271: * Only the fields belonging to the fetch group are reachable.
1272: * @param o
1273: * @return the detached copy of the persistent object
1274: */
1275: public Object detachCopy(Object o) {
1276: assertIsOpen();
1277: assertIsPO(o, "detachCopy");
1278: return speedoDetachCopy((PersistentObjectItf) o, new HashMap(),
1279: new ArrayList());
1280: }
1281:
1282: public Object speedoDetachCopy(PersistentObjectItf po, Map map,
1283: Collection fgHints) {
1284: JDOPersistentObjectItf jdopo = (JDOPersistentObjectItf) po;
1285: //check the meta info about the detachability of the class
1286: if (jdopo.jdoIsPersistent()) {
1287: if (jdopo.jdoIsDeleted()) {
1288: //persistent_deleted
1289: if (!jdopo.jdoIsNew())
1290: throw new JDOUserException(
1291: "This object cannot be detached: it has been deleted from the datastore.");
1292: }
1293: } else {
1294: //makePersistent
1295: speedoMakePersistent(jdopo, null);
1296: }
1297: if (!jdopo.speedoGetHome().isDetachable()) {
1298: throw new JDOUserException(
1299: "This class cannot be detached: it has not been defined as detachable in the jdo file.");
1300: }
1301: jdopo.speedoGetHome()
1302: .sendEvent(HomeItf.PRE_DETACH, jdopo, null);
1303: //persistent_new or persistent_dirty: updated with object id and version
1304: if (jdopo.jdoIsTransactional() && jdopo.jdoIsDirty()) {
1305: try {
1306: StateItf sa = (StateItf) tpm.writeIntention(tx, jdopo,
1307: null);
1308: if (!sa.hasBeenFlush()) {
1309: //flush
1310: tpm.flush(tx, sa);
1311: }
1312: } catch (Exception e) {
1313: throw new JDODataStoreException(
1314: "Problem while flushing a persistent object in order to detach a copy.",
1315: new Exception[] { ExceptionHelper.getNested(e) });
1316: }
1317: }
1318: //the core processing
1319: //avoid cycles using a map
1320: try {
1321: synchronized (fgHints) {
1322: PersistentObjectItf copy = jdopo.speedoGetHome()
1323: .detachCopy(jdopo, this , map, null, fgHints);
1324: if (jdopo.speedoGetHome().getVersioningStrategy() == SpeedoVersion.VERSION_NUMBER) {
1325: copy.speedoGetReferenceState()
1326: .speedoChangeVersion();
1327: }
1328: return copy;
1329: }
1330: } catch (Exception e) {
1331: throw new JDOUserException("Detach cannot be performed",
1332: new Exception[] { ExceptionHelper.getNested(e) });
1333: } finally {
1334: jdopo.speedoGetHome().sendEvent(HomeItf.POST_DETACH, jdopo,
1335: null);
1336: }
1337: }
1338:
1339: /**
1340: * Create a detached copy for each element of collection (assuming each element is persistent).
1341: * If there are duplicates in collection, the corresponding detached copy is used for each such duplicate.
1342: * @param collection
1343: * @return the collection of the detached copies in the same order than the parameter
1344: */
1345: public Collection detachCopyAll(Collection collection) {
1346: assertIsOpen();
1347: if (collection == null)
1348: return null;
1349: makePersistentAll(collection);
1350: ArrayList copies = new ArrayList();
1351: for (Iterator it = collection.iterator(); it.hasNext();) {
1352: copies.add(detachCopy(it.next()));
1353: }
1354: return copies;
1355: }
1356:
1357: public Object[] detachCopyAll(Object[] objects) {
1358: assertIsOpen();
1359: if (objects == null)
1360: return null;
1361: makePersistentAll(objects);
1362: Object[] copies = new Object[objects.length];
1363: for (int i = 0; i < objects.length; i++) {
1364: copies[i] = detachCopy(objects[i]);
1365: }
1366: return copies;
1367: }
1368:
1369: /**
1370: * Apply the changes contained in the detached object to the corresponding persistent instance in the cache.
1371: * @param detached
1372: * @param map is the attachement context
1373: * @return the peristent object containg attached values
1374: */
1375: public Object speedoAttachCopy(Object detached, Map map) {
1376: // if the detached object is null
1377: // then do nothing
1378: if (detached == null)
1379: return null;
1380:
1381: Object o = map.get(detached);
1382: // if the object is being or has been processed
1383: // then return the attached copy
1384: if (o != null)
1385: return o;
1386:
1387: Object oid = ((PersistentObjectItf) detached)
1388: .speedoGetEncodedPName();
1389: PersistentObjectItf sp = null;
1390: try {
1391: if (oid == null) {
1392: //make the object persistent
1393: speedoMakePersistent((PersistentObjectItf) detached,
1394: map);
1395: //return detached;
1396: sp = (PersistentObjectItf) detached;
1397: } else {
1398: sp = (PersistentObjectItf) speedoGetObjectById(oid,
1399: false);
1400: }
1401: sp.speedoGetHome().sendEvent(HomeItf.PRE_ATTACH, sp, null);
1402: StateItf sar = sp.speedoGetHome().readIntention(sp, null);
1403: //if made persistent in this method
1404: // force the state to detached_dirty
1405: if (oid == null) {
1406: sar.forceDetachedDirty();
1407: }
1408: //call the attach method on the po
1409: sp.speedoGetHome().attachCopy(sp, this , map, detached, sar);
1410: // if made persistent in this method
1411: // restore the state to detached_none
1412: if (oid == null) {
1413: sar.restoreDetachedNone();
1414: }
1415: //change the version on attach
1416: sar.speedoChangeVersion();
1417: sp.speedoGetHome().sendEvent(HomeItf.POST_ATTACH, sp, null);
1418: return sp;
1419: } catch (Exception e) {
1420: Exception ie = ExceptionHelper.getNested(e);
1421: String msg = "Impossible to attach a copy of the persistent object with the identifier: "
1422: + oid;
1423: logger.log(BasicLevel.INFO, msg, ie);
1424: throw (e instanceof JDOException ? (JDOException) e
1425: : new JDOException(msg, ie));
1426: }
1427: }
1428:
1429: public Object getUserObject(Object arg0) {
1430: return userObjects.get(arg0);
1431: }
1432:
1433: public Object putUserObject(Object arg0, Object arg1) {
1434: return userObjects.put(arg0, arg1);
1435: }
1436:
1437: public Object removeUserObject(Object arg0) {
1438: return userObjects.remove(arg0);
1439: }
1440:
1441: public void checkConsistency() {
1442: flush();
1443: // TODO: verify consistency of state in the WS
1444: }
1445:
1446: public Sequence getSequence(String name) {
1447: Sequence s = (Sequence) pmf.getSequenceManager().getSequence(
1448: name);
1449: if (s == null) {
1450: throw new JDOUserException(
1451: "The sequence "
1452: + name
1453: + " has not been found."
1454: + "Be sure that one class of the package the sequence belongs to has been loaded.");
1455: }
1456: return s;
1457: }
1458:
1459: public Object newInstance(Class arg0) {
1460: if (arg0 == null) {
1461: return null;
1462: }
1463: if (arg0.isInterface()) {
1464: throw new JDOUserException(
1465: "Speedo does not support persistent interface currently: "
1466: + arg0.getName());
1467: } else {
1468: try {
1469: return arg0.newInstance();
1470: } catch (Exception e) {
1471: throw new JDOUserException(
1472: "Speedo does not support persistent abstract class currently: "
1473: + arg0.getName());
1474: }
1475: }
1476: }
1477:
1478: public void closePOManager() {
1479: super .closePOManager();
1480: if (nbUse == 0) {
1481: userObject = null;
1482: }
1483: }
1484:
1485: protected void resetPMOnOpen(Object connectionspec) {
1486: ((JDOTransactionItf) tx)
1487: .setOptimistic(((PersistenceManagerFactory) pmf)
1488: .getOptimistic());
1489: setIgnoreCache(((PersistenceManagerFactory) pmf)
1490: .getIgnoreCache());
1491: boolean multithreaded = ((PersistenceManagerFactory) pmf)
1492: .getMultithreaded();
1493: if (multithreaded != semaphore.on)
1494: semaphore.init(multithreaded);
1495: }
1496:
1497: public void makeTransient(Object o, boolean useFetchPlan) {
1498: if (!useFetchPlan) {
1499: makeTransient(o);
1500: } else {
1501: //TODO: implement
1502: }
1503: }
1504:
1505: public void makeTransientAll(Object[] os, boolean useFetchPlan) {
1506: if (!useFetchPlan) {
1507: makeTransientAll(os);
1508: } else {
1509: //TODO: implement
1510: }
1511: }
1512:
1513: public void makeTransientAll(Collection os, boolean useFetchPlan) {
1514: if (!useFetchPlan) {
1515: makeTransientAll(os);
1516: } else {
1517: //TODO: implement
1518: }
1519: }
1520:
1521: public void retrieve(Object o, boolean FGOnly) {
1522: if (!FGOnly) {
1523: retrieve(o);
1524: } else {
1525: //TODO: implement
1526: }
1527: }
1528:
1529: /* (non-Javadoc)
1530: * @see javax.jdo.PersistenceManager#getDetachAllOnCommit()
1531: */
1532: public boolean getDetachAllOnCommit() {
1533: // TODO Auto-generated method stub
1534: return false;
1535: }
1536:
1537: /* (non-Javadoc)
1538: * @see javax.jdo.PersistenceManager#setDetachAllOnCommit(boolean)
1539: */
1540: public void setDetachAllOnCommit(boolean arg0) {
1541: // TODO Auto-generated method stub
1542: }
1543:
1544: }
|