You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by ma...@apache.org on 2007/04/02 17:42:44 UTC

svn commit: r524803 [1/2] - in /db/jdo/trunk/api20: src/java/javax/jdo/ src/schema/javax/jdo/ test/java/javax/jdo/ test/schema/jdoconfig.xml/ test/schema/jdoconfig.xml/Negative0/ test/schema/jdoconfig.xml/Negative0/META-INF/ test/schema/jdoconfig.xml/N...

Author: madams
Date: Mon Apr  2 08:42:42 2007
New Revision: 524803

URL: http://svn.apache.org/viewvc?view=rev&rev=524803
Log:
JDO-467
Committing changes.  Some unresolved issues remain; see JDO-467 for more details.

Added:
    db/jdo/trunk/api20/src/java/javax/jdo/Constants.java
    db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.dtd
    db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.xsd
    db/jdo/trunk/api20/test/java/javax/jdo/ClasspathHelper.java
    db/jdo/trunk/api20/test/java/javax/jdo/JDOHelperConfigTest.java
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative0/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative0/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative0/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative1/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative1/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative1/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative2/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative2/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative2/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative3/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative3/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative3/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative4/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative4/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative4/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative5/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative5/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative5/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/6a/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/6a/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/6a/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/6b/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/6b/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Negative6/6b/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive0/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive0/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive0/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/1a/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/1a/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/1a/META-INF/jdoconfig.xml
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/1b/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/1b/META-INF/
    db/jdo/trunk/api20/test/schema/jdoconfig.xml/Positive1/1b/META-INF/jdoconfig.xml
Modified:
    db/jdo/trunk/api20/src/java/javax/jdo/Bundle.properties
    db/jdo/trunk/api20/src/java/javax/jdo/JDOHelper.java
    db/jdo/trunk/api20/src/java/javax/jdo/PersistenceManagerFactory.java

Modified: db/jdo/trunk/api20/src/java/javax/jdo/Bundle.properties
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/src/java/javax/jdo/Bundle.properties?view=diff&rev=524803&r1=524802&r2=524803
==============================================================================
--- db/jdo/trunk/api20/src/java/javax/jdo/Bundle.properties (original)
+++ db/jdo/trunk/api20/src/java/javax/jdo/Bundle.properties Mon Apr  2 08:42:42 2007
@@ -77,3 +77,34 @@
 EXC_DateStringConstructor: Error parsing Date string "{0}" at position {1} \
 using date format "{2}".
 MSG_unknown: unknown
+EXC_DuplicateRequestedPUFoundInDifferentConfigs: Duplicate persistence unit \
+name "{0}" found in {1} and {2}.
+EXC_DuplicateRequestedPersistenceUnitFoundInSameConfig: Duplicate persistence \
+unit name "{0}" found in {1}.
+EXC_UnableToInvokeCreateEMFMethod:  Unable to invoke \
+javax.persistence.Persistence.createEntityManagerFactory(String)
+EXC_UnableToCastEMFToPMF:  Unable to cast EntityManagerFactory class {0} \
+to javax.jdo.PersistenceManagerFactory
+ERR_NoDocumentBuilderFactory:  Unable to instantiate \
+javax.xml.parsers.DocumentBuilderFactory
+EXC_ParserConfigException:  Encountered parser configuration exception while \
+getting javax.xml.parsers.DocumentBuilder
+EXC_ParsingException:  Exception parsing configuration {0}
+EXC_DuplicatePropertyFound: Duplicate property name "{0}" found in persistence \
+unit name "{1}" found in {2}.
+EXC_DuplicatePersistenceUnitNamePropertyFoundWithinUnitConfig:  Duplicate \
+persistence unit name found in {2}:  attribute is "{0}", element is "{1}"
+EXC_PropertyElementHasNoNameAttribute:  Found <property> element with no \
+"name" attribute in {0}
+EXC_PropertyElementNameAttributeHasNoValue:  Found <property> element name \
+attribute "{0}" with no value in {1}
+EXC_DuplicatePropertyNameGivenInPropertyElement: Duplicate property name given \
+in property element:  name {0} in {1}
+EXC_MissingListenerAttribute:  Required <instance-lifecycle-listener> \
+attribute "listener" missing in {0}
+EXC_MissingListenerAttributeValue:  <instance-lifecycle-listener> attribute \
+"listener" missing value in {0}
+EXC_InvalidJDOConfigNoRoot:  No root <jdoconfig> element found in {0}
+EXC_NoPMFConfigurableViaPropertiesOrXML: No PersistenceManagerFactory \
+configurable via properties resource "{0}" or no persistence unit named "{0}" \
+found using resource loader {1}

