Index: src/java/javax/jdo/JDOHelper.java
===================================================================
--- src/java/javax/jdo/JDOHelper.java (revision 632419)
+++ src/java/javax/jdo/JDOHelper.java (working copy)
@@ -58,6 +58,7 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import java.util.Enumeration;
import java.io.IOException;
@@ -760,19 +761,8 @@
String pmfClassName = (String) props.get (
PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS);
- if (pmfClassName == null) {
- // no PMF class name property -- try to find via services lookup
+ if (!isNullOrBlank(pmfClassName)) {
try {
- pmfClassName = getPMFClassNameViaServiceLookup(pmfClassLoader);
- }
- catch (IOException e) {
- throw new JDOFatalInternalException(msg.msg(
- "EXC_IOExceptionDuringServiceLookup"), e); // NOI18N
- }
- }
-
- if (pmfClassName != null) {
- try {
Class pmfClass = forName(pmfClassName, true, pmfClassLoader);
Method pmfMethod = getMethod(pmfClass,
"getPersistenceManagerFactory", //NOI18N
@@ -804,14 +794,24 @@
throw new JDOFatalInternalException (msg.msg(
"EXC_GetPMFUnexpectedException"), e); //NOI18N
}
+ } else {
+ // PMF class name property is null or blank -- try to find via services
+ List pmfClassNames = getPMFClassNamesViaServiceLookup(pmfClassLoader);
+ try {
+ pmfClassName = getPMFClassNameViaServiceLookup(pmfClassLoader);
+ }
+ catch (IOException e) {
+ throw new JDOFatalInternalException(msg.msg(
+ "EXC_IOExceptionDuringServiceLookup"), e); // NOI18N
+ }
}
-
- // else no PMF class name given; check PU name
+
+ // else no PMF class name given; try services lookup
String puName = (String) props.get(PROPERTY_PERSISTENCE_UNIT_NAME);
- if (puName != null && !"".equals(puName.trim())) {
+ if (!isNullOrBlank(puName)) {
PersistenceManagerFactory pmf =
- getPMFFromEMF(puName, props, pmfClassLoader);
+ getPMFFromPersistenceUnitName(puName, props, pmfClassLoader);
if (pmf != null) {
return pmf;
@@ -848,16 +848,63 @@
protected static String getPMFClassNameViaServiceLookup(ClassLoader cl)
throws IOException
{
- /*
- Note: not using sun.misc.Service because it's not a standard part of
- the JDK (yet).
- */
InputStream is = getResourceAsStream(cl,
SERVICE_LOOKUP_PMF_RESOURCE_NAME);
if (is == null) {
return null;
}
+ return getClassNameFromServicesInputStream(is);
+ }
+
+ /**
+ * Looks up a (@link PersistenceManagerFactory} implementation class name
+ * from the resource
+ * META-INF/services/javax.jdo.PersistenceManagerFactory,
+ * which should be a text file whose
+ * only contents are the fully qualified name of a class that implements
+ * {@link PersistenceManagerFactory}.
+ * Note that the method
+ * {@link java.lang.ClassLoader#getResourceAsStream(String)} is used to
+ * find the resource.
+ * Only the first implementation class name found in the resource is used.
+ * @param cl The ClassLoader used to find the resource.
+ * @return a list of resource names found in the resource files; should be
+ * PMF implementation class names; null and blank names are removed
+ */
+ protected static List/**/ getPMFClassNamesViaServiceLookup(ClassLoader cl)
+ {
+ List resourceNames = new ArrayList();
+ Enumeration resources;
+ try {
+ resources = getResources(cl, SERVICE_LOOKUP_PMF_RESOURCE_NAME);
+
+ } catch (IOException iOException) {
+ // no resources
+ return resourceNames;
+ }
+
+ while (resources.hasMoreElements()) {
+ URL resource = (URL)resources.nextElement();
+ try {
+ InputStream is = resource.openStream();
+ String name = getClassNameFromServicesInputStream(is);
+ if (!isNullOrBlank(name)) {
+ resourceNames.add(name);
+ }
+ } catch (IOException iOException) {
+ // never mind; try the next resource
+ }
+ }
+ return resourceNames;
+ }
+
+ /** Get a class name from a stream in resources format.
+ *
+ */
+ protected static String getClassNameFromServicesInputStream
+ (InputStream is) throws IOException
+ {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
try {
@@ -1073,34 +1120,20 @@
"EXC_GetPMFNoPMFClassNamePropertyOrPUNameProperty"));
}
- try {
- return invokeGetPersistenceManagerFactoryOnImplementation(
+ return invokeGetPersistenceManagerFactoryOnImplementation(
pmfClassName, overrides, properties, pmfLoader);
- } catch (ClassNotFoundException e) {
- throw new JDOFatalUserException(msg.msg(
- "EXC_GetPMFClassNotFound", pmfClassName), e);
- } catch (NoSuchMethodException e) {
- throw new JDOFatalUserException(msg.msg(
- "EXC_GetPMFNoSuchMethod2", pmfClassName), e);
- } catch (IllegalAccessException e) {
- throw new JDOFatalUserException(msg.msg(
- "EXC_GetPMFIllegalAccess", pmfClassName), e);
- } catch (InvocationTargetException e) {
- throw new JDOFatalUserException(msg.msg(
- "EXC_GetPMFInvocationTargetException", pmfClassName), e);
- }
}
- // else no properties found; next, assume name is a JPA PU name
+ // else no properties found; see if name is a JPA PU name
if (!ANONYMOUS_PERSISTENCE_MANAGER_FACTORY_NAME.equals(name)) {
PersistenceManagerFactory pmf =
- getPMFFromEMF(name, overrides, pmfLoader);
+ getPMFFromPersistenceUnitName(name, overrides, pmfLoader);
if (pmf != null) {
return pmf;
}
}
- // else no PMF found
+ // no PMF found
throw new JDOFatalUserException (msg.msg (
"EXC_NoPMFConfigurableViaPropertiesOrXML",
name)); //NOI18N
@@ -1109,19 +1142,28 @@
protected static PersistenceManagerFactory
invokeGetPersistenceManagerFactoryOnImplementation(
String pmfClassName, Map overrides, Map properties, ClassLoader cl)
- throws
- ClassNotFoundException,
- NoSuchMethodException,
- IllegalAccessException,
- InvocationTargetException
{
- Class implClass = forName(pmfClassName, true, cl);
- Method m = getMethod(implClass,
- "getPersistenceManagerFactory",
- new Class[] { Map.class, Map.class });
+ try {
+ Class implClass = forName(pmfClassName, true, cl);
+ Method m = getMethod(implClass,
+ "getPersistenceManagerFactory",
+ new Class[]{Map.class, Map.class});
+ return (PersistenceManagerFactory) invoke(m,
+ null, new Object[]{overrides, properties});
- return (PersistenceManagerFactory) invoke(m,
- null, new Object[] {overrides, properties});
+ } catch (ClassNotFoundException e) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_GetPMFClassNotFound", pmfClassName), e);
+ } catch (NoSuchMethodException e) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_GetPMFNoSuchMethod2", pmfClassName), e);
+ } catch (IllegalAccessException e) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_GetPMFIllegalAccess", pmfClassName), e);
+ } catch (InvocationTargetException e) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_GetPMFInvocationTargetException", pmfClassName), e);
+ }
}
@@ -1178,8 +1220,8 @@
*/
protected static Map getNamedPMFProperties(
String name,
- ClassLoader resourceLoader
- ) {
+ ClassLoader resourceLoader)
+ {
return getNamedPMFProperties(
name, resourceLoader, JDOCONFIG_RESOURCE_NAME);
}
@@ -1209,8 +1251,8 @@
protected static Map getNamedPMFProperties(
String name,
ClassLoader resourceLoader,
- String jdoconfigResourceName
- ) {
+ String jdoconfigResourceName)
+ {
// key is PU name, value is Map of PU properties
Map/**/ propertiesByNameInAllConfigs
= new HashMap/**/();
@@ -1326,6 +1368,29 @@
}
/**
+ * Attempts to load a PersistenceManagerFactory by using the name as a
+ * javax.jdo.PersistenceUnitName. This is done by constructing a
+ * properties instance with the name set as the value of
+ * javax.jdo.PersistenceUnitName and then invoking the
+ * PersistenceManagerFactory service on all implementations.
+ */
+ protected static PersistenceManagerFactory getPMFFromPersistenceUnitName(
+ String name, Map overrides, ClassLoader loader)
+ {
+ Properties props = new Properties();
+ props.put(PROPERTY_PERSISTENCE_UNIT_NAME, name);
+ List pmfNames = getPMFClassNamesViaServiceLookup(loader);
+ PersistenceManagerFactory pmf = null;
+ for (Iterator it = pmfNames.iterator(); it.hasNext();) {
+ String pmfName = (String)it.next();
+ pmf = invokeGetPersistenceManagerFactoryOnImplementation(
+ pmfName, props, overrides, loader);
+ if (pmf != null) break;
+ }
+ return pmf;
+ }
+
+ /**
* Attempts to locate a javax.persistence.EntityManagerFactory
* via the javax.persistence.Persistence method
* createEntityManagerFactory(String)
@@ -1496,9 +1561,9 @@
pmfPropertiesFromElements.getProperty(PROPERTY_NAME);
String pmfName = null;
- if (nullOrBlank(pmfNameFromAtts)) {
+ if (isNullOrBlank(pmfNameFromAtts)) {
// no PMF name attribute given
- if (!nullOrBlank(pmfNameFromElem)) {
+ if (!isNullOrBlank(pmfNameFromElem)) {
// PMF name element was given
pmfName = pmfNameFromElem;
}
@@ -1509,7 +1574,7 @@
}
else {
// PMF name given in an attribute
- if (!nullOrBlank(pmfNameFromElem)) {
+ if (!isNullOrBlank(pmfNameFromElem)) {
// exception -- PMF name given as both att & elem
throw new JDOFatalUserException(
msg.msg(
@@ -1726,7 +1791,7 @@
return p;
}
- protected static boolean nullOrBlank(String s) {
+ protected static boolean isNullOrBlank(String s) {
return s == null || "".equals(s.trim());
}