001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system.
004: * Copyright (C) 2001-2005 France Telecom R&D
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: *
021: *
022: * Contact: speedo@objectweb.org
023: *
024: * Authors: S.Chassande-Barrioz.
025: *
026: */package org.objectweb.speedo.pm.jdo.lib;
027:
028: import java.util.ArrayList;
029: import java.util.Arrays;
030: import java.util.Collection;
031: import java.util.Collections;
032: import java.util.HashMap;
033: import java.util.Iterator;
034: import java.util.List;
035: import java.util.Map;
036:
037: import javax.jdo.JDODataStoreException;
038: import javax.jdo.JDOException;
039: import javax.jdo.JDOUnsupportedOptionException;
040: import javax.jdo.JDOUserException;
041: import javax.jdo.PersistenceManager;
042: import javax.jdo.PersistenceManagerFactory;
043: import javax.jdo.datastore.DataStoreCache;
044: import javax.jdo.listener.InstanceLifecycleListener;
045:
046: import org.objectweb.fractal.api.Component;
047: import org.objectweb.fractal.api.Interface;
048: import org.objectweb.jorm.api.PClassMapping;
049: import org.objectweb.jorm.api.PException;
050: import org.objectweb.perseus.cache.api.CacheEntry;
051: import org.objectweb.perseus.cache.api.CacheEntryFilter;
052: import org.objectweb.perseus.cache.api.CacheException;
053: import org.objectweb.perseus.cache.api.FixableCacheEntry;
054: import org.objectweb.perseus.persistence.api.PersistenceException;
055: import org.objectweb.speedo.api.SpeedoProperties;
056: import org.objectweb.speedo.lib.Personality;
057: import org.objectweb.speedo.mapper.api.ConnectionSpecFactory;
058: import org.objectweb.speedo.mim.api.HomeItf;
059: import org.objectweb.speedo.pm.api.POManagerItf;
060: import org.objectweb.speedo.pm.jdo.api.JDOPOManagerFactoryItf;
061: import org.objectweb.speedo.pm.jdo.api.JDOPOManagerItf;
062: import org.objectweb.speedo.pm.lib.AbstractPOManagerFactory;
063: import org.objectweb.util.monolog.api.BasicLevel;
064:
065: /**
066: * The JDOPOManagerFactory is a factory of JDOPOManagerItf.
067: *
068: * @see org.objectweb.speedo.pm.api.POManagerItf
069: * @see org.objectweb.speedo.pm.api.POManagerSwitchItf
070: * @see org.objectweb.speedo.pm.jdo.lib.JDOPOManager
071: * @see org.objectweb.speedo.pm.jdo.lib.JDOPOManagerFactory
072: * @see org.objectweb.speedo.pm.lib.POManagerInstanciatorImpl
073: * @see org.objectweb.speedo.pm.lib.POManagerSwitchImpl
074: *
075: * @author S.Chassande-Barrioz
076: */
077: public class JDOPOManagerFactory extends AbstractPOManagerFactory
078: implements JDOPOManagerFactoryItf, PersistenceManagerFactory {
079:
080: /**
081: * Comment for <code>serialVersionUID</code>
082: */
083: private static final long serialVersionUID = 5483892775367751203L;
084:
085: public final static String CONNECTION_SPEC_FACTORY = "org.objectweb.speedo.connectionSpecFactory";
086: private final static String optionArray[] = {
087: SpeedoProperties.JDO_OPTION_TRANSIENT_TRANSACTIONAL,
088: //not yet supportded JDO_OPTION_NON_TRANSACTIONAL_READ,
089: //not yet supportded ed JDO_OPTION_NON_TRANSACTIONAL_WRITE,
090: SpeedoProperties.JDO_OPTION_RETAIN_VALUES,
091: //not yet supportded JDO_OPTION_RESTORE_VALUES,
092: SpeedoProperties.JDO_OPTION_OPTIMISTIC,
093: SpeedoProperties.JDO_OPTION_APPLICATION_IDENTITY,
094: SpeedoProperties.JDO_OPTION_DATASTORE_IDENTITY,
095: SpeedoProperties.JDO_OPTION_NON_DURABLE_IDENTITY,
096: SpeedoProperties.JDO_OPTION_ARRAY_LIST,
097: SpeedoProperties.JDO_OPTION_HASH_MAP,
098: SpeedoProperties.JDO_OPTION_HASH_TABLE,
099: SpeedoProperties.JDO_OPTION_LINKED_LIST,
100: SpeedoProperties.JDO_OPTION_TREE_MAP,
101: SpeedoProperties.JDO_OPTION_TREE_SET,
102: SpeedoProperties.JDO_OPTION_VECTOR,
103: SpeedoProperties.JDO_OPTION_ARRAY,
104: SpeedoProperties.JDO_OPTION_MAP,
105: SpeedoProperties.JDO_OPTION_LIST,
106: SpeedoProperties.JDO_OPTION_NULL_COLLECTION,
107: SpeedoProperties.JDO_QUERY_JDOQL };
108:
109: private List registeredClasses = new ArrayList();
110:
111: public JDOPOManagerFactory() {
112: super (Personality.JDO);
113: //JDOImplHelper.getInstance().addRegisterClassListener(this);
114: }
115:
116: public POManagerItf getPOManager() {
117: return (POManagerItf) getPersistenceManager();
118: }
119:
120: // IMPLEMENTATION OF THE DataStoreCache INTERFACE //
121: //------------------------------------------------//
122: public void evict(Object oid) {
123: try {
124: tpm.evict(null, oid, false);
125: } catch (PersistenceException e) {
126: throw new JDOException(
127: "Error during the eviction of an entry: ", e);
128: }
129: }
130:
131: public void evictAll(Class clazz, boolean subClasses) {
132: final List classesToEvict = getClasses(clazz, subClasses);
133: try {
134: unbindManager.unbind(new CacheEntryFilter() {
135: public boolean accept(CacheEntry ce) {
136: Object o = ce.getCeObject();
137: return o != null
138: && classesToEvict.contains(o.getClass());
139: }
140: }, false);
141: } catch (CacheException e) {
142: throw new JDOException(
143: "Error during the eviction of entries of the class '"
144: + clazz.getName() + "' with"
145: + (subClasses ? "" : "out")
146: + " sub classes: ", e);
147: }
148: }
149:
150: private List getClasses(Class clazz, boolean subClasses) {
151: List classes = new ArrayList();
152: classes.add(clazz);
153: if (subClasses) {
154: PClassMapping[] subpcms;
155: try {
156: subpcms = jormFactory.getPClassMapping(clazz)
157: .getSubPCMs();
158: } catch (PException e1) {
159: return classes;
160: }
161: for (int i = 0; i < subpcms.length; i++) {
162: ClassLoader cl = subpcms[i].getClass().getClassLoader();
163: if (cl == null) {
164: cl = getClass().getClassLoader();
165: if (cl == null) {
166: cl = ClassLoader.getSystemClassLoader();
167: }
168: }
169: try {
170: Class subclass = cl.loadClass(subpcms[i]
171: .getClassName());
172: classes.add(subclass);
173: } catch (ClassNotFoundException e) {
174: logger
175: .log(BasicLevel.WARN,
176: "Impossible to load the class '"
177: + subpcms[i].getClassName()
178: + "': ", e);
179: continue;
180: }
181: }
182: }
183: return classes;
184: }
185:
186: public void evictAll(Collection oids) {
187: try {
188: unbindManager.unbind(oids, false);
189: } catch (CacheException e) {
190: throw new JDOException(
191: "Error during the eviction of an entry: ", e);
192: }
193: }
194:
195: public void evictAll(Object[] oids) {
196: evictAll(Arrays.asList(oids));
197: }
198:
199: public void evictAll() {
200: try {
201: unbindManager.unbindUnfixed(false);
202: } catch (CacheException e) {
203: throw new JDOException(
204: "Error during the eviction of an entry: ", e);
205: }
206: }
207:
208: public void pin(Object oid) {
209: FixableCacheEntry ce = (FixableCacheEntry) cacheManager
210: .lookup(oid);
211: if (ce != null && ce.getCeFixCount() == 0) {
212: try {
213: cacheManager.fix(ce);
214: } catch (CacheException e) {
215: logger.log(BasicLevel.WARN,
216: "Impossible to pin the persistent class: ", e);
217: }
218: } //else TODO: pin forever an oid by creating the CacheEntry
219: }
220:
221: public void pinAll(Class clazz, boolean subClasses) {
222: final List classesToPin = getClasses(clazz, subClasses);
223: try {
224: cacheManager.unfix(new CacheEntryFilter() {
225: public boolean accept(CacheEntry ce) {
226: Object o = ce.getCeObject();
227: return ((FixableCacheEntry) ce).getCeFixCount() == 0
228: && o != null
229: && classesToPin.contains(o.getClass());
230: }
231: });
232: } catch (CacheException e) {
233: throw new JDOException(
234: "Error during the eviction of entries of the class '"
235: + clazz.getName() + "' with"
236: + (subClasses ? "" : "out")
237: + " sub classes: ", e);
238: }
239: // TODO: pin forever
240: }
241:
242: public void pinAll(Collection oids) {
243: for (Iterator iter = oids.iterator(); iter.hasNext();) {
244: pin(iter.next());
245: }
246: }
247:
248: public void pinAll(Object[] oids) {
249: pinAll(Arrays.asList(oids));
250: }
251:
252: public void unpin(Object oid) {
253: FixableCacheEntry ce = (FixableCacheEntry) cacheManager
254: .lookup(oid);
255: if (ce != null && ce.getCeFixCount() == 0) {
256: try {
257: cacheManager.unfix(ce);
258: } catch (CacheException e) {
259: logger.log(BasicLevel.WARN,
260: "Impossible to pin the persistent class: ", e);
261: }
262: }
263: }
264:
265: public void unpinAll(Class clazz, boolean subClasses) {
266: final List classesToUnpin = getClasses(clazz, subClasses);
267: try {
268: cacheManager.unfix(new CacheEntryFilter() {
269: public boolean accept(CacheEntry ce) {
270: Object o = ce.getCeObject();
271: return ((FixableCacheEntry) ce).getCeFixCount() == 1
272: && o != null
273: && classesToUnpin.contains(o.getClass());
274: }
275: });
276: } catch (CacheException e) {
277: throw new JDOException(
278: "Error during the eviction of entries of the class '"
279: + clazz.getName() + "' with"
280: + (subClasses ? "" : "out")
281: + " sub classes: ", e);
282: }
283: // TODO: unpin forever
284: }
285:
286: public void unpinAll(Collection oids) {
287: for (Iterator iter = oids.iterator(); iter.hasNext();) {
288: unpin(iter.next());
289: }
290: }
291:
292: public void unpinAll(Object[] oids) {
293: unpinAll(Arrays.asList(oids));
294: }
295:
296: // IMPLEMENTATION OF THE PersistentManagerFactory INTERFACE //
297: //----------------------------------------------------------//
298:
299: /** Get an instance of PersistenceManager from this factory. The instance has
300: * default values for options.
301: * Invokes <code>init</code> at the first call.
302: *
303: * @return a PersistenceManager instance with default options.
304: */
305: public PersistenceManager getPersistenceManager() {
306: return getPersistenceManager(null);
307: }
308:
309: public void close() {
310: //TODO: implements the close method on the PMF
311: }
312:
313: /** Get an instance of PersistenceManager from this factory. The instance has
314: * default values for options. The parameters userid and password are used
315: * when obtaining datastore connections from the connection pool.
316: * Invokes <code>init</code> at the first call.
317: *
318: * @param userid the userid for the connection
319: * @param password the password for the connection
320: * @return a PersistenceManager instance with default options.
321: */
322: public PersistenceManager getPersistenceManager(String userid,
323: String password) {
324: Object cs = null;
325: if (csf == null) {
326: String cn = connectionProperties
327: .getProperty(CONNECTION_SPEC_FACTORY);
328: if (cn != null && cn.length() > 0) {
329: try {
330: csf = (ConnectionSpecFactory) Class.forName(cn)
331: .newInstance();
332: cs = csf.getConnectionSpec(this , userid, password);
333: } catch (Exception e) {
334: logger.log(BasicLevel.ERROR,
335: "Impossible to instanciate the ConnectionSpecFactory: "
336: + cn, e);
337: }
338: }
339: } else {
340: cs = csf.getConnectionSpec(this , userid, password);
341: }
342: return getPersistenceManager(cs);
343: }
344:
345: public synchronized PersistenceManager getPersistenceManager(
346: Object cs) {
347: if (!started) {
348: imbricatedAuthorized = Boolean.valueOf(
349: connectionProperties.getProperty(
350: SpeedoProperties.IMRICATED_PM_ALLOWED,
351: "false")).booleanValue();
352: start();
353: }
354: if (imbricatedAuthorized) {
355: JDOPOManagerItf pm = (JDOPOManagerItf) pms
356: .lookup(getThis());
357: if (pm != null) {
358: pm.getSemaphore().P();
359: try {
360: if ((cs == null && pm.getConnectionSpec() == null)
361: || (cs != null && cs.equals(pm
362: .getConnectionSpec()))) {
363: if (!pm.isPOMClosed()) {
364: logger
365: .log(BasicLevel.INFO,
366: "reuse the same PersistenceManager (Imbricated)");
367: pm.addUse();
368: return pm;
369: }
370: }
371: } finally {
372: pm.getSemaphore().V();
373: }
374: }
375: }
376:
377: try {
378: // Gets a PM from the pool
379: Object pr = managedPM.getResource(null);
380: logger.log(BasicLevel.DEBUG,
381: "get a persistenceManager from the pool");
382: Component ci = ((Interface) pr).getFcItfOwner();
383: JDOPOManagerItf pm = (JDOPOManagerItf) ci
384: .getFcInterface("po-manager");
385: pm.open(cs);
386: bindPM2Thread(pm);
387: pm.addUse();
388: return pm;
389: } catch (Exception e) {
390: throw new JDODataStoreException(
391: "Cannot provides a PersistenceManager ",
392: new Exception[] { e });
393: }
394: }
395:
396: public DataStoreCache getDataStoreCache() {
397: return this ;
398: }
399:
400: public boolean isClosed() {
401: //TODO: implement the isclosed method on PMF
402: return false;
403: }
404:
405: public String getMapping() {
406: return connectionProperties.getProperty(
407: SpeedoProperties.JDO_OPTION_MAPPING,
408: "no user name defined");
409: }
410:
411: public void setMapping(String arg0) {
412: connectionProperties.setProperty(
413: SpeedoProperties.JDO_OPTION_MAPPING, arg0);
414: }
415:
416: /** Set the user name for the data store connection.
417: * @param userName the user name for the data store connection.
418: */
419: public void setConnectionUserName(String userName) {
420: connectionProperties.setProperty(
421: SpeedoProperties.JDO_OPTION_CONNECTION_USER_NAME,
422: userName);
423: }
424:
425: /** Get the user name for the data store connection.
426: * @return the user name for the data store connection.
427: */
428: public String getConnectionUserName() {
429: return connectionProperties.getProperty(
430: SpeedoProperties.JDO_OPTION_CONNECTION_USER_NAME,
431: "no user name defined");
432: }
433:
434: /** Set the password for the data store connection.
435: * @param password the password for the data store connection.
436: */
437: public void setConnectionPassword(String password) {
438: connectionProperties.setProperty(
439: SpeedoProperties.JDO_OPTION_CONNECTION_PASSWORD,
440: password);
441: }
442:
443: /** Get the password for the data store connection.
444: * @return password the password for the data store connection.
445: */
446: protected String getConnectionPassword() {
447: return connectionProperties
448: .getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_PASSWORD);
449: }
450:
451: /** Set the URL for the data store connection.
452: * @param URL the URL for the data store connection.
453: */
454: public void setConnectionURL(String URL) {
455: connectionProperties.setProperty(
456: SpeedoProperties.JDO_OPTION_CONNECTION_URL, URL);
457: }
458:
459: /** Get the URL for the data store connection.
460: * @return the URL for the data store connection.
461: */
462: public String getConnectionURL() {
463: return connectionProperties
464: .getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_URL);
465: }
466:
467: /** Set the driver name for the data store connection.
468: * @param driverName the driver name for the data store connection.
469: */
470: public void setConnectionDriverName(String driverName) {
471: if (started) {
472: throw new JDOUserException(
473: "It is forbidden to modify property after a getPersistenceManager() call");
474: }
475: connectionProperties.setProperty(
476: SpeedoProperties.JDO_OPTION_CONNECTION_DRIVER_NAME,
477: driverName);
478: }
479:
480: /** Get the driver name for the data store connection.
481: * @return the driver name for the data store connection.
482: */
483: public String getConnectionDriverName() {
484: return connectionProperties
485: .getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_DRIVER_NAME);
486: }
487:
488: /** Set the name for the data store connection factory.
489: * @param connectionFactoryName the name of the data store connection factory.
490: */
491: public void setConnectionFactoryName(String connectionFactoryName) {
492: if (started) {
493: throw new JDOUserException(
494: "It is forbidden to modify property after a getPersistenceManager() call");
495: }
496: connectionProperties.setProperty(
497: SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY_NAME,
498: connectionFactoryName);
499: }
500:
501: /** Get the name for the data store connection factory.
502: * @return the name of the data store connection factory.
503: */
504: public String getConnectionFactoryName() {
505: return connectionProperties
506: .getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY_NAME);
507: }
508:
509: /** Set the data store connection factory. JDO implementations
510: * will support specific connection factories. The connection
511: * factory interfaces are not part of the JDO specification.
512: * @param connectionFactory the data store connection factory.
513: */
514: public void setConnectionFactory(Object connectionFactory) {
515: if (started) {
516: throw new JDOUserException(
517: "It is forbidden to modify property after a getPersistenceManager() call");
518: }
519: throw new JDOUnsupportedOptionException(
520: "Cannot set a Connection Factory, use <> instead");
521: }
522:
523: /** Get the data store connection factory.
524: * @return the data store connection factory.
525: */
526: public Object getConnectionFactory() {
527: return mapper.getConnectionFactory();
528: }
529:
530: /** Set the name for the second data store connection factory. This is
531: * needed for managed environments to get nontransactional connections for
532: * optimistic transactions.
533: * @param connectionFactoryName the name of the data store connection factory.
534: */
535: public void setConnectionFactory2Name(String connectionFactoryName) {
536: if (started) {
537: throw new JDOUserException(
538: "It is forbidden to modify property after a getPersistenceManager() call");
539: }
540: connectionProperties.setProperty(
541: SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY2_NAME,
542: connectionFactoryName);
543: }
544:
545: /** Get the name for the second data store connection factory. This is
546: * needed for managed environments to get nontransactional connections for
547: * optimistic transactions.
548: * @return the name of the data store connection factory.
549: */
550: public String getConnectionFactory2Name() {
551: return connectionProperties
552: .getProperty(SpeedoProperties.JDO_OPTION_CONNECTION_FACTORY2_NAME);
553: }
554:
555: /** Set the second data store connection factory. This is
556: * needed for managed environments to get nontransactional connections for
557: * optimistic transactions. JDO implementations
558: * will support specific connection factories. The connection
559: * factory interfaces are not part of the JDO specification.
560: * @param connectionfactory the data store connection factory.
561: */
562: public void setConnectionFactory2(Object connectionfactory) {
563: if (started) {
564: throw new JDOUserException(
565: "It is forbidden to modify property after a getPersistenceManager() call");
566: }
567: throw new JDOUnsupportedOptionException(
568: "Cannot set a second Connection Factory");
569: }
570:
571: /** Get the second data store connection factory. This is
572: * needed for managed environments to get nontransactional connections for
573: * optimistic transactions.
574: * @return the data store connection factory.
575: */
576: public Object getConnectionFactory2() {
577: return mapper.getConnectionFactory();
578: }
579:
580: /** Set the default Multithreaded setting for all PersistenceManager instances
581: * obtained from this factory.
582: *
583: * @param flag the default Multithreaded setting.
584: */
585: public void setMultithreaded(boolean flag) {
586: if (started) {
587: throw new JDOUserException(
588: "It is forbidden to modify property after a getPersistenceManager() call");
589: }
590: connectionProperties.setProperty(
591: SpeedoProperties.JDO_OPTION_MULTITREADED, new Boolean(
592: flag).toString());
593: }
594:
595: /** Get the default Multithreaded setting for all PersistenceManager instances
596: * obtained from this factory.
597: *
598: * @return the default Multithreaded setting.
599: */
600: public boolean getMultithreaded() {
601: return connectionProperties.getProperty(
602: SpeedoProperties.JDO_OPTION_MULTITREADED, "").equals(
603: "true");
604: }
605:
606: /** Set the default Optimistic setting for all PersistenceManager instances
607: * obtained from this factory.
608: *
609: * @param flag the default Optimistic setting.
610: */
611: public void setOptimistic(boolean flag) {
612: if (started) {
613: throw new JDOUserException(
614: "It is forbidden to modify property after a getPersistenceManager() call");
615: }
616: connectionProperties.setProperty(
617: SpeedoProperties.JDO_OPTION_OPTIMISTIC, new Boolean(
618: flag).toString());
619: }
620:
621: /** Get the default Optimistic setting for all PersistenceManager instances
622: * obtained from this factory.
623: *
624: * @return the default Optimistic setting.
625: */
626: public boolean getOptimistic() {
627: return connectionProperties.getProperty(
628: SpeedoProperties.JDO_OPTION_OPTIMISTIC, "").equals(
629: "true");
630: }
631:
632: /** Set the default RetainValues setting for all PersistenceManager instances
633: * obtained from this factory.
634: *
635: * @param flag the default RetainValues setting.
636: */
637: public void setRetainValues(boolean flag) {
638: if (started) {
639: throw new JDOUserException(
640: "It is forbidden to modify property after a getPersistenceManager() call");
641: }
642: connectionProperties.setProperty(
643: SpeedoProperties.JDO_OPTION_RETAIN_VALUES, new Boolean(
644: flag).toString());
645: }
646:
647: /** Get the default RetainValues setting for all PersistenceManager instances
648: * obtained from this factory.
649: *
650: * @return the default RetainValues setting.
651: */
652: public boolean getRetainValues() {
653: return connectionProperties.getProperty(
654: SpeedoProperties.JDO_OPTION_RETAIN_VALUES, "").equals(
655: "true");
656: }
657:
658: /** Set the default NontransactionalRead setting for all PersistenceManager instances
659: * obtained from this factory.
660: *
661: * @param flag the default NontransactionalRead setting.
662: */
663: public void setNontransactionalRead(boolean flag) {
664: if (started) {
665: throw new JDOUserException(
666: "It is forbidden to modify property after a getPersistenceManager() call");
667: }
668: connectionProperties.setProperty(
669: SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_READ,
670: new Boolean(flag).toString());
671: }
672:
673: /** Get the default NontransactionalRead setting for all PersistenceManager instances
674: * obtained from this factory.
675: *
676: * @return the default NontransactionalRead setting.
677: */
678: public boolean getNontransactionalRead() {
679: return connectionProperties.getProperty(
680: SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_READ)
681: .equals("true");
682: }
683:
684: /** Set the default NontransactionalWrite setting for all PersistenceManager instances
685: * obtained from this factory.
686: *
687: * @param flag the default NontransactionalWrite setting.
688: */
689: public void setNontransactionalWrite(boolean flag) {
690: if (started) {
691: throw new JDOUserException(
692: "It is forbidden to modify property after a getPersistenceManager() call");
693: }
694: connectionProperties.setProperty(
695: SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_WRITE,
696: new Boolean(flag).toString());
697: }
698:
699: /** Get the default NontransactionalWrite setting for all PersistenceManager instances
700: * obtained from this factory.
701: *
702: * @return the default NontransactionalWrite setting.
703: */
704: public boolean getNontransactionalWrite() {
705: return connectionProperties.getProperty(
706: SpeedoProperties.JDO_OPTION_NON_TRANSACTIONAL_WRITE)
707: .equals("true");
708: }
709:
710: /** Set the default IgnoreCache setting for all PersistenceManager instances
711: * obtained from this factory.
712: *
713: * @param flag the default IgnoreCache setting.
714: */
715: public void setIgnoreCache(boolean flag) {
716: if (started) {
717: throw new JDOUserException(
718: "It is forbidden to modify property after a getPersistenceManager() call");
719: }
720: connectionProperties.setProperty(
721: SpeedoProperties.JDO_OPTION_IGNORE_CACHE, new Boolean(
722: flag).toString());
723: }
724:
725: /** Get the default IgnoreCache setting for all PersistenceManager instances
726: * obtained from this factory.
727: *
728: * @return the default IngoreCache setting.
729: */
730: public boolean getIgnoreCache() {
731: return "true".equalsIgnoreCase(connectionProperties
732: .getProperty(SpeedoProperties.JDO_OPTION_IGNORE_CACHE));
733: }
734:
735: /** Get the MaxPool setting for the PersistenceManager
736: * pool for this factory.
737: * @return the MaxPool setting.
738: */
739: public int getMaxPool() {
740: String v = connectionProperties
741: .getProperty(SpeedoProperties.PM_POOL_MAX);
742: if (v != null && v.length() > 0) {
743: return Integer.parseInt(v);
744: } else {
745: return GETMAXPOOL;
746: }
747: }
748:
749: /** Set the MaxPool setting for the PersistenceManager
750: * pool for this factory.
751: * @param maxPool the MaxPool setting.
752: */
753: public void setMaxPool(int maxPool) {
754: if (started) {
755: throw new JDOUserException(
756: "It is forbidden to modify property after a getPersistenceManager() call");
757: }
758: connectionProperties.setProperty(SpeedoProperties.PM_POOL_MAX,
759: Integer.toString(maxPool));
760: }
761:
762: /** Get the MinPool setting for the PersistenceManager
763: * pool for this factory.
764: * @return the MinPool setting.
765: */
766: public int getMinPool() {
767: return Integer.parseInt(connectionProperties
768: .getProperty(SpeedoProperties.PM_POOL_MIN));
769: }
770:
771: /** Set the MinPool setting for the PersistenceManager
772: * pool for this factory.
773: * @param minPool the MinPool setting.
774: */
775: public void setMinPool(int minPool) {
776: if (started) {
777: throw new JDOUserException(
778: "It is forbidden to modify property after a getPersistenceManager() call");
779: }
780: connectionProperties.setProperty(SpeedoProperties.PM_POOL_MIN,
781: Integer.toString(minPool));
782: }
783:
784: /** Get the MsWait setting for the PersistenceManager
785: * pool for this factory.
786: * @return the MsWait setting.
787: */
788: public int getMsWait() {
789: return Integer.parseInt(connectionProperties
790: .getProperty(SpeedoProperties.PM_POOL_TIMEOUT));
791: }
792:
793: /** Set the MsWait setting for the PersistenceManager
794: * pool for this factory.
795: * @param msWait the MsWait setting.
796: */
797: public void setMsWait(int msWait) {
798: if (started) {
799: throw new JDOUserException(
800: "It is forbidden to modify property after a getPersistenceManager() call");
801: }
802: connectionProperties.setProperty(
803: SpeedoProperties.PM_POOL_TIMEOUT, Integer
804: .toString(msWait));
805: }
806:
807: /** The application can determine from the results of this
808: * method which optional features, and which query languages
809: * are supported by the JDO implementation.
810: * <P>Each supported JDO optional feature is represented by a
811: * String with one of the following values:
812: *
813: * <P>javax.jdo.option.TransientTransactional
814: * <P>javax.jdo.option.NontransactionalRead
815: * <P>javax.jdo.option.NontransactionalWrite
816: * <P>javax.jdo.option.RetainValues
817: * <P>javax.jdo.option.Optimistic
818: * <P>javax.jdo.option.ApplicationIdentity
819: * <P>javax.jdo.option.DatastoreIdentity
820: * <P>javax.jdo.option.NonDatastoreIdentity
821: * <P>javax.jdo.option.ArrayList
822: * <P>javax.jdo.option.HashMap
823: * <P>javax.jdo.option.Hashtable
824: * <P>javax.jdo.option.LinkedList
825: * <P>javax.jdo.option.TreeMap
826: * <P>javax.jdo.option.TreeSet
827: * <P>javax.jdo.option.Vector
828: * <P>javax.jdo.option.Map
829: * <P>javax.jdo.option.List
830: * <P>javax.jdo.option.Array
831: * <P>javax.jdo.option.NullCollection
832: *
833: *<P>The standard JDO query language is represented by a String:
834: *<P>javax.jdo.query.JDOQL
835: * @return the List of String representing the supported Options
836: */
837: public Collection supportedOptions() {
838: return Collections.unmodifiableList(Arrays.asList(optionArray));
839: }
840:
841: public void setRestoreValues(boolean b) {
842: }
843:
844: public boolean getRestoreValues() {
845: return false;
846: }
847:
848: private Map class2listeners;
849: private Map listener2classes;
850:
851: public synchronized void addInstanceLifecycleListener(
852: InstanceLifecycleListener l, Class[] classes) {
853: //Register the listener
854: if (class2listeners == null) {
855: class2listeners = new HashMap();
856: listener2classes = new HashMap();
857: }
858: List classesCol = (List) listener2classes.get(l);
859: if (classesCol == null) {
860: classesCol = new ArrayList();
861: listener2classes.put(l, classesCol);
862: }
863: classesCol.addAll(Arrays.asList(classes));
864:
865: for (int i = 0; i < classes.length; i++) {
866: List listenersCol = (List) class2listeners.get(classes[i]);
867: if (listenersCol == null) {
868: listenersCol = new ArrayList();
869: class2listeners.put(classes[i], listenersCol);
870: }
871: listenersCol.add(l);
872: HomeItf sh = null;
873: try {
874: sh = (HomeItf) jormFactory.getPClassMapping(classes[i]);
875: } catch (PException e) {
876: }
877: if (sh == null) {
878: logger
879: .log(
880: BasicLevel.WARN,
881: "Class '"
882: + classes[i].getName()
883: + "' is not recongnized as a persistent class. The listener will not receiver event, but it is registerd.");
884: } else {
885: sh.addInstanceLifeCycleListener(l);
886: }
887: }
888: }
889:
890: public synchronized void removeInstanceLifecycleListener(
891: InstanceLifecycleListener l) {
892: List classes = (List) listener2classes.remove(l);
893: if (classes != null) {
894: for (Iterator iter = classes.iterator(); iter.hasNext();) {
895: Class clazz = (Class) iter.next();
896: List listenersCol = (List) class2listeners.get(clazz);
897: if (listenersCol != null) {
898: if (listenersCol.remove(l)) {
899: HomeItf sh = null;
900: try {
901: sh = (HomeItf) jormFactory
902: .getPClassMapping(clazz);
903: } catch (PException e) {
904: }
905: if (sh != null) {
906: sh.removeInstanceLifeCycleListener(l);
907: }
908:
909: }
910: }
911: }
912: }
913: }
914:
915: /* (non-Javadoc)
916: * @see javax.jdo.PersistenceManagerFactory#getDetachAllOnCommit()
917: */
918: public boolean getDetachAllOnCommit() {
919: // TODO Auto-generated method stub
920: return false;
921: }
922:
923: /* (non-Javadoc)
924: * @see javax.jdo.PersistenceManagerFactory#setDetachAllOnCommit(boolean)
925: */
926: public void setDetachAllOnCommit(boolean arg0) {
927: // TODO Auto-generated method stub
928:
929: }
930: }
|