Added: db/jdo/trunk/api20/src/java/javax/jdo/Constants.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/src/java/javax/jdo/Constants.java?view=auto&rev=524803
==============================================================================
--- db/jdo/trunk/api20/src/java/javax/jdo/Constants.java (added)
+++ db/jdo/trunk/api20/src/java/javax/jdo/Constants.java Mon Apr  2 08:42:42 2007
@@ -0,0 +1,806 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.jdo;
+
+/**
+ * Constant values used in JDO.
+ *
+ * @since 2.1
+ */
+public interface Constants {
+
+    /**
+     * The name of the standard JDO configuration resource file(s).
+     * Constant value is <code>META-INF/jdoconfig.xml</code>.
+     *
+     * @since 2.1
+     */
+    static String JDOCONFIG_RESOURCE_NAME
+        = "META-INF/jdoconfig.xml";
+
+    /**
+     * The standard JDO configuration schema namespace.
+     * Constant value is <code>http://java.sun.com/xml/ns/jdo/jdoconfig</code>.
+     *
+     * @since 2.1
+     */
+    static String JDOCONFIG_XSD_NS
+        = "http://java.sun.com/xml/ns/jdo/jdoconfig";
+
+    /**
+     * The standard JDO metadata schema namespace.
+     * Constant value is <code>http://java.sun.com/xml/ns/jdo/jdo</code>.
+     *
+     * @since 2.1
+     */
+    static String JDO_XSD_NS
+        = "http://java.sun.com/xml/ns/jdo/jdo";
+
+    /**
+     * The standard JDO object-repository mapping schema namespace.
+     * Constant value is <code>http://java.sun.com/xml/ns/jdo/orm</code>.
+     *
+     * @since 2.1
+     */
+    static String ORM_XSD_NS
+        = "http://java.sun.com/xml/ns/jdo/orm";
+
+    /**
+     * The standard JDO query schema namespace.
+     * Constant value is <code>http://java.sun.com/xml/ns/jdo/jdoquery</code>.
+     *
+     * @since 2.1
+     */
+    static String JDOQUERY_XSD_NS
+        = "http://java.sun.com/xml/ns/jdo/jdoquery";
+
+    /**
+     * The name of the persistence manager factory element in the JDO
+     * configuration file.
+     * Constant value is <code>persistence-manager-factory</code>.
+     *
+     * @since 2.1
+     */
+    static String ELEMENT_PERSISTENCE_MANAGER_FACTORY
+        = "persistence-manager-factory";
+
+    /**
+     * The name of the persistence manager factory element's "class" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CLASS
+        = "class";
+    /**
+     * The name of the persistence manager factory element's
+     * "persistence-unit-name" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_PERSISTENCE_UNIT_NAME
+        = "persistence-unit-name";
+    /**
+     * The name of the persistence manager factory element's "optimistic"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_OPTIMISTIC
+        = "optimistic";
+    /**
+     * The name of the persistence manager factory element's "retain-values"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_RETAIN_VALUES
+        = "retain-values";
+    /**
+     * The name of the persistence manager factory element's "restore-values"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_RESTORE_VALUES
+        = "restore-values";
+    /**
+     * The name of the persistence manager factory element's "ignore-cache"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_IGNORE_CACHE
+        = "ignore-cache";
+    /**
+     * The name of the persistence manager factory element's
+     * "nontransactional-read" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_NONTRANSACTIONAL_READ
+        = "nontransactional-read";
+    /**
+     * The name of the persistence manager factory element's
+     * "nontransactional-write" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_NONTRANSACTIONAL_WRITE
+        = "nontransactional-write";
+    /**
+     * The name of the persistence manager factory element's "multithreaded"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_MULTITHREADED
+        = "multithreaded";
+    /**
+     * The name of the persistence manager factory element's
+     * "connection-driver-name" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CONNECTION_DRIVER_NAME
+        = "connection-driver-name";
+    /**
+     * The name of the persistence manager factory element's
+     * "connection-user-name" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CONNECTION_USER_NAME
+        = "connection-user-name";
+    /**
+     * The name of the persistence manager factory element's
+     * "connection-password" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CONNECTION_PASSWORD
+        = "connection-password";
+    /**
+     * The name of the persistence manager factory element's "connection-url"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CONNECTION_URL
+        = "connection-url";
+    /**
+     * The name of the persistence manager factory element's
+     * "connection-factory-name" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CONNECTION_FACTORY_NAME
+        = "connection-factory-name";
+    /**
+     * The name of the persistence manager factory element's
+     * "connection-factory2-name" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_CONNECTION_FACTORY2_NAME
+        = "connection-factory2-name";
+    /**
+     * The name of the persistence manager factory element's
+     * "detach-all-on-commit" attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_DETACH_ALL_ON_COMMIT
+        = "detach-all-on-commit";
+    /**
+     * The name of the persistence manager factory element's "mapping"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_MAPPING
+        = "mapping";
+    /**
+     * The name of the persistence manager factory element's "mapping"
+     * attribute.
+     *
+     * @since 2.1
+     */
+    static String PMF_ATTRIBUTE_ServerTimeZoneID
+        = "server-time-zone-id";
+
+    /**
+     * The name of the persistence manager factory property elements in the JDO
+     * configuration file.
+     */
+    static String ELEMENT_PROPERTY
+        = "property";
+    /**
+     * The name of the persistence manager factory property element's "name"
+     * attribute.
+     */
+    static String PROPERTY_ATTRIBUTE_NAME
+        = "name";
+    /**
+     * The name of the persistence manager factory property element's "value"
+     * attribute.
+     */
+    static String PROPERTY_ATTRIBUTE_VALUE
+        = "value";
+
+    /**
+     * The name of the instance lifecycle listener element in the JDO
+     * configuration file.
+     */
+    static String ELEMENT_INSTANCE_LIFECYCLE_LISTENER
+        = "instance-lifecycle-listener";
+
+    /**
+     * The name of the instance lifecycle listener element's "listener"
+     * attribute.
+     */
+    static String INSTANCE_LIFECYCLE_LISTENER_ATTRIBUTE_LISTENER
+        = "listener";
+    /**
+     * The name of the instance lifecycle listener element's "classes"
+     * attribute.
+     */
+    static String INSTANCE_LIFECYCLE_LISTENER_ATTRIBUTE_CLASSES
+        = "classes";
+
+    /**
+     * "javax.jdo.option.TransientTransactional"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_TRANSACTIONAL_TRANSIENT
+        = "javax.jdo.option.TransientTransactional";
+    /**
+     * "javax.jdo.option.NontransactionalRead"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_NONTRANSACTIONAL_READ
+        = "javax.jdo.option.NontransactionalRead";
+    /**
+     * "javax.jdo.option.NontransactionalWrite"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_NONTRANSACTIONAL_WRITE
+        = "javax.jdo.option.NontransactionalWrite";
+    /**
+     * "javax.jdo.option.RetainValues"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_RETAIN_VALUES
+        = "javax.jdo.option.RetainValues";
+    /**
+     * "javax.jdo.option.Optimistic"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_OPTIMISTIC
+        = "javax.jdo.option.Optimistic";
+    /**
+     * "javax.jdo.option.ApplicationIdentity"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_APPLICATION_IDENTITY
+        = "javax.jdo.option.ApplicationIdentity";
+    /**
+     * "javax.jdo.option.DatastoreIdentity"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_DATASTORE_IDENTITY
+        = "javax.jdo.option.DatastoreIdentity";
+    /**
+     * "javax.jdo.option.NonDurableIdentity"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_NONDURABLE_IDENTITY
+        = "javax.jdo.option.NonDurableIdentity";
+    /**
+     * "javax.jdo.option.ArrayList"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_ARRAYLIST
+        = "javax.jdo.option.ArrayList";
+    /**
+     * "javax.jdo.option.LinkedList"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_LINKEDLIST
+        = "javax.jdo.option.LinkedList";
+    /**
+     * "javax.jdo.option.TreeMap"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_TREEMAP
+        = "javax.jdo.option.TreeMap";
+    /**
+     * "javax.jdo.option.TreeSet"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_TREESET
+        = "javax.jdo.option.TreeSet";
+    /**
+     * "javax.jdo.option.Vector"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_VECTOR
+        = "javax.jdo.option.Vector";
+    /**
+     * "javax.jdo.option.Array"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_ARRAY
+        = "javax.jdo.option.Array";
+    /**
+     * "javax.jdo.option.NullCollection"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_NULL_COLLECTION
+        = "javax.jdo.option.NullCollection";
+    /**
+     * "javax.jdo.option.ChangeApplicationIdentity"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_CHANGE_APPLICATION_IDENTITY
+        = "javax.jdo.option.ChangeApplicationIdentity";
+    /**
+     * "javax.jdo.option.BinaryCompatibility"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_BINARY_COMPATIBILITY
+        = "javax.jdo.option.BinaryCompatibility";
+    /**
+     * "javax.jdo.option.GetDataStoreConnection"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_GET_DATASTORE_CONNECTION
+        = "javax.jdo.option.GetDataStoreConnection";
+    /**
+     * "javax.jdo.option.GetJDBCConnection"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_GET_JDBC_CONNECTION
+        = "javax.jdo.option.GetJDBCConnection";
+    /**
+     * "javax.jdo.query.SQL"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_QUERY_SQL
+        = "javax.jdo.query.SQL";
+    /**
+     * "javax.jdo.option.UnconstrainedQueryVariables"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_UNCONSTRAINED_QUERY_VARIABLES
+        = "javax.jdo.option.UnconstrainedQueryVariables";
+    /**
+     * "javax.jdo.option.version.DateTime"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_VERSION_DATETIME
+        = "javax.jdo.option.version.DateTime";
+    /**
+     * "javax.jdo.option.version.StateImage"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_VERSION_STATE_IMAGE
+        = "javax.jdo.option.version.StateImage";
+    /**
+     * "javax.jdo.option.PreDirtyEvent"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_PREDIRTY_EVENT
+        = "javax.jdo.option.PreDirtyEvent";
+    /**
+     * "javax.jdo.option.mapping.HeterogeneousObjectType"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_MAPPING_HETEROGENEOUS_OBJECT_TYPE
+        = "javax.jdo.option.mapping.HeterogeneousObjectType";
+    /**
+     * "javax.jdo.option.mapping.HeterogeneousInterfaceType"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_MAPPING_HETEROGENEOUS_INTERFACE_TYPE
+        = "javax.jdo.option.mapping.HeterogeneousInterfaceType";
+    /**
+     * "javax.jdo.option.mapping.JoinedTablePerClass"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_MAPPING_JOINED_TABLE_PER_CLASS
+        = "javax.jdo.option.mapping.JoinedTablePerClass";
+    /**
+     * "javax.jdo.option.mapping.JoinedTablePerConcreteClass"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_MAPPING_JOINED_TABLE_PER_CONCRETE_CLASS
+        = "javax.jdo.option.mapping.JoinedTablePerConcreteClass";
+    /**
+     * "javax.jdo.option.mapping.NonJoinedTablePerConcreteClass"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_MAPPING_NON_JOINED_TABLE_PER_CONCRETE_CLASS
+        = "javax.jdo.option.mapping.NonJoinedTablePerConcreteClass";
+    /**
+     * "javax.jdo.option.mapping.RelationSubclassTable"
+     *
+     * @see PersistenceManagerFactory#supportedOptions()
+     * @since 2.1
+     */
+    static String OPTION_MAPPING_RELATION_SUBCLASS_TABLE
+        = "javax.jdo.option.mapping.RelationSubclassTable";
+
+    /**
+     * "javax.jdo.PersistenceManagerFactoryClass"
+     *
+     * @see JDOHelper#getPersistenceManagerFactory(java.util.Map)
+     * @since 2.1
+     */
+    static String PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS
+        = "javax.jdo.PersistenceManagerFactoryClass";
+
+    /**
+     * "javax.jdo.option.Optimistic"
+     *
+     * @see PersistenceManagerFactory#getOptimistic()
+     * @since 2.1
+     */
+    static String PROPERTY_OPTIMISTIC
+        = "javax.jdo.option.Optimistic";
+    /**
+     * "javax.jdo.option.RetainValues"
+     *
+     * @see PersistenceManagerFactory#getRetainValues()
+     * @since 2.1
+     */
+    static String PROPERTY_RETAIN_VALUES
+        = "javax.jdo.option.RetainValues";
+    /**
+     * "javax.jdo.option.RestoreValues"
+     *
+     * @see PersistenceManagerFactory#getRestoreValues()
+     * @since 2.1
+     */
+    static String PROPERTY_RESTORE_VALUES
+        = "javax.jdo.option.RestoreValues";
+    /**
+     * "javax.jdo.option.IgnoreCache"
+     *
+     * @see PersistenceManagerFactory#getIgnoreCache()
+     * @since 2.1
+     */
+    static String PROPERTY_IGNORE_CACHE
+        = "javax.jdo.option.IgnoreCache";
+    /**
+     * "javax.jdo.option.NontransactionalRead"
+     *
+     * @see PersistenceManagerFactory#getNontransactionalRead()
+     * @since 2.1
+     */
+    static String PROPERTY_NONTRANSACTIONAL_READ
+        = "javax.jdo.option.NontransactionalRead";
+    /**
+     * "javax.jdo.option.NontransactionalWrite"
+     *
+     * @see PersistenceManagerFactory#getNontransactionalWrite()
+     * @since 2.1
+     */
+    static String PROPERTY_NONTRANSACTIONAL_WRITE
+        = "javax.jdo.option.NontransactionalWrite";
+    /**
+     * "javax.jdo.option.Multithreaded"
+     *
+     * @see PersistenceManagerFactory#getMultithreaded()
+     * @since 2.1
+     */
+    static String PROPERTY_MULTITHREADED
+        = "javax.jdo.option.Multithreaded";
+    /**
+     * "javax.jdo.option.DetachAllOnCommit"
+     *
+     * @see PersistenceManagerFactory#getDetachAllOnCommit()
+     * @since 2.1
+     */
+    static String PROPERTY_DETACH_ALL_ON_COMMIT
+        = "javax.jdo.option.DetachAllOnCommit";
+    /**
+     * "javax.jdo.option.ConnectionDriverName"
+     *
+     * @see PersistenceManagerFactory#getConnectionDriverName()
+     * @since 2.1
+     */
+    static String PROPERTY_CONNECTION_DRIVER_NAME
+        = "javax.jdo.option.ConnectionDriverName";
+    /**
+     * "javax.jdo.option.ConnectionUserName"
+     *
+     * @see PersistenceManagerFactory#getConnectionUserName()
+     * @since 2.1
+     */
+    static String PROPERTY_CONNECTION_USER_NAME
+        = "javax.jdo.option.ConnectionUserName";
+    /**
+     * "javax.jdo.option.Password"
+     *
+     * @since 2.1
+     */
+    static String PROPERTY_CONNECTION_PASSWORD
+        = "javax.jdo.option.ConnectionPassword";
+    /**
+     * "javax.jdo.option.ConnectionURL"
+     *
+     * @see PersistenceManagerFactory#getConnectionURL()
+     * @since 2.1
+     */
+    static String PROPERTY_CONNECTION_URL
+        = "javax.jdo.option.ConnectionURL";
+    /**
+     * "javax.jdo.option.ConnectionFactoryName"
+     *
+     * @see PersistenceManagerFactory#getConnectionFactoryName()
+     * @since 2.1
+     */
+    static String PROPERTY_CONNECTION_FACTORY_NAME
+        = "javax.jdo.option.ConnectionFactoryName";
+    /**
+     * "javax.jdo.option.ConnectionFactory2Name"
+     *
+     * @see PersistenceManagerFactory#getConnectionFactory2Name()
+     * @since 2.1
+     */
+    static String PROPERTY_CONNECTION_FACTORY2_NAME
+        = "javax.jdo.option.ConnectionFactory2Name";
+    /**
+     * "javax.jdo.option.Mapping"
+     *
+     * @see PersistenceManagerFactory#getMapping()
+     * @since 2.1
+     */
+    static String PROPERTY_MAPPING
+        = "javax.jdo.option.Mapping";
+    /**
+     * "javax.jdo.option.PersistenceUnitName"
+     *
+     * @see PersistenceManagerFactory#getPersistenceUnitName()
+     * @since 2.1
+     */
+    static String PROPERTY_PERSISTENCE_UNIT_NAME
+        = "javax.jdo.option.PersistenceUnitName";
+
+    /**
+     * "javax.jdo.option.InstanceLifecycleListener"
+     *
+     * @see PersistenceManagerFactory#addInstanceLifecycleListener(javax.jdo.listener.InstanceLifecycleListener,Class[])
+     * @see PersistenceManagerFactory#removeInstanceLifecycleListener(javax.jdo.listener.InstanceLifecycleListener)
+     */
+    static String PROPERTY_INSTANCE_LIFECYCLE_LISTENER
+        = "javax.jdo.option.InstanceLifecycleListener";
+
+    /**
+     * Prefix used to configure
+     * {@link javax.jdo.listener.InstanceLifecycleListener} instances
+     * externally.
+     * To configure an <code>InstanceLifecycleListener</code> via properties,
+     * create a property name with the prefix of
+     * this constant and append the fully qualified listener class name, then
+     * set its value to the comma- or whitespace-delimited list
+     * of persistence-capable classes whose instances are to be observed.
+     * Use no value to indicate that instances of
+     * all persistence-capable classes are to be observed.<br>
+     * For example,<br>
+     * <code>javax.jdo.option.InstanceLifecycleListener.com.example.MyListener=com.example.Foo,com.example.Bar</code><br>
+     * is equivalent to calling<br>
+     * <code>pmf.addInstanceLifecycleListener(new com.example.MyListener(), new Class[] {com.example.Foo.class, com.example.Bar.class});</code><br>
+     * where <code>pmf</code> is an instance of type
+     * <code>PersistenceManagerFactory</code>.
+     *
+     * @see javax.jdo.PersistenceManagerFactory#addInstanceLifecycleListener(javax.jdo.listener.InstanceLifecycleListener,Class[])
+     * @since 2.1
+     */
+    static String PROPERTY_PREFIX_INSTANCE_LIFECYCLE_LISTENER
+        = PROPERTY_INSTANCE_LIFECYCLE_LISTENER + ".";
+
+    /**
+     * Mapping "javax.jdo.mapping.Catalog"
+     *
+     * @since 2.1
+     */
+    static String PROPERTY_MAPPING_CATALOG
+        = "javax.jdo.mapping.Catalog";
+    /**
+     * Mapping "javax.jdo.mapping.Schema"
+     *
+     * @since 2.1
+     */
+    static String PROPERTY_MAPPING_SCHEMA
+        = "javax.jdo.mapping.Schema";
+
+    /**
+     * Mapping "javax.jdo.option.ServerTimeZoneID"
+     *
+     * @since 2.1
+     */
+    static String PROPERTY_SERVER_TIMEZONE_ID
+        = "javax.jdo.option.ServerTimeZoneID";
+
+    /**
+     * Nonconfigurable property constanct "VendorName"
+     *
+     * @see PersistenceManagerFactory#getProperties()
+     * @since 2.1
+     */
+    static String NONCONFIGURABLE_PROPERTY_VENDOR_NAME
+        = "VendorName";
+    /**
+     * Nonconfigurable property constanct "VersionNumber"
+     *
+     * @see PersistenceManagerFactory#getProperties()
+     * @since 2.1
+     */
+    static String NONCONFIGURABLE_PROPERTY_VERSION_NUMBER
+        = "VersionNumber";
+
+    /**
+     * The value for TransactionType to specify that transactions
+     * are managed by the Java Transactions API, as documented in
+     * JSR-220.
+     *
+     * @since 2.1
+     */
+    static String JTA
+        = "JTA";
+
+    /**
+     * The value for TransactionType to specify that transactions
+     * are managed by the javax.jdo.Transaction instance, similar
+     * to the usage as documented in JSR-220.
+     *
+     * @since 2.1
+     */
+    static String RESOURCE_LOCAL
+        = "RESOURCE_LOCAL";
+
+    /**
+     * The name of the resource for the DTD of the standard JDO configuration
+     * file.
+     *
+     * @since 2.1
+     */
+    static String JDOCONFIG_DTD_RESOURCE
+        = "javax/jdo/jdoconfig_2_1.dtd";
+
+    /**
+     * The name of the resource for the XML schema of the standard JDO
+     * configuration file.
+     *
+     * @since 2.1
+     */
+    static String JDOCONFIG_XSD_RESOURCE
+        = "javax/jdo/jdoconfig_2_1.xsd";
+
+    /**
+     * The name of the resource for the DTD of the standard JDO metadata file.
+     *
+     * @since 2.1
+     */
+    static String JDO_DTD_RESOURCE
+        = "javax/jdo/jdo_2_0.dtd";
+
+    /**
+     * The name of the resource for the XML schema of the standard JDO
+     * metadata file.
+     *
+     * @since 2.1
+     */
+    static String JDO_XSD_RESOURCE
+        = "javax/jdo/jdo_2_0.xsd";
+
+    /**
+     * The name of the resource for the DTD of the standard JDO
+     * object-relational mapping metadata file.
+     *
+     * @since 2.1
+     */
+    static String ORM_DTD_RESOURCE
+        = "javax/jdo/orm_2_0.dtd";
+
+    /**
+     * The name of the resource for the XML schema of the standard JDO
+     * object-relational mapping metadata file.
+     *
+     * @since 2.1
+     */
+    static String ORM_XSD_RESOURCE
+        = "javax/jdo/orm_2_0.xsd";
+
+    /**
+     * The name of the resource for the DTD of the standard JDO query
+     * metadata file.
+     *
+     * @since 2.1
+     */
+    static String JDOQUERY_DTD_RESOURCE
+        = "javax/jdo/jdoquery_2_0.dtd";
+
+    /**
+     * The name of the resource for the XML schema of the standard JDO query
+     * metadata file.
+     *
+     * @since 2.1
+     */
+    static String JDOQUERY_XSD_RESOURCE
+        = "javax/jdo/jdoquery_2_0.xsd";
+}

