0001: /*
0002: * Copyright 2004 (C) TJDO.
0003: * All rights reserved.
0004: *
0005: * This software is distributed under the terms of the TJDO License version 1.0.
0006: * See the terms of the TJDO License in the documentation provided with this software.
0007: *
0008: * $Id: PersistenceManagerFactoryImpl.java,v 1.13 2004/01/25 22:30:38 jackknifebarber Exp $
0009: */
0010:
0011: package com.triactive.jdo;
0012:
0013: import java.sql.Connection;
0014: import java.util.ArrayList;
0015: import java.util.Arrays;
0016: import java.util.Collection;
0017: import java.util.Collections;
0018: import java.util.Enumeration;
0019: import java.util.HashMap;
0020: import java.util.HashSet;
0021: import java.util.Iterator;
0022: import java.util.List;
0023: import java.util.Map;
0024: import java.util.Properties;
0025: import java.util.Set;
0026: import javax.jdo.JDOUnsupportedOptionException;
0027: import javax.jdo.JDOUserException;
0028: import javax.jdo.PersistenceManager;
0029: import javax.jdo.PersistenceManagerFactory;
0030: import javax.jdo.spi.JDOPermission;
0031: import javax.naming.InitialContext;
0032: import javax.naming.NamingException;
0033: import javax.sql.DataSource;
0034: import org.apache.log4j.Category;
0035:
0036: /**
0037: * A factory used to obtain {@link javax.jdo.PersistenceManager} instances.
0038: *
0039: * @author <a href="mailto:mmartin5@austin.rr.com">Mike Martin</a>
0040: * @version $Revision: 1.13 $
0041: */
0042:
0043: public class PersistenceManagerFactoryImpl implements
0044: PersistenceManagerFactory {
0045: private static final Category LOG = Category
0046: .getInstance(PersistenceManagerFactoryImpl.class);
0047:
0048: /**
0049: * The system property that selects the default value for the
0050: * ValidateTables setting. This is the string
0051: * "com.triactive.jdo.validateTables".
0052: */
0053: public static final String VALIDATE_TABLES_PROPERTY = "com.triactive.jdo.validateTables";
0054:
0055: /**
0056: * The system property that selects the default value for the
0057: * ValidateConstraints setting. This is the string
0058: * "com.triactive.jdo.validateConstraints".
0059: */
0060: public static final String VALIDATE_CONSTRAINTS_PROPERTY = "com.triactive.jdo.validateConstraints";
0061:
0062: /**
0063: * The system property that selects the default value for the
0064: * AutoCreateTables setting. This is the string
0065: * "com.triactive.jdo.autoCreateTables".
0066: */
0067: public static final String AUTO_CREATE_TABLES_PROPERTY = "com.triactive.jdo.autoCreateTables";
0068:
0069: /**
0070: * The system property that selects the default value for the
0071: * transaction isolation level. This is the string
0072: * "com.triactive.jdo.transactionIsolation".
0073: */
0074: public static final String TRANSACTION_ISOLATION_PROPERTY = "com.triactive.jdo.transactionIsolation";
0075:
0076: /**
0077: * This is an interface that allows setting properties on a PersistenceManagerFactory
0078: * with Strings.
0079: */
0080: public interface PropertySetter {
0081: /**
0082: * Set this property on the given PersistenceManagerFactoryImpl to the String value.
0083: * @param pmf The PersistenceManagerFactoryImpl to set the value on.
0084: * @param value The String value to set.
0085: */
0086: public void set(PersistenceManagerFactoryImpl pmf, String value);
0087: }
0088:
0089: /**
0090: * A Map mapping property name to the corresponding PropertySetter.
0091: */
0092: private static final Map PROPERTY_SETTERS = initPropertySetters();
0093:
0094: private String driverName = null;
0095: private String URL = null;
0096: private String userName = null;
0097: private String password = null;
0098:
0099: private Object connectionFactory = null;
0100: private String connectionFactoryName = null;
0101:
0102: private Object connectionFactory2 = null;
0103: private String connectionFactory2Name = null;
0104:
0105: private boolean multithreaded = false;
0106: private boolean optimistic = false;
0107: private boolean retainValues = false;
0108: private boolean restoreValues = false;
0109: private boolean nontransactionalRead = false;
0110: private boolean nontransactionalWrite = false;
0111: private boolean ignoreCache = false;
0112: private boolean validateTables = new Boolean(System.getProperty(
0113: VALIDATE_TABLES_PROPERTY, "true")).booleanValue();
0114: private boolean validateConstraints = new Boolean(System
0115: .getProperty(VALIDATE_CONSTRAINTS_PROPERTY, "true"))
0116: .booleanValue();
0117: private boolean autoCreateTables = new Boolean(System.getProperty(
0118: AUTO_CREATE_TABLES_PROPERTY, "false")).booleanValue();
0119: private int isolationLevel = Connection.TRANSACTION_SERIALIZABLE;
0120:
0121: private int minPool = 3;
0122: private int maxPool = 100;
0123: private int msWait = 30000;
0124:
0125: /**
0126: * Once false, attempts to change properties above will fail (see
0127: * assertConfigurable).
0128: */
0129: private transient boolean configurable = true;
0130: private transient DataSource tds = null;
0131: private transient DataSource ntds = null;
0132:
0133: /**
0134: * The set of PMs returned by this PMF that are still open. null if the
0135: * PMF has been closed.
0136: */
0137: private transient Set openPMs = new HashSet();
0138:
0139: /**
0140: * Constructs a new PersistenceManagerFactoryImpl.
0141: */
0142:
0143: public PersistenceManagerFactoryImpl() {
0144: String tip = System.getProperty(TRANSACTION_ISOLATION_PROPERTY);
0145:
0146: if (tip != null) {
0147: try {
0148: setTransactionIsolation(tip);
0149: } catch (IllegalArgumentException e) {
0150: LOG
0151: .warn("Invalid transaction isolation property ignored: "
0152: + TRANSACTION_ISOLATION_PROPERTY
0153: + "="
0154: + tip);
0155: }
0156: }
0157: }
0158:
0159: /**
0160: * Return a new PersistenceManagerFactoryImpl with options set according
0161: * to the given Properties.
0162: * @param props The Properties to initialize the PersistenceManagerFactory with.
0163: * @return A PersistenceManagerFactoryImpl with options set according to the
0164: * given Properties.
0165: * @see javax.jdo.JDOHelper#getPersistenceManagerFactory(java.util.Properties)
0166: */
0167: public synchronized static PersistenceManagerFactory getPersistenceManagerFactory(
0168: Properties props) {
0169: PersistenceManagerFactoryImpl pmf = new PersistenceManagerFactoryImpl();
0170:
0171: // Read properties.
0172: pmf.setOptions(props);
0173:
0174: return pmf;
0175: }
0176:
0177: public synchronized void close() {
0178: if (openPMs == null)
0179: return;
0180:
0181: SecurityManager secmgr = System.getSecurityManager();
0182: if (secmgr != null)
0183: secmgr
0184: .checkPermission(JDOPermission.CLOSE_PERSISTENCE_MANAGER_FACTORY);
0185:
0186: List nestedEx = new ArrayList();
0187: Iterator i = openPMs.iterator();
0188:
0189: while (i.hasNext()) {
0190: PersistenceManager pm = (PersistenceManager) i.next();
0191:
0192: if (pm.currentTransaction().isActive())
0193: nestedEx.add(new JDOUserException(
0194: "PersistenceManager has an active transaction",
0195: pm));
0196: }
0197:
0198: if (!nestedEx.isEmpty()) {
0199: Throwable[] nested = (Throwable[]) nestedEx
0200: .toArray(new Throwable[nestedEx.size()]);
0201: throw new JDOUserException(
0202: "One or more PersistenceManagers have an active transaction",
0203: nested);
0204: }
0205:
0206: i = openPMs.iterator();
0207:
0208: while (i.hasNext())
0209: ((PersistenceManagerImpl) i.next()).forceClose();
0210:
0211: configurable = false;
0212: openPMs = null;
0213: }
0214:
0215: public synchronized boolean equals(Object obj) {
0216: if (obj == this )
0217: return true;
0218:
0219: if (!(obj instanceof PersistenceManagerFactoryImpl))
0220: return false;
0221:
0222: PersistenceManagerFactoryImpl pmf = (PersistenceManagerFactoryImpl) obj;
0223:
0224: if (driverName == null) {
0225: if (pmf.driverName != null)
0226: return false;
0227: } else if (!driverName.equals(pmf.driverName))
0228: return false;
0229:
0230: if (URL == null) {
0231: if (pmf.URL != null)
0232: return false;
0233: } else if (!URL.equals(pmf.URL))
0234: return false;
0235:
0236: if (userName == null) {
0237: if (pmf.userName != null)
0238: return false;
0239: } else if (!userName.equals(pmf.userName))
0240: return false;
0241:
0242: if (password == null) {
0243: if (pmf.password != null)
0244: return false;
0245: } else if (!password.equals(pmf.password))
0246: return false;
0247:
0248: if (connectionFactory == null) {
0249: if (pmf.connectionFactory != null)
0250: return false;
0251: } else if (!connectionFactory.equals(pmf.connectionFactory))
0252: return false;
0253:
0254: if (connectionFactoryName == null) {
0255: if (pmf.connectionFactoryName != null)
0256: return false;
0257: } else if (!connectionFactoryName
0258: .equals(pmf.connectionFactoryName))
0259: return false;
0260:
0261: if (connectionFactory2 == null) {
0262: if (pmf.connectionFactory2 != null)
0263: return false;
0264: } else if (!connectionFactory2.equals(pmf.connectionFactory2))
0265: return false;
0266:
0267: if (connectionFactory2Name == null) {
0268: if (pmf.connectionFactory2Name != null)
0269: return false;
0270: } else if (!connectionFactory2Name
0271: .equals(pmf.connectionFactory2Name))
0272: return false;
0273:
0274: return multithreaded == pmf.multithreaded
0275: && optimistic == pmf.optimistic
0276: && retainValues == pmf.retainValues
0277: && restoreValues == pmf.restoreValues
0278: && nontransactionalRead == pmf.nontransactionalRead
0279: && nontransactionalWrite == pmf.nontransactionalWrite
0280: && ignoreCache == pmf.ignoreCache
0281: && validateTables == pmf.validateTables
0282: && validateConstraints == pmf.validateConstraints
0283: && autoCreateTables == pmf.autoCreateTables
0284: && minPool == pmf.minPool && maxPool == pmf.maxPool
0285: && msWait == pmf.msWait;
0286: }
0287:
0288: public synchronized int hashCode() {
0289: return (driverName == null ? 0 : driverName.hashCode())
0290: ^ (URL == null ? 0 : URL.hashCode())
0291: ^ (userName == null ? 0 : userName.hashCode())
0292: ^ (password == null ? 0 : password.hashCode())
0293: ^ (connectionFactory == null ? 0 : connectionFactory
0294: .hashCode())
0295: ^ (connectionFactoryName == null ? 0
0296: : connectionFactoryName.hashCode())
0297: ^ (connectionFactory2 == null ? 0 : connectionFactory2
0298: .hashCode())
0299: ^ (connectionFactory2Name == null ? 0
0300: : connectionFactory2Name.hashCode())
0301: ^ (multithreaded ? 1 : 0) ^ (optimistic ? 1 : 0)
0302: ^ (retainValues ? 1 : 0) ^ (restoreValues ? 1 : 0)
0303: ^ (nontransactionalRead ? 1 : 0)
0304: ^ (nontransactionalWrite ? 1 : 0)
0305: ^ (ignoreCache ? 1 : 0) ^ (validateTables ? 1 : 0)
0306: ^ (validateConstraints ? 1 : 0)
0307: ^ (autoCreateTables ? 1 : 0) ^ minPool ^ maxPool
0308: ^ msWait;
0309: }
0310:
0311: /**
0312: * Initialize the PROPERTY_SETTERS Map.
0313: * @return The PROPERTY_SETTERS Map.
0314: */
0315: private static final Map initPropertySetters() {
0316: final Map map = new HashMap();
0317: map.put("javax.jdo.option.Optimistic", new PropertySetter() {
0318: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0319: pmf.setOptimistic(Boolean.valueOf(s).booleanValue());
0320: }
0321: });
0322: map.put("javax.jdo.option.RetainValues", new PropertySetter() {
0323: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0324: pmf.setRetainValues(Boolean.valueOf(s).booleanValue());
0325: }
0326: });
0327: map.put("javax.jdo.option.RestoreValues", new PropertySetter() {
0328: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0329: pmf.setRestoreValues(Boolean.valueOf(s).booleanValue());
0330: }
0331: });
0332: map.put("javax.jdo.option.IgnoreCache", new PropertySetter() {
0333: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0334: pmf.setIgnoreCache(Boolean.valueOf(s).booleanValue());
0335: }
0336: });
0337: map.put("javax.jdo.option.NontransactionalRead",
0338: new PropertySetter() {
0339: public void set(PersistenceManagerFactoryImpl pmf,
0340: String s) {
0341: pmf.setNontransactionalRead(Boolean.valueOf(s)
0342: .booleanValue());
0343: }
0344: });
0345: map.put("javax.jdo.option.NontransactionalWrite",
0346: new PropertySetter() {
0347: public void set(PersistenceManagerFactoryImpl pmf,
0348: String s) {
0349: pmf.setNontransactionalWrite(Boolean.valueOf(s)
0350: .booleanValue());
0351: }
0352: });
0353: map.put("javax.jdo.option.Multithreaded", new PropertySetter() {
0354: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0355: pmf.setMultithreaded(Boolean.valueOf(s).booleanValue());
0356: }
0357: });
0358: map.put("javax.jdo.option.ConnectionUserName",
0359: new PropertySetter() {
0360: public void set(PersistenceManagerFactoryImpl pmf,
0361: String s) {
0362: pmf.setConnectionUserName(s);
0363: }
0364: });
0365: map.put("javax.jdo.option.ConnectionPassword",
0366: new PropertySetter() {
0367: public void set(PersistenceManagerFactoryImpl pmf,
0368: String s) {
0369: pmf.setConnectionPassword(s);
0370: }
0371: });
0372: map.put("javax.jdo.option.ConnectionDriverName",
0373: new PropertySetter() {
0374: public void set(PersistenceManagerFactoryImpl pmf,
0375: String s) {
0376: pmf.setConnectionDriverName(s);
0377: }
0378: });
0379: map.put("javax.jdo.option.ConnectionURL", new PropertySetter() {
0380: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0381: pmf.setConnectionURL(s);
0382: }
0383: });
0384: map.put("javax.jdo.option.ConnectionFactoryName",
0385: new PropertySetter() {
0386: public void set(PersistenceManagerFactoryImpl pmf,
0387: String s) {
0388: pmf.setConnectionFactoryName(s);
0389: }
0390: });
0391: map.put("javax.jdo.option.ConnectionFactory2Name",
0392: new PropertySetter() {
0393: public void set(PersistenceManagerFactoryImpl pmf,
0394: String s) {
0395: pmf.setConnectionFactory2Name(s);
0396: }
0397: });
0398: map.put(VALIDATE_TABLES_PROPERTY, new PropertySetter() {
0399: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0400: pmf
0401: .setValidateTables(Boolean.valueOf(s)
0402: .booleanValue());
0403: }
0404: });
0405: map.put(VALIDATE_CONSTRAINTS_PROPERTY, new PropertySetter() {
0406: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0407: pmf.setValidateConstraints(Boolean.valueOf(s)
0408: .booleanValue());
0409: }
0410: });
0411: map.put(AUTO_CREATE_TABLES_PROPERTY, new PropertySetter() {
0412: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0413: pmf.setAutoCreateTables(Boolean.valueOf(s)
0414: .booleanValue());
0415: }
0416: });
0417: map.put(TRANSACTION_ISOLATION_PROPERTY, new PropertySetter() {
0418: public void set(PersistenceManagerFactoryImpl pmf, String s) {
0419: pmf.setTransactionIsolation(s);
0420: }
0421: });
0422: return map;
0423: }
0424:
0425: /**
0426: * Asserts that a change to a configuration property is allowed.
0427: */
0428:
0429: private void assertConfigurable() {
0430: if (!configurable)
0431: throw new JDOUserException(
0432: "Configuration changes not allowed after PersistenceManagers have been generated");
0433: }
0434:
0435: /**
0436: * Asserts that the PMF is still open.
0437: */
0438:
0439: private void assertNotClosed() {
0440: if (openPMs == null)
0441: throw new JDOUserException(
0442: "PersistenceManagerFactory has been closed");
0443: }
0444:
0445: /**
0446: * Looks up a DataSource object in JNDI.
0447: *
0448: * @param name The JNDI name of the DataSource.
0449: *
0450: * @return The DataSource object.
0451: *
0452: * @exception ConnectionFactoryNotFoundException
0453: * If a JNDI lookup failure occurs.
0454: * @exception UnsupportedConnectionFactoryException
0455: * If the object is not a javax.sql.DataSource.
0456: */
0457:
0458: private DataSource lookupDataSource(String name) {
0459: Object obj;
0460:
0461: try {
0462: obj = new InitialContext().lookup(name);
0463: } catch (NamingException e) {
0464: throw new ConnectionFactoryNotFoundException(name, e);
0465: }
0466:
0467: if (!(obj instanceof DataSource))
0468: throw new UnsupportedConnectionFactoryException(obj);
0469:
0470: return (DataSource) obj;
0471: }
0472:
0473: /**
0474: * Freezes the current configuration.
0475: *
0476: * @exception UnsupportedConnectionFactoryException
0477: * If the configured connection factory is not a javax.sql.DataSource.
0478: */
0479:
0480: private void freezeConfiguration() {
0481: if (configurable) {
0482: if (connectionFactory != null) {
0483: if (!(connectionFactory instanceof DataSource))
0484: throw new UnsupportedConnectionFactoryException(
0485: connectionFactory);
0486:
0487: tds = (DataSource) connectionFactory;
0488: } else if (connectionFactoryName != null)
0489: tds = lookupDataSource(connectionFactoryName);
0490: else
0491: tds = new DriverManagerDataSource(driverName, URL);
0492:
0493: if (connectionFactory2 != null) {
0494: if (!(connectionFactory2 instanceof DataSource))
0495: throw new UnsupportedConnectionFactoryException(
0496: connectionFactory2);
0497:
0498: ntds = (DataSource) connectionFactory2;
0499: } else if (connectionFactory2Name != null)
0500: ntds = lookupDataSource(connectionFactory2Name);
0501: else
0502: ntds = tds;
0503:
0504: configurable = false;
0505: }
0506: }
0507:
0508: /**
0509: * Set the options for this PersistenceManagerFactory based on the given Properties.
0510: * @param prop The Properties to set the options from.
0511: */
0512: private void setOptions(Properties props) {
0513: for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
0514: String prop = (String) e.nextElement();
0515:
0516: PropertySetter setter = (PropertySetter) PROPERTY_SETTERS
0517: .get(prop);
0518: if (null != prop && null != setter) {
0519: String value = props.getProperty(prop);
0520: setter.set(this , value);
0521: }
0522: }
0523: }
0524:
0525: /**
0526: * Returns the data source to be used for transactional access.
0527: *
0528: * @return The data source to be used for transactional access.
0529: */
0530:
0531: public synchronized DataSource getTransactionalDataSource() {
0532: freezeConfiguration();
0533:
0534: return tds;
0535: }
0536:
0537: /**
0538: * Returns the data source to be used for non-transactional access.
0539: *
0540: * @return The data source to be used for non-transactional access.
0541: */
0542:
0543: public synchronized DataSource getNontransactionalDataSource() {
0544: freezeConfiguration();
0545:
0546: return ntds;
0547: }
0548:
0549: /**
0550: * Get an instance of <tt>PersistenceManager</tt> from this factory. The
0551: * instance has default values for options.
0552: *
0553: * <p>After the first use of getPersistenceManager, no "set" methods will
0554: * succeed.
0555: *
0556: * @return a <tt>PersistenceManager</tt> instance with default options.
0557: */
0558:
0559: public synchronized PersistenceManager getPersistenceManager() {
0560: return getPersistenceManager(userName, password);
0561: }
0562:
0563: /**
0564: * Get an instance of <tt>PersistenceManager</tt> from this factory. The
0565: * instance has default values for options. The parameters userid and
0566: * password are used when obtaining datastore connections from the
0567: * connection pool.
0568: *
0569: * <p>After the first use of getPersistenceManager, no "set" methods will
0570: * succeed.
0571: *
0572: * @param userName the user name for the connection
0573: * @param password the password for the connection
0574: *
0575: * @return a <tt>PersistenceManager</tt> instance with default options.
0576: */
0577:
0578: public synchronized PersistenceManager getPersistenceManager(
0579: String userName, String password) {
0580: assertNotClosed();
0581: freezeConfiguration();
0582:
0583: PersistenceManagerImpl pm = new PersistenceManagerImpl(this ,
0584: userName, password);
0585:
0586: openPMs.add(pm);
0587:
0588: return pm;
0589: }
0590:
0591: synchronized void pmClosed(PersistenceManagerImpl pm) {
0592: if (openPMs != null)
0593: openPMs.remove(pm);
0594: }
0595:
0596: /**
0597: * Set the user name for the data store connection.
0598: * @param userName the user name for the data store connection.
0599: */
0600:
0601: public synchronized void setConnectionUserName(String userName) {
0602: assertConfigurable();
0603: this .userName = userName;
0604: }
0605:
0606: /**
0607: * Get the user name for the data store connection.
0608: * @return the user name for the data store connection.
0609: */
0610:
0611: public String getConnectionUserName() {
0612: return userName;
0613: }
0614:
0615: /**
0616: * Set the password for the data store connection.
0617: * @param password the password for the data store connection.
0618: */
0619:
0620: public synchronized void setConnectionPassword(String password) {
0621: assertConfigurable();
0622: this .password = password;
0623: }
0624:
0625: /**
0626: * Set the URL for the data store connection.
0627: * @param URL the URL for the data store connection.
0628: */
0629:
0630: public synchronized void setConnectionURL(String URL) {
0631: assertConfigurable();
0632: this .URL = URL;
0633: }
0634:
0635: /**
0636: * Get the URL for the data store connection.
0637: * @return the URL for the data store connection.
0638: */
0639:
0640: public String getConnectionURL() {
0641: return URL;
0642: }
0643:
0644: /**
0645: * Set the driver name for the data store connection.
0646: * @param driverName the driver name for the data store connection.
0647: */
0648:
0649: public synchronized void setConnectionDriverName(String driverName) {
0650: assertConfigurable();
0651: this .driverName = driverName;
0652: }
0653:
0654: /**
0655: * Get the driver name for the data store connection.
0656: * @return the driver name for the data store connection.
0657: */
0658:
0659: public String getConnectionDriverName() {
0660: return driverName;
0661: }
0662:
0663: /**
0664: * Set the name for the data store connection factory.
0665: * @param connectionFactoryName the name of the data store connection factory.
0666: */
0667:
0668: public synchronized void setConnectionFactoryName(
0669: String connectionFactoryName) {
0670: assertConfigurable();
0671: this .connectionFactoryName = connectionFactoryName;
0672: }
0673:
0674: /**
0675: * Get the name for the data store connection factory.
0676: * @return the name of the data store connection factory.
0677: */
0678:
0679: public String getConnectionFactoryName() {
0680: return connectionFactoryName;
0681: }
0682:
0683: /**
0684: * Set the data store connection factory. JDO implementations
0685: * will support specific connection factories. The connection
0686: * factory interfaces are not part of the JDO specification.
0687: * @param connectionFactory the data store connection factory.
0688: */
0689:
0690: public synchronized void setConnectionFactory(
0691: Object connectionFactory) {
0692: assertConfigurable();
0693: this .connectionFactory = connectionFactory;
0694: }
0695:
0696: /**
0697: * Get the data store connection factory.
0698: * @return the data store connection factory.
0699: */
0700:
0701: public Object getConnectionFactory() {
0702: return connectionFactory;
0703: }
0704:
0705: /**
0706: * Set the name for the second data store connection factory. This is
0707: * needed for managed environments to get nontransactional connections for
0708: * optimistic transactions.
0709: * @param connectionFactory2Name the name of the data store connection factory.
0710: */
0711:
0712: public synchronized void setConnectionFactory2Name(
0713: String connectionFactory2Name) {
0714: assertConfigurable();
0715: this .connectionFactory2Name = connectionFactory2Name;
0716: }
0717:
0718: /**
0719: * Get the name for the second data store connection factory. This is
0720: * needed for managed environments to get nontransactional connections for
0721: * optimistic transactions.
0722: * @return the name of the data store connection factory.
0723: */
0724:
0725: public String getConnectionFactory2Name() {
0726: return connectionFactory2Name;
0727: }
0728:
0729: /**
0730: * Set the second data store connection factory. This is
0731: * needed for managed environments to get nontransactional connections for
0732: * optimistic transactions. JDO implementations
0733: * will support specific connection factories. The connection
0734: * factory interfaces are not part of the JDO specification.
0735: * @param connectionFactory2 the data store connection factory.
0736: */
0737:
0738: public synchronized void setConnectionFactory2(
0739: Object connectionFactory2) {
0740: assertConfigurable();
0741: this .connectionFactory2 = connectionFactory2;
0742: }
0743:
0744: /**
0745: * Get the second data store connection factory. This is
0746: * needed for managed environments to get nontransactional connections for
0747: * optimistic transactions.
0748: * @return the data store connection factory.
0749: */
0750:
0751: public Object getConnectionFactory2() {
0752: return connectionFactory2;
0753: }
0754:
0755: /**
0756: * Set the default Multithreaded setting for all <tt>PersistenceManager</tt> instances
0757: * obtained from this factory.
0758: *
0759: * @param flag the default Multithreaded setting.
0760: */
0761:
0762: public synchronized void setMultithreaded(boolean flag) {
0763: assertConfigurable();
0764:
0765: multithreaded = flag;
0766: }
0767:
0768: /**
0769: * Get the default Multithreaded setting for all <tt>PersistenceManager</tt> instances
0770: * obtained from this factory.
0771: *
0772: * @return the default Multithreaded setting.
0773: */
0774:
0775: public boolean getMultithreaded() {
0776: return multithreaded;
0777: }
0778:
0779: /**
0780: * Set the default Optimistic setting for all <tt>PersistenceManager</tt> instances
0781: * obtained from this factory.
0782: *
0783: * @param flag the default Optimistic setting.
0784: */
0785:
0786: public synchronized void setOptimistic(boolean flag) {
0787: assertConfigurable();
0788:
0789: optimistic = flag;
0790:
0791: if (flag)
0792: nontransactionalRead = flag;
0793: }
0794:
0795: /**
0796: * Get the default Optimistic setting for all <tt>PersistenceManager</tt> instances
0797: * obtained from this factory.
0798: *
0799: * @return the default Optimistic setting.
0800: */
0801:
0802: public boolean getOptimistic() {
0803: return optimistic;
0804: }
0805:
0806: /**
0807: * Set the default RetainValues setting for all <tt>PersistenceManager</tt> instances
0808: * obtained from this factory.
0809: *
0810: * @param flag the default RetainValues setting.
0811: */
0812:
0813: public synchronized void setRetainValues(boolean flag) {
0814: assertConfigurable();
0815: retainValues = flag;
0816:
0817: if (flag)
0818: nontransactionalRead = flag;
0819: }
0820:
0821: /**
0822: * Get the default RetainValues setting for all <tt>PersistenceManager</tt> instances
0823: * obtained from this factory.
0824: *
0825: * @return the default RetainValues setting.
0826: */
0827:
0828: public boolean getRetainValues() {
0829: return retainValues;
0830: }
0831:
0832: /**
0833: * Set the default RestoreValues setting for all <tt>PersistenceManager</tt> instances
0834: * obtained from this factory.
0835: *
0836: * @param flag the default RestoreValues setting.
0837: */
0838:
0839: public synchronized void setRestoreValues(boolean flag) {
0840: assertConfigurable();
0841: restoreValues = flag;
0842: }
0843:
0844: /**
0845: * Get the default RestoreValues setting for all <tt>PersistenceManager</tt> instances
0846: * obtained from this factory.
0847: *
0848: * @return the default RestoreValues setting.
0849: */
0850:
0851: public boolean getRestoreValues() {
0852: return restoreValues;
0853: }
0854:
0855: /**
0856: * Set the default NontransactionalRead setting for all <tt>PersistenceManager</tt> instances
0857: * obtained from this factory.
0858: *
0859: * @param flag the default NontransactionalRead setting.
0860: */
0861:
0862: public synchronized void setNontransactionalRead(boolean flag) {
0863: assertConfigurable();
0864: nontransactionalRead = flag;
0865: }
0866:
0867: /**
0868: * Get the default NontransactionalRead setting for all <tt>PersistenceManager</tt> instances
0869: * obtained from this factory.
0870: *
0871: * @return the default NontransactionalRead setting.
0872: */
0873:
0874: public boolean getNontransactionalRead() {
0875: return nontransactionalRead;
0876: }
0877:
0878: /**
0879: * Set the default NontransactionalWrite setting for all <tt>PersistenceManager</tt> instances
0880: * obtained from this factory.
0881: *
0882: * @param flag the default NontransactionalWrite setting.
0883: */
0884:
0885: public synchronized void setNontransactionalWrite(boolean flag) {
0886: assertConfigurable();
0887: nontransactionalWrite = flag;
0888: }
0889:
0890: /**
0891: * Get the default NontransactionalWrite setting for all <tt>PersistenceManager</tt> instances
0892: * obtained from this factory.
0893: *
0894: * @return the default NontransactionalWrite setting.
0895: */
0896:
0897: public boolean getNontransactionalWrite() {
0898: return nontransactionalWrite;
0899: }
0900:
0901: /**
0902: * Set the default IgnoreCache setting for all <tt>PersistenceManager</tt> instances
0903: * obtained from this factory.
0904: *
0905: * @param flag the default IgnoreCache setting.
0906: */
0907:
0908: public synchronized void setIgnoreCache(boolean flag) {
0909: assertConfigurable();
0910: ignoreCache = flag;
0911: }
0912:
0913: /**
0914: * Get the default IgnoreCache setting for all <tt>PersistenceManager</tt> instances
0915: * obtained from this factory.
0916: *
0917: * @return the default IngoreCache setting.
0918: */
0919:
0920: public boolean getIgnoreCache() {
0921: return ignoreCache;
0922: }
0923:
0924: /**
0925: * Set the MaxPool setting for the <tt>PersistenceManager</tt>
0926: * pool for this factory.
0927: * @param maxPool the MaxPool setting.
0928: */
0929:
0930: public synchronized void setMaxPool(int maxPool) {
0931: assertConfigurable();
0932: this .maxPool = maxPool;
0933: }
0934:
0935: /**
0936: * Get the MaxPool setting for the <tt>PersistenceManager</tt>
0937: * pool for this factory.
0938: * @return the MaxPool setting.
0939: */
0940:
0941: public int getMaxPool() {
0942: return maxPool;
0943: }
0944:
0945: /**
0946: * Set the MinPool setting for the <tt>PersistenceManager</tt>
0947: * pool for this factory.
0948: * @param minPool the MinPool setting.
0949: */
0950:
0951: public synchronized void setMinPool(int minPool) {
0952: assertConfigurable();
0953: this .minPool = minPool;
0954: }
0955:
0956: /**
0957: * Get the MinPool setting for the <tt>PersistenceManager</tt>
0958: * pool for this factory.
0959: * @return the MinPool setting.
0960: */
0961:
0962: public int getMinPool() {
0963: return minPool;
0964: }
0965:
0966: /**
0967: * Set the MsWait setting for the <tt>PersistenceManager</tt>
0968: * pool for this factory.
0969: * @param msWait the MsWait setting.
0970: */
0971:
0972: public synchronized void setMsWait(int msWait) {
0973: assertConfigurable();
0974: this .msWait = msWait;
0975: }
0976:
0977: /**
0978: * Get the MsWait setting for the <tt>PersistenceManager</tt>
0979: * pool for this factory.
0980: * @return the MsWait setting.
0981: */
0982:
0983: public int getMsWait() {
0984: return msWait;
0985: }
0986:
0987: /**
0988: * Set the default ValidateTables setting for all
0989: * <tt>PersistenceManager</tt> instances obtained from this factory.
0990: *
0991: * @param flag the default ValidateTables setting.
0992: */
0993:
0994: public synchronized void setValidateTables(boolean flag) {
0995: assertConfigurable();
0996: validateTables = flag;
0997: }
0998:
0999: /**
1000: * Get the default ValidateTables setting for all
1001: * <tt>PersistenceManager</tt> instances obtained from this factory.
1002: *
1003: * @return the default ValidateTables setting.
1004: */
1005:
1006: public boolean getValidateTables() {
1007: return validateTables;
1008: }
1009:
1010: /**
1011: * Set the default ValidateConstraints setting for all
1012: * <tt>PersistenceManager</tt> instances obtained from this factory.
1013: *
1014: * @param flag the default ValidateConstraints setting.
1015: */
1016:
1017: public synchronized void setValidateConstraints(boolean flag) {
1018: assertConfigurable();
1019: validateConstraints = flag;
1020: }
1021:
1022: /**
1023: * Get the default ValidateConstraints setting for all
1024: * <tt>PersistenceManager</tt> instances obtained from this factory.
1025: *
1026: * @return the default ValidateConstraints setting.
1027: */
1028:
1029: public boolean getValidateConstraints() {
1030: return validateConstraints;
1031: }
1032:
1033: /**
1034: * Set the default AutoCreateTables setting for all
1035: * <tt>PersistenceManager</tt> instances obtained from this factory.
1036: *
1037: * @param flag the default AutoCreateTables setting.
1038: */
1039:
1040: public synchronized void setAutoCreateTables(boolean flag) {
1041: assertConfigurable();
1042: autoCreateTables = flag;
1043: }
1044:
1045: /**
1046: * Get the default AutoCreateTables setting for all
1047: * <tt>PersistenceManager</tt> instances obtained from this factory.
1048: *
1049: * @return the default AutoCreateTables setting.
1050: */
1051:
1052: public boolean getAutoCreateTables() {
1053: return autoCreateTables;
1054: }
1055:
1056: /**
1057: * Set the default transaction isolation level for all
1058: * <tt>PersistenceManager</tt> instances obtained from this factory.
1059: *
1060: * @param isolationLevelName
1061: * One of the values "read uncommitted", "read committed", "repeatable
1062: * read", or "serializable". The name is case-insensitive, and spaces
1063: * and underscores are equivalent.
1064: *
1065: */
1066:
1067: private synchronized void setTransactionIsolation(
1068: String isolationLevelName) {
1069: assertConfigurable();
1070:
1071: String iln = isolationLevelName.trim().replace(' ', '_')
1072: .toUpperCase();
1073:
1074: if (iln.equals("READ_UNCOMMITTED"))
1075: isolationLevel = Connection.TRANSACTION_READ_UNCOMMITTED;
1076: else if (iln.equals("READ_COMMITTED"))
1077: isolationLevel = Connection.TRANSACTION_READ_COMMITTED;
1078: else if (iln.equals("REPEATABLE_READ"))
1079: isolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
1080: else if (iln.equals("SERIALIZABLE"))
1081: isolationLevel = Connection.TRANSACTION_SERIALIZABLE;
1082: else
1083: throw new IllegalArgumentException(
1084: "Illegal isolation level: " + isolationLevelName);
1085: }
1086:
1087: /**
1088: * Set the default transaction isolation level for all
1089: * <tt>PersistenceManager</tt> instances obtained from this factory.
1090: *
1091: * @param isolationLevel the default transaction isolation level.
1092: */
1093:
1094: public synchronized void setTransactionIsolation(int isolationLevel) {
1095: assertConfigurable();
1096:
1097: switch (isolationLevel) {
1098: case Connection.TRANSACTION_READ_UNCOMMITTED:
1099: case Connection.TRANSACTION_READ_COMMITTED:
1100: case Connection.TRANSACTION_REPEATABLE_READ:
1101: case Connection.TRANSACTION_SERIALIZABLE:
1102: break;
1103:
1104: default:
1105: throw new IllegalArgumentException(
1106: "Illegal isolation level: " + isolationLevel);
1107: }
1108:
1109: this .isolationLevel = isolationLevel;
1110: }
1111:
1112: /**
1113: * Get the default transaction isolation level for all
1114: * <tt>PersistenceManager</tt> instances obtained from this factory.
1115: *
1116: * @return the default transaction isolation level.
1117: */
1118:
1119: public int getTransactionIsolation() {
1120: return isolationLevel;
1121: }
1122:
1123: /**
1124: * Return non-configurable properties of this PersistenceManagerFactory.
1125: * Properties with keys VendorName and VersionNumber are required. Other
1126: * keys are optional.
1127: * @return the non-configurable properties of this
1128: * PersistenceManagerFactory.
1129: */
1130:
1131: public Properties getProperties() {
1132: Properties props = new Properties();
1133:
1134: props.setProperty("VendorName", "TriActive");
1135: props.setProperty("VersionNumber", "$Name: TJDO_2_1 $");
1136:
1137: return props;
1138: }
1139:
1140: /**
1141: * The application can determine from the results of this method which
1142: * optional features, and which query languages are supported by the JDO
1143: * implementation.
1144: *
1145: * <p>Each supported JDO optional feature is represented by a String with
1146: * one of the following values:
1147: *
1148: * <pre><blockquote>
1149: * javax.jdo.option.TransientTransactional
1150: * javax.jdo.option.NontransactionalRead
1151: * javax.jdo.option.NontransactionalWrite
1152: * javax.jdo.option.RetainValues
1153: * javax.jdo.option.Optimistic
1154: * javax.jdo.option.ApplicationIdentity
1155: * javax.jdo.option.DatastoreIdentity
1156: * javax.jdo.option.NonDatastoreIdentity
1157: * javax.jdo.option.ArrayList
1158: * javax.jdo.option.HashMap
1159: * javax.jdo.option.Hashtable
1160: * javax.jdo.option.LinkedList
1161: * javax.jdo.option.TreeMap
1162: * javax.jdo.option.TreeSet
1163: * javax.jdo.option.Vector
1164: * javax.jdo.option.Map
1165: * javax.jdo.option.List
1166: * javax.jdo.option.Array
1167: * javax.jdo.option.NullCollection
1168: * </blockquote></pre>
1169: *
1170: * The standard JDO query language is represented by a String:
1171: *
1172: * <pre><blockquote>
1173: * javax.jdo.query.JDOQL
1174: * </blockquote></pre>
1175: *
1176: * @return A Collection of String representing the supported options.
1177: */
1178:
1179: public Collection supportedOptions() {
1180: return Collections.unmodifiableList(Arrays.asList(optionArray));
1181: }
1182:
1183: private static final String[] optionArray = {
1184: "javax.jdo.option.TransientTransactional",
1185: "javax.jdo.option.NontransactionalRead",
1186: "javax.jdo.option.RetainValues",
1187: "javax.jdo.option.DatastoreIdentity",
1188: "javax.jdo.option.NonDatastoreIdentity",
1189: "javax.jdo.option.HashMap", "javax.jdo.option.Map",
1190: "javax.jdo.query.JDOQL", "javax.jdo.query.TJDOSQL" };
1191: }
|