Modified: db/jdo/trunk/api20/src/java/javax/jdo/JDOHelper.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/src/java/javax/jdo/JDOHelper.java?view=diff&rev=524803&r1=524802&r2=524803
==============================================================================
--- db/jdo/trunk/api20/src/java/javax/jdo/JDOHelper.java (original)
+++ db/jdo/trunk/api20/src/java/javax/jdo/JDOHelper.java Mon Apr  2 08:42:42 2007
@@ -22,6 +22,14 @@
  
 package javax.jdo;
 
+import org.xml.sax.SAXException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.Element;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -31,15 +39,19 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 
-import java.util.ArrayList;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.net.URL;
+
 import java.util.Collection;
-import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Enumeration;
+import java.util.Collections;
 
 import javax.jdo.spi.I18NHelper;
 import javax.jdo.spi.JDOImplHelper;
@@ -54,6 +66,11 @@
 
 import javax.rmi.PortableRemoteObject;
 
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.FactoryConfigurationError;
+
 
 /**
  * This class can be used by a JDO-aware application to call the JDO behavior
@@ -69,13 +86,103 @@
  * 
  * @version 2.1
  */
-public class JDOHelper extends Object {
-      
+public class JDOHelper extends Object implements Constants {
+
+    /**
+     * A mapping from jdoconfig.xsd element attributes to PMF properties.
+     */
+    static final Map ATTRIBUTE_PROPERTY_XREF
+        = createAttributePropertyXref();
+
+    /**
+     * The standard XML schema type.
+     */
+    protected static final String XSD_TYPE
+        = "http://www.w3.org/2001/XMLSchema";
+    
+    /**
+     * The JAXP schema language property.
+     */
+    protected static final String SCHEMA_LANGUAGE_PROP
+        = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+
+    /**
+     * External schema location property.
+     */
+    protected static final String SCHEMA_LOCATION_PROP
+        = "http://apache.org/xml/properties/schema/external-schemaLocation";
+
     /** The Internationalization message helper.
      */
     private final static I18NHelper msg = 
         I18NHelper.getInstance ("javax.jdo.Bundle"); //NOI18N
 
+    /**
+     * Creates a map from jdoconfig.xsd element attributes to PMF properties.
+     * @return An unmodifiable Map of jdoconfig.xsd element attributes to PMF
+     * properties.
+     */
+    static Map createAttributePropertyXref() {
+        Map xref = new HashMap();
+
+        xref.put(
+            PMF_ATTRIBUTE_CLASS,
+            PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS);
+        xref.put(
+            PMF_ATTRIBUTE_CONNECTION_DRIVER_NAME,
+            PROPERTY_CONNECTION_DRIVER_NAME);
+        xref.put(
+            PMF_ATTRIBUTE_CONNECTION_FACTORY_NAME,
+            PROPERTY_CONNECTION_FACTORY_NAME);
+        xref.put(
+            PMF_ATTRIBUTE_CONNECTION_FACTORY2_NAME,
+            PROPERTY_CONNECTION_FACTORY2_NAME);
+        xref.put(
+            PMF_ATTRIBUTE_CONNECTION_PASSWORD,
+            PROPERTY_CONNECTION_PASSWORD);
+        xref.put(
+            PMF_ATTRIBUTE_CONNECTION_URL,
+            PROPERTY_CONNECTION_URL);
+        xref.put(
+            PMF_ATTRIBUTE_CONNECTION_USER_NAME,
+            PROPERTY_CONNECTION_USER_NAME);
+        xref.put(
+            PMF_ATTRIBUTE_IGNORE_CACHE,
+            PROPERTY_IGNORE_CACHE);
+        xref.put(
+            PMF_ATTRIBUTE_MAPPING,
+            PROPERTY_MAPPING);
+        xref.put(
+            PMF_ATTRIBUTE_MULTITHREADED,
+            PROPERTY_MULTITHREADED);
+        xref.put(
+            PMF_ATTRIBUTE_NONTRANSACTIONAL_READ,
+            PROPERTY_NONTRANSACTIONAL_READ);
+        xref.put(
+            PMF_ATTRIBUTE_NONTRANSACTIONAL_WRITE,
+            PROPERTY_NONTRANSACTIONAL_WRITE);
+        xref.put(
+            PMF_ATTRIBUTE_OPTIMISTIC,
+            PROPERTY_OPTIMISTIC);
+        xref.put(
+            PMF_ATTRIBUTE_PERSISTENCE_UNIT_NAME,
+            PROPERTY_PERSISTENCE_UNIT_NAME);
+        xref.put(
+            PMF_ATTRIBUTE_RESTORE_VALUES,
+            PROPERTY_RESTORE_VALUES);
+        xref.put(
+            PMF_ATTRIBUTE_RETAIN_VALUES,
+            PROPERTY_RETAIN_VALUES);
+        xref.put(
+            PMF_ATTRIBUTE_DETACH_ALL_ON_COMMIT,
+            PROPERTY_DETACH_ALL_ON_COMMIT);
+        xref.put(
+            PMF_ATTRIBUTE_ServerTimeZoneID,
+            PROPERTY_SERVER_TIMEZONE_ID);
+
+        return Collections.unmodifiableMap(xref);
+    }
+
     /** The JDOImplHelper instance used for handling non-binary-compatible
      *  implementations.
      */
@@ -487,23 +594,35 @@
         }
     }
     
-    /** Get a <code>PersistenceManagerFactory</code> based on a <code>Properties</code> 
+    /** Get the anonymous <code>PersistenceManagerFactory</code> configured via the standard
+     * configuration file resource "META-INF/jdoconfig.xml", using the current thread's context class loader
+     * to locate the configuration file resource(s).
+     * @return the anonymous <code>PersistenceManagerFactory</code>.
+     * @since 2.1
+     * @see #getPersistenceManagerFactory(String,ClassLoader)
+     */
+    public static PersistenceManagerFactory getPersistenceManagerFactory() {
+        ClassLoader cl = getContextClassLoader();
+        return getPersistenceManagerFactory ((String)null, cl);
+    }
+
+    /** Get a <code>PersistenceManagerFactory</code> based on a <code>Properties</code>
      * instance, using the current thread's context class loader to locate the
      * <code>PersistenceManagerFactory</code> class.
      * @return the <code>PersistenceManagerFactory</code>.
-     * @param props a <code>Properties</code> instance with properties of the 
+     * @param props a <code>Properties</code> instance with properties of the
      * <code>PersistenceManagerFactory</code>.
-     * @see #getPersistenceManagerFactory(Map,ClassLoader)
+     * @see #getPersistenceManagerFactory(java.util.Map,ClassLoader)
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
             (Map props) {
         ClassLoader cl = getContextClassLoader();
         return getPersistenceManagerFactory (props, cl);
     }
-    
+
     /**
      * Get a <code>PersistenceManagerFactory</code> based on a 
-     * <code>Properties</code> instance and a class loader.
+     * <code>Map</code> instance and a class loader.
      * The following are standard key values:
      * <BR><code>"javax.jdo.PersistenceManagerFactoryClass"
      * <BR>"javax.jdo.option.Optimistic",
@@ -520,8 +639,20 @@
      * <BR>"javax.jdo.option.ConnectionFactory2Name",
      * <BR>"javax.jdo.option.Mapping",
      * <BR>"javax.jdo.mapping.Catalog",
-     * <BR>"javax.jdo.mapping.Schema".
-     * </code><P>JDO implementations
+     * <BR>"javax.jdo.mapping.Schema",
+     * <BR>"javax.jdo.option.PersistenceUnitName".
+     * </code>
+     * and properties of the form
+     * <BR><code>javax.jdo.option.InstanceLifecycleListener.{listenerClass}={pcClasses}</code>
+     * where <code>{listenerClass}</code> is the fully qualified name of a
+     * class that implements
+     * {@link javax.jdo.listener.InstanceLifecycleListener}, and
+     * <code>{pcClasses}</code> is an optional comma- or whitespace-delimited
+     * list of persistence-capable classes to be observed; the absence of a
+     * value for a property of this form means that instances of all
+     * persistence-capable classes will be observed by an instance of the given
+     * listener class.
+     * <P>JDO implementations
      * are permitted to define key values of their own.  Any key values not
      * recognized by the implementation must be ignored.  Key values that are
      * recognized but not supported by an implementation must result in a
@@ -544,9 +675,9 @@
     public static PersistenceManagerFactory getPersistenceManagerFactory
             (Map props, ClassLoader cl) {
         String pmfClassName = (String) props.get (
-            "javax.jdo.PersistenceManagerFactoryClass"); //NOI18N
+            PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS); //NOI18N
         if (pmfClassName == null) {
-            throw new JDOFatalUserException (msg.msg(
+            throw new JDOFatalUserException(msg.msg(
                 "EXC_GetPMFNoClassNameProperty")); // NOI18N
         }
         try {
@@ -584,93 +715,682 @@
     }
     
     /**
-     * Returns a {@link PersistenceManagerFactory} configured based
+     * Returns a named {@link PersistenceManagerFactory} with the given persistence unit name or,
+     * if not found, a {@link PersistenceManagerFactory} configured based
      * on the properties stored in the resource at
-     * <code>propsResource</code>. This method is equivalent to
+     * <code>name</code>. This method is equivalent to
      * invoking {@link
      * #getPersistenceManagerFactory(String,ClassLoader)} with
      * <code>Thread.currentThread().getContextClassLoader()</code> as
      * the <code>loader</code> argument.
+     * If multiple persistence units with the name given are found, a {@link JDOFatalUserException} is thrown.
      * @since 2.0
-     * @param propsResource the resource containing the Properties
+     * @param name the persistence unit name or resource containing the Properties
      * @return the PersistenceManagerFactory
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-        (String propsResource) {
-        return getPersistenceManagerFactory (propsResource,
+        (String name) {
+        return getPersistenceManagerFactory (name,
             getContextClassLoader());
     }
 
     /**
-     * Returns a {@link PersistenceManagerFactory} configured based
+     * Returns a named {@link PersistenceManagerFactory} with the given persistence unit name or,
+     * if not found, a {@link PersistenceManagerFactory} configured based
      * on the properties stored in the resource at
-     * <code>propsResource</code>. Loads the resource via
+     * <code>name</code>.  Loads the resource via
      * <code>loader</code>, and creates a {@link
      * PersistenceManagerFactory} with <code>loader</code>. Any
      * <code>IOException</code>s thrown during resource loading will
      * be wrapped in a {@link JDOFatalUserException}.
+     * If multiple persistence units with the name given are found, a {@link JDOFatalUserException} is thrown.
      * @since 2.0
-     * @param propsResource the resource containing the Properties
-     * @param loader the class loader to use to load both the propsResource and 
+     * @param name the persistence unit name or resource containing the Properties
+     * @param loader the class loader to use to load both the name and
      * the <code>PersistenceManagerFactory</code> class
      * @return the PersistenceManagerFactory
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-        (String propsResource, ClassLoader loader) {
-        return getPersistenceManagerFactory(propsResource, loader, loader);
+        (String name, ClassLoader loader) {
+        return getPersistenceManagerFactory(name, loader, loader);
     }
         
     /**
-     * Returns a {@link PersistenceManagerFactory} configured based
+     * Returns a named {@link PersistenceManagerFactory} with the given
+     * persistence unit name or,
+     * if not found, a {@link PersistenceManagerFactory} configured based
      * on the properties stored in the resource at
-     * <code>propsResource</code>. Loads the Properties via
-     * <code>propsLoader</code>, and creates a {@link
+     * <code>name</code>.  Loads the Properties via
+     * <code>resourceLoader</code>, and creates a {@link
      * PersistenceManagerFactory} with <code>pmfLoader</code>. Any
-     * <code>IOException</code>s thrown during resource loading will
+     * exceptions thrown during resource loading will
      * be wrapped in a {@link JDOFatalUserException}.
+     * If multiple persistence units with the requested name are found, a
+     * {@link JDOFatalUserException} is thrown.
      * @since 2.0
-     * @param propsResource the resource containing the Properties
-     * @param propsLoader the class loader to use to load the propsResource
+     * @param name the persistence unit name or resource containing the Properties
+     * @param resourceLoader the class loader to use to load the name
      * @param pmfLoader the class loader to use to load the 
      * <code>PersistenceManagerFactory</code> class
      * @return the PersistenceManagerFactory
      */
     public static PersistenceManagerFactory getPersistenceManagerFactory
-        (String propsResource, ClassLoader propsLoader, ClassLoader pmfLoader) {
-        
-        if (propsResource == null)
-            throw new JDOFatalUserException (msg.msg (
-                "EXC_GetPMFNullResource")); //NOI18N
-        if (propsLoader == null)
+        (String name, ClassLoader resourceLoader, ClassLoader pmfLoader) {
+
+        if (resourceLoader == null)
             throw new JDOFatalUserException (msg.msg (
                 "EXC_GetPMFNullPropsLoader")); //NOI18N
         if (pmfLoader == null)
             throw new JDOFatalUserException (msg.msg (
                 "EXC_GetPMFNullPMFLoader")); //NOI18N
 
-        Properties props = new Properties ();
         InputStream in = null;
-        try {
-            in = propsLoader.getResourceAsStream (propsResource);
-            if (in == null)
+        if (name != null) { // then try to load resources from properties file
+            Properties props = new Properties ();
+            try {
+                in = resourceLoader.getResourceAsStream (name);
+                if (in != null) {
+                    // then some kind of resource was found by the given name;
+                    // assume that it's a properties file and proceed as usual
+                    props.load (in);
+                    return getPersistenceManagerFactory (props, pmfLoader);
+                }
+            }
+            catch (IOException ioe) {
                 throw new JDOFatalUserException (msg.msg (
-                    "EXC_GetPMFNoResource", propsResource, propsLoader)); //NOI18N
-            props.load (in);
-        } catch (IOException ioe) {
+                    "EXC_GetPMFIOExceptionRsrc", name), ioe); //NOI18N
+            }
+            finally {
+                if (in != null)
+                    try {
+                        in.close ();
+                    } catch (IOException ioe) { }
+            }
+        }
+        // JDO 2.1:  else name was null or no resource found by given name;
+        // assume name represents name of PU
+
+        PersistenceManagerFactory pmf = getPersistenceUnit(
+            name == null ? "" : name.trim(),
+            resourceLoader,
+            pmfLoader
+        );
+        if (pmf != null) {
+            return pmf;
+        }
+
+        // else no PU found
+        throw new JDOFatalUserException (msg.msg (
+            "EXC_NoPMFConfigurableViaPropertiesOrXML",
+            name,
+            resourceLoader)); //NOI18N
+    }
+
+    /** Find and return<BR><ul>
+     * <li>a {@link PersistenceManagerFactory} with the given name,</li>
+     * <li>a JPA <code>EntityManagerFactory</code> cast to a
+     * {@link PersistenceManagerFactory}, or <li>
+     * <li>null if not found.</li>
+     * If name is null
+     * or blank, this method attempts to return the anonymous
+     * {@link PersistenceManagerFactory}.  If multiple persistence units with
+     * the given name are found (including the anonymous persistence unit),
+     * this method will throw {@link JDOFatalUserException}.
+     *
+     * @param name The persistence unit name, or null, the empty string or a
+     * string only containing whitespace characters for the anonymous
+     * persistence unit.
+     * @param resourceLoader The ClassLoader used to load the standard JDO
+     * configuration file(s) given in the constant
+     * {@link Constants#JDOCONFIG_RESOURCE_NAME}.
+     * @param pmfLoader The loader used to load the
+     * {@link PersistenceManagerFactory} implementation class.
+     * @return A {@link PersistenceManagerFactory} corresponding to the
+     * persistence unit name if found, or null if not found.
+     * @throws JDOFatalUserException if multiple persistence units are found
+     * with the given name, or any other is encountered.
+     * @since 2.1
+     */
+    public static PersistenceManagerFactory getPersistenceUnit(
+            String name,
+            ClassLoader resourceLoader,
+            ClassLoader pmfLoader
+    ) {
+        Map properties = getPersistenceUnitProperties(
+                name, resourceLoader, JDOCONFIG_RESOURCE_NAME);
+
+        if (properties != null) { // found requested JDO persistence unit props
+            return getPersistenceManagerFactory(properties, pmfLoader);
+        }
+
+        // else try to return PMF from JPA EMF
+        if ("".equals(name)) { // no such thing as an anonymous JPA EMF
+            return null;
+        }
+
+        // else try to return PMF from named JPA EMF
+        return getPMFFromEMF(name, pmfLoader);
+    }
+
+    protected static Map getPersistenceUnitProperties(
+            String name
+    ) {
+        return getPersistenceUnitProperties(
+            name, getContextClassLoader(), JDOCONFIG_RESOURCE_NAME);
+    }
+
+    protected static Map getPersistenceUnitProperties(
+            String name,
+            ClassLoader resourceLoader
+    ) {
+        return getPersistenceUnitProperties(
+            name, resourceLoader, JDOCONFIG_RESOURCE_NAME);
+    }
+
+    /**
+     * Find and return the named {@link PersistenceManagerFactory}, or null if
+     * not found.  If name is null, return the anonymous
+     * {@link PersistenceManagerFactory}.  If multiple persistence units with
+     * the given name are found (including anonymous), throw
+     * {@link JDOFatalUserException}.
+     * This method is here only to facilitate testing; the parameter
+     * "jdoconfigResourceName" in public usage should always have the value
+     * given in the constant <code>JDOCONFIG_RESOURCE_NAME</code>.
+     *
+     * @param name The persistence unit name, or null or blank for the
+     * anonymous persistence unit.
+     * @param resourceLoader The ClassLoader used to load the standard JDO
+     * configuration file.
+     * @param jdoconfigResourceName The name of the configuration file to read.
+     * In public usage, this should always be the value of
+     * {@link Constants#JDOCONFIG_RESOURCE_NAME}.
+     * @return The named PersistenceManagerFactory properties if found, null if
+     * not.
+     * @since 2.1
+     * @throws JDOFatalUserException if multiple persistence units are found
+     * with the given name, or any other exception is encountered.
+     */
+    protected static Map getPersistenceUnitProperties(
+            String name,
+            ClassLoader resourceLoader,
+            String jdoconfigResourceName
+    ) {
+        /* JDO 2.1:
+        Attempt to find & return named persistence unit here.
+        If name == null or name == "", then we're looking for the default PMF.
+
+        If we can't find it, this method returns null.
+        */
+        name = name == null ? "" : name.trim(); // for use as key in Maps
+        
+        // key is PU name, value is Map of PU properties
+        Map/*<String,Map>*/ propertiesByNameInAllConfigs
+                = new HashMap/*<String,Map>*/();
+        try {
+            URL firstFoundConfigURL = null;
+
+            // get all JDO configurations
+            Enumeration resources =
+                resourceLoader.getResources(jdoconfigResourceName);
+
+            if (resources.hasMoreElements()) {
+
+                // get ready to parse XML
+                DocumentBuilderFactory factory = null;
+                // TODO:  ensure DBF is initialized properly
+                factory = DocumentBuilderFactory.newInstance();
+                factory.setIgnoringComments(true);
+                factory.setNamespaceAware(true);
+                factory.setValidating(false);
+                factory.setIgnoringElementContentWhitespace(true);
+                factory.setExpandEntityReferences(true);
+
+                do {
+                    URL currentConfigURL = (URL) resources.nextElement();
+                    Map/*<String,Map>*/ propertiesByNameInCurrentConfig =
+                        readPersistenceUnitProperties(
+                            currentConfigURL, name, factory);
+
+                    // try to detect duplicate requested PU
+                    if (propertiesByNameInCurrentConfig.containsKey(name)) {
+                        // possible dup -- check for it
+                        if (firstFoundConfigURL == null) {
+                            firstFoundConfigURL = currentConfigURL;
+                        }
+                        
+                        if (propertiesByNameInAllConfigs.containsKey(name))
+                            throw new JDOFatalUserException (msg.msg(
+                                "EXC_DuplicateRequestedPUFoundInDifferentConfigs",
+                                "".equals(name)
+                                        ? "(anonymous)"
+                                        : name,
+                                firstFoundConfigURL.toExternalForm(),
+                                currentConfigURL.toExternalForm())); //NOI18N
+                    }
+                    // no dups -- add found PUs to all PUs and keep going
+                    propertiesByNameInAllConfigs
+                        .putAll(propertiesByNameInCurrentConfig);
+                } while (resources.hasMoreElements());
+            }
+        }
+        catch (FactoryConfigurationError e) {
+            throw new JDOFatalUserException(
+                msg.msg("ERR_NoDocumentBuilderFactory"), e);
+        }
+        catch (IOException ioe) {
             throw new JDOFatalUserException (msg.msg (
-                "EXC_GetPMFIOExceptionRsrc", propsResource), ioe); //NOI18N
+                "EXC_GetPMFIOExceptionRsrc", name), ioe); //NOI18N
+        }
+
+        // done with reading all config resources;
+        // return what we found, which may very well be null
+        return (Map) propertiesByNameInAllConfigs.get(name);
+    }
+
+
+    /**
+     * Convenience method for retrieving the JPA persistence unit by the given
+     * name.  This method is equivalent to
+     * calling {@link #getPMFFromEMF(String,ClassLoader)} with the context ClassLoader.
+     * @param name The persistence unit name.
+     * @see #getPMFFromEMF(String,ClassLoader)
+     * @return The named EMF cast as a PMF.
+     */
+    protected static PersistenceManagerFactory getPMFFromEMF(String name) {
+        return getPMFFromEMF(name, getContextClassLoader());
+    }
+
+    /**
+     * Attempts to locate a <code>javax.persistence.EntityManagerFactory</code>
+     * via the <code>javax.persistence.Persistence</code> method
+     * <code>createEntityManagerFactory(String)</code>
+     * and casts it to a {@link PersistenceManagerFactory}.  It is a user error
+     * if his chosen JPA vendor's <code>EntityManagerFactory</code>
+     * implementation class does not also implement
+     * {@link PersistenceManagerFactory}.
+     * @param name The persistence unit name.
+     * @param loader The classloader used to attempt loading of the class
+     * <code>javax.persistence.Persistence</code>
+     * and <code>javax.persistence.PersistenceException</code>.
+     * @return The <code>EntityManagerFactory</code>, cast as a
+     * <code>PersistenceManagerFactory</code> for the given
+     * persistence unit name, or <code>null</code> if any of the following
+     * conditions are true.
+     *  <ul>
+     *    <li>The attempt to load <code>javax.persistence.Persistence</code> or
+     *          <code>javax.persistence.Persistence</code> fails for any
+     *        reason.</li>
+     *    <li>The named JPA persistence unit is not found.</li>
+     *  </ul>
+     * @throws JDOFatalUserException This method will throw
+     * a {@link JDOFatalUserException}
+     * with the exception that caused the error
+     * if any of the following conditions are true.
+     * <ul>
+     *  <li>The <code>javax.persistence.Persistence</code> method
+     *      <code>createEntityManagerFactory(String)</code>
+     *      cannot be invoked.</li>
+     *  <li>The <code>javax.persistence.EntityManagerFactory</code> cannot be
+     *      cast to a
+     *      <code>{@link PersistenceManagerFactory}</code>.</li>
+     * </ul>
+     */
+    protected static PersistenceManagerFactory getPMFFromEMF(
+        String name, ClassLoader loader
+    ) {
+        /*
+            This implementation uses reflection to try to get an EMF so that
+            javax.jdo, a Java SE API, does not introduce an unnecessary
+            dependency on a Java EE API, namely the
+            javax.persistence.Persistence class, while still
+            being compatible with JPA.
+         */
+
+        // First, get required classes & methods
+        Class persistenceClass = null;
+        Class persistenceExceptionClass = null;
+        Method createEntityManagerFactoryMethod = null;
+        try {
+            persistenceClass = Class.forName(
+                "javax.persistence.Persistence",
+                true,
+                loader);
+
+            createEntityManagerFactoryMethod = persistenceClass.getMethod(
+                    "createEntityManagerFactory",
+                    new Class[] { String.class });
+
+            persistenceExceptionClass =
+                Class.forName(
+                    "javax.persistence.PersistenceException",
+                    true,
+                    loader);
+        }
+        catch (Exception x) {
+            // may happen -- if it does, javax.persistence.Persistence or
+            // requisites not available
+            return null;
+        }
+
+        // Now, try to invoke createEntityManagerFactory method
+        Object entityManagerFactory = null;
+        Throwable t = null;
+        try {
+            entityManagerFactory =
+                createEntityManagerFactoryMethod.invoke(
+                    persistenceClass, new Object[] { name });
+        }
+        catch (RuntimeException x) {
+            if (persistenceExceptionClass.isAssignableFrom(x.getClass())) {
+                // named persistence unit not found
+                return null;
+            }
+            // else something else went wrong
+            t = x;
+        }
+        catch (Exception x) {
+            t = x;
+        }
+        if (t != null) { // something went wrong -- throw
+            throw new JDOFatalUserException(
+                msg.msg("EXC_UnableToInvokeCreateEMFMethod"), t);
+        }
+
+        // Last, try to cast to PMF & return
+        try {
+            return (PersistenceManagerFactory) entityManagerFactory;
+        }
+        catch (ClassCastException x) { // EMF impl doesn't also implement PMF
+            throw new JDOFatalUserException(
+                msg.msg(
+                    "EXC_UnableToCastEMFToPMF",
+                    entityManagerFactory.getClass().getName()),
+                x);
+        }
+    }
+
+    /** Reads JDO configuration file, creates a Map for each
+     * persistence-manager-factory, then returns the map.
+     * @param url URL of a JDO configuration file compliant with
+     * javax/jdo/jdoconfig.xsd.
+     * @param requestedPersistenceUnitName The name of the requested
+     * persistence unit (allows for fail-fast).
+     * @param factory The <code>DocumentBuilderFactory</code> to use for XML
+     * parsing.
+     * @return a Map<String,Map> holding persistence unit configurations; for
+     * the anonymous persistence unit, the
+     * value of the String key is the empty string, "".
+     */
+    protected static Map/*<String,Map>*/ readPersistenceUnitProperties(
+        URL url,
+        String requestedPersistenceUnitName,
+        DocumentBuilderFactory factory
+    ) {
+        requestedPersistenceUnitName = requestedPersistenceUnitName == null
+            ? ""
+            : requestedPersistenceUnitName.trim();
+
+        Map propertiesByName = new HashMap();
+        InputStream in = null;
+        try {
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            in = url.openStream();
+            Document doc = builder.parse(in);
+
+            Element root = doc.getDocumentElement();
+            if (root == null) {
+                throw new JDOFatalUserException(
+                    msg.msg("EXC_InvalidJDOConfigNoRoot", url.toExternalForm())
+                );
+            }
+
+            // TODO:  prefer using namespace-aware APIs
+            NodeList pmfs = root.getElementsByTagName(
+                ELEMENT_PERSISTENCE_MANAGER_FACTORY);
+
+            for(int i = 0; i < pmfs.getLength(); i++) {
+                Node pmfElement = pmfs.item(i);
+
+                Properties pmfPropertiesFromAttributes
+                    = readPropertiesFromPMFElementAttributes(pmfElement);
+
+                Properties pmfPropertiesFromElements
+                    = readPropertiesFromPMFSubelements(pmfElement, url);
+
+                // for informative error handling, get PU name (or names) now
+                String puNameFromAtts =
+                    pmfPropertiesFromAttributes.getProperty(
+                        PROPERTY_PERSISTENCE_UNIT_NAME);
+                String puNameFromElem =
+                    pmfPropertiesFromElements.getProperty(
+                        PROPERTY_PERSISTENCE_UNIT_NAME);
+
+                String puName = null;
+                if (nullOrBlank(puNameFromAtts)) {
+                    // no PU name attribute given
+                    if (!nullOrBlank(puNameFromElem)) {
+                        // PU name element was given
+                        puName = puNameFromElem;
+                    }
+                    else  {
+                        // PU name not given at all, means the "anonymous" PU
+                        puName = "";
+                    }
+                }
+                else {
+                    // PU name given in an attribute
+                    if (!nullOrBlank(puNameFromElem)) {
+                        // exception -- PU name given as both att & elem
+                        throw new JDOFatalUserException(
+                            msg.msg(
+                                "EXC_DuplicatePersistenceUnitNamePropertyFoundWithinUnitConfig",
+                                puNameFromAtts,
+                                puNameFromElem,
+                                url.toExternalForm()));
+                    }
+                    puName = puNameFromAtts;
+                }
+                puName = puName == null ? "" : puName.trim();
+
+                // check for duplicate properties among atts & elems
+                if (requestedPersistenceUnitName.equals(puName)) {
+                    Iterator it =
+                        pmfPropertiesFromAttributes.keySet().iterator();
+                    while (it.hasNext()) {
+                        String property = (String) it.next();
+                        if (pmfPropertiesFromElements.contains(property)) {
+                            throw new JDOFatalUserException(
+                                msg.msg(
+                                    "EXC_DuplicatePropertyFound",
+                                    property,
+                                    puName,
+                                    url.toExternalForm()));
+                        }
+                    }
+                }
+                
+                // at this point, we're guaranteed not to have duplicate
+                // properties -- merge them
+                Properties pmfProps = new Properties();
+                pmfProps.putAll(pmfPropertiesFromAttributes);
+                pmfProps.putAll(pmfPropertiesFromElements);
+
+                // check for duplicate requested PU name
+                if (puName.equals(requestedPersistenceUnitName)
+                    && propertiesByName.containsKey(puName)) {
+
+                    throw new JDOFatalUserException(msg.msg(
+                        "EXC_DuplicateRequestedPersistenceUnitFoundInSameConfig",
+                        puName,
+                        url.toExternalForm()));
+                }
+                propertiesByName.put(puName, pmfProps);
+            }
+            return propertiesByName;
+        }
+        catch (IOException ioe) {
+            throw new JDOFatalUserException(
+                msg.msg("EXC_GetPMFIOExceptionRsrc", url.toString()),
+                ioe); //NOI18N
+        }
+        catch (ParserConfigurationException e) {
+            throw new JDOFatalUserException(
+                msg.msg("EXC_ParserConfigException"),
+                e);
+        }
+        catch (SAXException e) {
+            throw new JDOFatalUserException(
+                msg.msg("EXC_ParsingException", url.toExternalForm()),
+                e);
+        }
+        catch (JDOException e) {
+            throw e;
+        }
+        catch (RuntimeException e) {
+            throw new JDOFatalUserException(
+                msg.msg("EXC_ParsingException", url.toExternalForm()),
+                e);
         }
         finally {
-            if (in != null)
+            if (in != null) {
                 try {
-                    in.close (); 
-                } catch (IOException ioe) { }
+                    in.close();
+                }
+                catch (IOException ioe) { /* gulp */ }
+            }
+        }
+    }
+
+    protected static Properties readPropertiesFromPMFElementAttributes(
+        Node pmfElement
+    ) {
+        Properties p = new Properties();
+        NamedNodeMap attributes = pmfElement.getAttributes();
+        if (attributes == null) {
+            return p;
+        }
+
+        for(int i = 0; i < attributes.getLength(); i++) {
+            Node att = attributes.item(i);
+            String attName = att.getNodeName();
+            String attValue = att.getNodeValue().trim();
+
+            String jdoPropertyName =
+                (String) ATTRIBUTE_PROPERTY_XREF.get(attName);
+
+            p.put(
+                jdoPropertyName != null
+                    ? jdoPropertyName
+                    : attName,
+                attValue);
         }
 
-        return getPersistenceManagerFactory (props, pmfLoader);
+        return p;
     }
 
+    protected static Properties readPropertiesFromPMFSubelements(
+        Node pmfElement, URL url)
+    {
+        Properties p = new Properties();
+        NodeList elements = pmfElement.getChildNodes();
+        if (elements == null) {
+            return p;
+        }
+        for(int i = 0; i < elements.getLength(); i++) {
+            Node element = elements.item(i);
+            if (element.getNodeType() != Node.ELEMENT_NODE) {
+                continue;
+            }
+            
+            String elementName = element.getNodeName();
+            NamedNodeMap attributes = element.getAttributes();
+            if (ELEMENT_PROPERTY.equalsIgnoreCase(elementName)) {
+                // <property name="..." value="..."/>
+
+                // get the "name" attribute's value (required)
+                Node nameAtt = attributes.getNamedItem(PROPERTY_ATTRIBUTE_NAME);
+                if (nameAtt == null) {
+                    throw new JDOFatalUserException(
+                        msg.msg("EXC_PropertyElementHasNoNameAttribute", url));
+                }
+                String name = nameAtt.getNodeValue().trim();
+                if ("".equals(name)) {
+                    throw new JDOFatalUserException(
+                        msg.msg(
+                            "EXC_PropertyElementNameAttributeHasNoValue",
+                            name,
+                            url));
+                }
+                // The next call allows users to use either the
+                // <persistence-manager-factory> attribute names or the
+                // "javax.jdo" property names in <property> element "name"
+                // attributes.  Handy-dandy.
+                String jdoPropertyName =
+                    (String) ATTRIBUTE_PROPERTY_XREF.get(name);
+                
+                String propertyName = jdoPropertyName != null
+                        ? jdoPropertyName
+                        : name;
+
+                if (p.containsKey(propertyName)) {
+                    throw new JDOFatalUserException(
+                        msg.msg(
+                            "EXC_DuplicatePropertyNameGivenInPropertyElement",
+                            propertyName,
+                            url));
+                }
+
+                // get the "value" attribute's value (optional)
+                Node valueAtt = attributes.getNamedItem(
+                    PROPERTY_ATTRIBUTE_VALUE);
+                String value = valueAtt == null
+                    ? null
+                    : valueAtt.getNodeValue().trim();
+
+                p.put(propertyName, value);
+            }
+            else if (ELEMENT_INSTANCE_LIFECYCLE_LISTENER.equals(elementName)) {
+                // <instance-lifecycle-listener listener="..." classes="..."/>
+
+                // get the "listener" attribute's value
+                Node listenerAtt = attributes.getNamedItem(
+                    INSTANCE_LIFECYCLE_LISTENER_ATTRIBUTE_LISTENER);
+                if (listenerAtt == null) {
+                    throw new JDOFatalUserException(
+                        msg.msg(
+                            "EXC_MissingListenerAttribute",
+                            url));
+                }
+                String listener = listenerAtt.getNodeValue().trim();
+                if ("".equals(listener)) {
+                    throw new JDOFatalUserException(
+                        msg.msg(
+                            "EXC_MissingListenerAttributeValue",
+                            url));
+                }
+
+                // listener properties are of the form
+                // "javax.jdo.option.InstanceLifecycleListener." + listener
+                listener =
+                    PROPERTY_PREFIX_INSTANCE_LIFECYCLE_LISTENER + listener;
+
+                // get the "classes" attribute's value (optional)
+                Node classesAtt = attributes.getNamedItem(
+                    INSTANCE_LIFECYCLE_LISTENER_ATTRIBUTE_CLASSES);
+                String value = classesAtt == null
+                    ? null
+                    : classesAtt.getNodeValue().trim();
 
+                p.put(listener,  value);
+            }
+        }
+        return p;
+    }
+
+    protected static boolean nullOrBlank(String s) {
+        return s == null || "".equals(s.trim());
+    }
+    
     /**
      * Returns a {@link PersistenceManagerFactory} configured based
      * on the properties stored in the file at

Modified: db/jdo/trunk/api20/src/java/javax/jdo/PersistenceManagerFactory.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/src/java/javax/jdo/PersistenceManagerFactory.java?view=diff&rev=524803&r1=524802&r2=524803
==============================================================================
--- db/jdo/trunk/api20/src/java/javax/jdo/PersistenceManagerFactory.java (original)
+++ db/jdo/trunk/api20/src/java/javax/jdo/PersistenceManagerFactory.java Mon Apr  2 08:42:42 2007
@@ -25,6 +25,8 @@
 import java.util.Properties;
 import java.util.Collection;
 
+import java.io.Serializable;
+
 import javax.jdo.datastore.DataStoreCache;
 
 import javax.jdo.listener.InstanceLifecycleListener;
@@ -54,21 +56,8 @@
  * @version 2.1
  */
 
-public interface PersistenceManagerFactory extends java.io.Serializable {
-
-    /** 
-     * The value for TransactionType to specify that transactions
-     * are managed by the Java Transactions API, as documented in 
-     * JSR-220.
-     */
-    public static final String JTA = "JTA";
+public interface PersistenceManagerFactory extends Serializable {
 
-    /** 
-     * The value for TransactionType to specify that transactions
-     * are managed by the javax.jdo.Transaction instance, similar
-     * to the usage as documented in JSR-220.
-     */
-    public static final String RESOURCE_LOCAL = "RESOURCE_LOCAL";
     
     /** Close this PersistenceManagerFactory. Check for 
      * JDOPermission("closePersistenceManagerFactory") and if not authorized, 
@@ -425,8 +414,8 @@
      * This has the same semantics as the same-named property in
      * JSR-220 EntityManagerFactory.
      * @see #getTransactionType()
-     * @see #JTA
-     * @see #RESOURCE_LOCAL
+     * @see Constants#JTA
+     * @see Constants#RESOURCE_LOCAL
      * @since 2.1
      * @param name the TransactionType
      * @throws JDOUserException if the parameter is not a permitted value

Added: db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.dtd
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.dtd?view=auto&rev=524803
==============================================================================
--- db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.dtd (added)
+++ db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.dtd Mon Apr  2 08:42:42 2007
@@ -0,0 +1,50 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<!--
+<!DOCTYPE jdoconfig
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Java Data Objects Configuration 2.1//EN"
+    "http://java.sun.com/dtd/jdoconfig_2_1.dtd">
+-->
+<!ELEMENT jdoconfig (persistence-manager-factory+)>
+
+<!ELEMENT persistence-manager-factory (property*, instance-lifecycle-listener*)>
+<!ATTLIST persistence-manager-factory class CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory persistence-unit-name CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory optimistic (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory retain-values (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory restore-values (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory ignore-cache (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory nontransactional-read (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory nontransactional-write (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory multithreaded (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory connection-driver-name CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory connection-user-name CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory connection-password CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory connection-url CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory connection-factory-name CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory connection-factory2-name CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory mapping CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory detach-all-on-commit (true|false) CDATA #IMPLIED>
+<!ATTLIST persistence-manager-factory server-time-zone-id CDATA #IMPLIED>
+
+<!ELEMENT property EMPTY>
+<!ATTLIST property name CDATA #REQUIRED>
+<!ATTLIST property value CDATA #IMPLIED>
+
+<!ELEMENT instance-lifecycle-listener EMPTY>
+<!ATTLIST instance-lifecycle-listener listener CDATA #REQUIRED>
+<!ATTLIST instance-lifecycle-listener classes CDATA #IMPLIED>

Added: db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.xsd
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.xsd?view=auto&rev=524803
==============================================================================
--- db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.xsd (added)
+++ db/jdo/trunk/api20/src/schema/javax/jdo/jdoconfig_2_1.xsd Mon Apr  2 08:42:42 2007
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<xs:schema
+    targetNamespace="http://java.sun.com/xml/ns/jdo/jdoconfig"
+    xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    xmlns:jdoconfig="http://java.sun.com/xml/ns/jdo/jdoconfig"
+    elementFormDefault="qualified"
+    attributeFormDefault="unqualified"
+    version="2.1">
+    <xs:annotation>
+        <xs:documentation>
+            This is the XML Schema for the JDO configuration file.
+        </xs:documentation>
+    </xs:annotation>
+
+    <xs:element name="jdoconfig">
+        <xs:complexType>
+            <xs:annotation>
+                <xs:documentation>
+                    The root configuration element for JDO.
+                </xs:documentation>
+            </xs:annotation>
+            <xs:sequence>
+                <xs:element name="persistence-manager-factory" minOccurs="1"
+                            maxOccurs="unbounded">
+                    <xs:complexType>
+                        <xs:annotation>
+                            <xs:documentation>
+                                Standard JDO PersistenceManagerFactory
+                                configuration properties.
+                                Vendor-specific properties are set using
+                                additional vendor-specific attributes and/or
+                                property elements.
+                            </xs:documentation>
+                        </xs:annotation>
+                        <xs:sequence minOccurs="0" maxOccurs="1">
+                            <xs:element name="property" minOccurs="0"
+                                        maxOccurs="unbounded">
+                                <xs:complexType>
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            Vendor-specific properties.
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                    <xs:attributeGroup ref="attlist.property"/>
+                                </xs:complexType>
+                            </xs:element>
+                            <xs:element name="instance-lifecycle-listener"
+                                        minOccurs="0" maxOccurs="unbounded">
+                                <xs:complexType>
+                                    <xs:annotation>
+                                        <xs:documentation>
+                                            javax.jdo.listener.InstanceLifecycleListener
+                                            instance configuration.
+                                            There is one
+                                            instance-lifecycle-listener element
+                                            per listener instance.
+                                            Only one instance of the listener
+                                            class is supported in this
+                                            configuration file.
+                                            If multiple instances of the same
+                                            listener class is required, then the
+                                            API
+                                            PersistenceManagerFactory.addInstanceLifecycleListener(...)
+                                            must be used.
+
+                                            If attribute "classes" is missing,
+                                            all persistence-capable instances
+                                            are observed,
+                                            otherwise it is a comma- or
+                                            whitespace-delimited list of
+                                            persistence-capable
+                                            classes whose instances' will be
+                                            observed.
+                                        </xs:documentation>
+                                    </xs:annotation>
+                                    <xs:attributeGroup
+                                        ref="attlist.instance-lifecycle-listener"/>
+                                </xs:complexType>
+                            </xs:element>
+                        </xs:sequence>
+                        <xs:attributeGroup
+                            ref="attlist.persistence-manager-factory"/>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+            <xs:attributeGroup ref="attlist.jdoconfig"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:attributeGroup name="attlist.jdoconfig"/>
+
+    <xs:attributeGroup name="attlist.persistence-manager-factory">
+        <xs:annotation>
+            <xs:documentation>
+                These are attributes corresponding to the standard properties
+                defined in JDO 2.1.
+                Any other attributes present, if unrecognized by a JDO
+                implementation, may be silently ignored.
+            </xs:documentation>
+        </xs:annotation>
+
+        <!-- Corresponds to standard JDO property javax.jdo.PersistenceManagerFactoryClass. -->
+        <xs:attribute name="class" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.PersistenceUnitName.  The absence of this attributes implies the anonymous persistence unit. -->
+        <xs:attribute name="persistence-unit-name" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.Optimistic. -->
+        <xs:attribute name="optimistic" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.RetainValues. -->
+        <xs:attribute name="retain-values" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.RestoreValues. -->
+        <xs:attribute name="restore-values" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.IgnoreCache. -->
+        <xs:attribute name="ignore-cache" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.NontransactionalRead. -->
+        <xs:attribute name="nontransactional-read" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.NontransactionalWrite. -->
+        <xs:attribute name="nontransactional-write" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.Multithreaded. -->
+        <xs:attribute name="multithreaded" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ConnectionDriverName. -->
+        <xs:attribute name="connection-driver-name" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ConnectionUserName. -->
+        <xs:attribute name="connection-user-name" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ConnectionPassword. -->
+        <xs:attribute name="connection-password" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ConnectionURL. -->
+        <xs:attribute name="connection-url" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ConnectionFactoryName. -->
+        <xs:attribute name="connection-factory-name" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ConnectionFactory2Name. -->
+        <xs:attribute name="connection-factory2-name" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.Mapping. -->
+        <xs:attribute name="mapping" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.DetachAllOnCommit. -->
+        <xs:attribute name="detach-all-on-commit" use="optional"/>
+        <!-- Corresponds to standard JDO property javax.jdo.option.ServerTimeZoneID. -->
+        <xs:attribute name="server-time-zone-id" use="optional"/>
+        <!-- Any other vendor-specific attributes are allowed and passed literally to the underlying implementation. -->
+        <xs:anyAttribute processContents="lax"/>
+    </xs:attributeGroup>
+
+    <xs:attributeGroup name="attlist.property">
+        <!-- The name of the vendor-specific property. -->
+        <xs:attribute name="name" use="required"/>
+        <!-- The value of the vendor-specific property. -->
+        <xs:attribute name="value" use="optional"/>
+    </xs:attributeGroup>
+
+    <xs:attributeGroup name="attlist.instance-lifecycle-listener">
+        <!-- The name of the listener class to instantiate. -->
+        <xs:attribute name="listener" use="required"/>
+        <!-- Comma- or whitespace-delimited list of persistence-capable classes whose instances to observe.  The absence of this attribute means to observe all. -->
+        <xs:attribute name="classes" use="optional"/>
+    </xs:attributeGroup>
+
+</xs:schema>

Added: db/jdo/trunk/api20/test/java/javax/jdo/ClasspathHelper.java
URL: http://svn.apache.org/viewvc/db/jdo/trunk/api20/test/java/javax/jdo/ClasspathHelper.java?view=auto&rev=524803
==============================================================================
--- db/jdo/trunk/api20/test/java/javax/jdo/ClasspathHelper.java (added)
+++ db/jdo/trunk/api20/test/java/javax/jdo/ClasspathHelper.java Mon Apr  2 08:42:42 2007
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.jdo;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class ClasspathHelper {
+
+    private static URLClassLoader SYSTEM_CLASSLOADER = (URLClassLoader) ClassLoader.getSystemClassLoader();
+    private static Method METHOD;
+    static {
+        try {
+            METHOD = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
+            METHOD.setAccessible(true);
+        }
+        catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    public static void addFile(String s) throws IOException {
+        addFile(s, null);
+    }
+
+    public static void addFile(File f) throws IOException {
+        addFile(f, null);
+    }
+
+    public static void addURL(URL u) throws IOException {
+        addURL(u, null);
+    }
+
+    public static void addFile(String s, URLClassLoader loader) throws IOException {
+        addFile(new File(s), loader);
+    }
+
+    public static void addFile(File f, URLClassLoader loader) throws IOException {
+        addURL(f.toURL(), loader);
+    }
+
+    public static void addURL(URL u, URLClassLoader loader) throws IOException {
+        if (loader == null) {
+            loader = SYSTEM_CLASSLOADER;
+        }
+        try {
+            METHOD.invoke(loader, new Object[] { u });
+        }
+        catch (Throwable t) {
+            throw new IOException("Could not add URL to system classloader: " + t.getMessage());
+        }
+    }
+}
+