[
https://issues.apache.org/jira/browse/JDO-545?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Matthew T. Adams updated JDO-545:
---------------------------------
Attachment: (was: jdo-545.v01.patch)
> Allow users to supply property-overriding Map instances when configuring from
> resources (properties, jdoconfig.xml, or persistence.xml)
> ---------------------------------------------------------------------------------------------------------------------------------------
>
> Key: JDO-545
> URL: https://issues.apache.org/jira/browse/JDO-545
> Project: JDO
> Issue Type: Improvement
> Components: api2, api2-legacy
> Affects Versions: JDO 2 maintenance release 1
> Reporter: Matthew T. Adams
> Assignee: Matthew T. Adams
> Fix For: JDO 2 maintenance release 1
>
>
> See my changes inline below, enclosed by "<<<" and ">>>", and my comments.
> -matthew
> On Oct 1, 2007, at 2:07 PM, Craig L Russell wrote:
> Javadogs,
> I've completed the specification update for these methods. Please take a look
> and comment:
> Note that this section doesn't exactly match what Matthew has already
> implemented, but really close...
> <proposed>
> PersistenceManagerFactory methods
> The methods in this section provide for bootstrapping the
> PersistenceManagerFactory by configuration according to the properties
> documented in Section 11.1. Users have a choice of configuration techniques:
> The application provides a Map of properties used to construct a
> PersistenceManagerFactory
> The application provides a Map of override properties and <<<the name of a
> resource in standard Java Properties format, the name of a named
> PersistenceManagerFactory, or a JPA persistence unit name>>> that are used to
> construct a PersistenceManagerFactory
> The application provides the name of a resource in standard Java Properties
> format whose contents define the properties for the PersistenceManagerFactory
> The application provides an InputStream in standard Java Properties format
> whose contents define the properties for the PersistenceManagerFactory
> The application provides a File whose contents are in standard Java
> Properties format which define the properties for the
> PersistenceManagerFactory
> The application provides a JNDI name and context in which the name is defined
> The application provides a resource named META-INF/jdoconfig.xml and
> optionally META-INF/services/javax.jdo.PersistenceManagerFactory which
> contain configuration information
> The application provides a resource named META-INF/persistence.xml and
> optionally META-INF/services/javax.persistence.EntityManagerFactory which
> contain configuration information
> For the cases of InputStream, File, and resource name, a Properties instance
> is constructed by JDOHelper and passed to one of the
> getPersistenceManagerFactory(Map) methods. When using these techniques, each
> configuration of PersistenceManagerFactory is contained <<<either in a Java
> Properties resource, in a META-INF/jdoconfig.xml and optionally a
> META-INF/services/javax.jdo.PersistenceManagerFactory, or in a
> META-INF/persistence.xml and optionally a
> META-INF/services/javax.persistence.EntityManagerFactory. The >>>
> propsLoader parameter is used only to load the resource to construct the Map.
> Once the Map with configuration information is obtained, the loader is used
> for loading all other resour<<<c>>>es,
> Comment: I'm confused about what the "propsLoader" and the "loader" are.
> I'll assume the "propsLoader" is the ClassLoader used to load resources
> required to build the Properties instance (aka "Map"), and the "loader" is
> the ClassLoader used to load classes and whatever other resources whose
> loading can't be controlled.
> including the persistence.xml, jdoconfig.xml, services locators, and
> PersistenceManagerFactory class.
> Comment: This is not true; some of these resources are loaded by
> propsLoader, some are not. If all native JDO means of creating a Properties
> instance (aka "Map") fail, we delegate to javax.persistence.Persistence, and
> we can't tell Persistence.createEntityManagerFactory(..) which ClassLoader to
> use for resource loading and which to use for class loading; in fact, we
> can't tell it anything about which ClassLoader(s) to use.
> In order to build the Properties instance (aka "Map"), the following
> resources are loaded by the propsLoader: the Java Properties resource with
> the given name, and if that's not found, all META-INF/jdoconfig.xml files on
> the classpath. If, after constructing a Properties instance there is no
> javax.jdo.PersistenceManagerFactoryClass property, then the propsLoader is
> used again to load a META-INF/services/javax.jdo.PersistenceManagerFactory;
> the exact one is determined by ClassLoader's getResourceAsStream(String)
> method. If no META-INF/jdoconfig.xml files are found or no
> PersistenceManagerFactory is found with the requested name, then JDOHelper
> delegates to javax.persistence.Persistence.createEntityManagerFactory(String)
> to look up the META-INF/persistence.xml file with the persistence unit name
> given, then casts the returned EntityManagerFactory to a
> PersistenceManagerFactory.
> A8.6-22 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (Map props, String name, ClassLoader loader);]
> A8.6-23 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (Map props, String name);]
> These methods create a new copy of the Map parameter, add the property
> "javax.jdo.option.Name" with the value of the name parameter and delegate to
> the corresponding JDOHelper method taking a Map parameter.
> Comment: This is new and not yet coded. I understand the motivation to add
> these methods (which is Persistence.createEntityManagerFactory(String,Map)),
> so I'm cool with adding these, but we'll have to tighten up the description
> of the overriding Properties, especially in the case that no Java Properties
> resource is found and the named PMF is not found. Do we pass the given Map
> down to Persistence.createEntityManagerFactory(String,Map)? I am inclined to
> say yes (see end comments plus the patch).
> A8.6-13 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (File propsFile);]
> A8.6-14 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (File propsFile, ClassLoader loader);]
> A8.6-17 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (InputStream stream);]
> A8.6-18 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (InputStream stream, ClassLoader loader);]
> These methods use the parameter(s) passed as arguments to construct a
> Properties instance, and then delegate to the JDOHelper method
> getPersistenceManagerFactory that takes a Map parameter.
> A8.6-15 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (String propsResourceName);]
> A8.6-16 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (String propsResourceName, ClassLoader loader);]
> A8.6-21[public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (String propsResourceName, ClassLoader propsLoader,
> ClassLoader pmfLoader);]
> These methods use the propsLoader getResourceAsStream method with the
> propsResourceName as an argument to obtain an InputStream, construct a new
> Properties instance, then delegate to the corresponding JDOHelper method
> getPersistenceManagerFactory that takes a Map parameter.
> Comment: Correct.
> If the named resource does not exist, JDOHelper constructs a new Map, adds a
> property named "javax.jdo.option.Name" with the value of the
> propsResourceName parameter, and then delegates to the corresponding
> JDOHelper method taking a Map parameter.
> Comment: Minor detail (see below). JDOHelper conveniently converts a null
> name to an empty string.
> The empty string (not a null string) identifies the default
> PersistenceManagerFactory name.
> Comment: JDOHelper's
> gerPersistenceManagerFactory(String[,ClassLoader[,ClassLoader]]) methods
> treat the empty string and a null string equally. Officially, the empty
> string is the name of the anonymous or unnamed PMF; null strings are just
> converted to empty strings for convenience. We should probably add a
> constant ANONYMOUS_PERSISTENCE_MANAGER_FACTOR_NAME (or
> UNNAMED_PERSISTENCE_MANAGER_FACTORY_NAME) String with the value "" to
> javax.jdo.Constants just so that it's explicit in the code. What do you
> think?
> A8.6-2 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (Map props);]
> A8.6-3 [This method delegates to the corresponding method with a class loader
> parameter, using the calling thread's current contextClassLoader as the class
> loader.]
> A8.6-1 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (Map props, ClassLoader loader);]
> This method returns a PersistenceManagerFactory based on entries contained in
> the Map parameter. Three map entries are significant to the processing of
> this method:
> javax.jdo.option.PersistenceUnitName: If not null, this identifies the name
> of the persistence unit to be accessed. The
> Persistence.createEntityManagerFactory method is called with the props and
> PersistenceUnitName as parameters. The result is cast to
> PersistenceManagerFactory and returned to the user.
> javax.jdo.option.Name: If not null, this identifies the name of the
> PersistenceManagerFactory listed in jdoconfig. The class loader loads
> META-INF/jdoconfig.xml and finds the PersistenceManagerFactory by name. If
> the value of the entry javax.jdo.option.Name is the empty string, this
> identifies the unnamed PersistenceManagerFactory listed in jdoconfig.
> JDOHelper constructs a Map instance with the contents of the jdoconfig entry
> and overrides its contents with the props parameter. Processing continues
> with PersistenceManagerFactoryClass.
> javax.jdo.PersistenceManagerFactoryClass:
> If not null, this identifies the name of the PersistenceManagerFactory class.
> JDOHelper uses the loader to resolve the PersistenceManagerFactory class name.
> A8.6-6 [If the class named by the PersistenceManagerFactoryClass property
> cannot be found, or is not accessible to the user, then JDOFatalUserException
> is thrown.] JDOHelper invokes the static method getPersistenceManagerFactory
> in the named class, passing the props as the parameter. A8.6-7 [If there is
> no public static implementation of the getPersistenceManagerFactory(Map)
> method, ]A8.6-5 [or if there are any exceptions while trying to call the
> static method,] A8.6-8 [or if the implementation of the static
> getPersistenceManagerFactory(Map) method throws an exception, then
> JDOFatalInternalException is thrown]. The nested exception indicates the root
> cause of the exception.
> Comment: Correct so far.
> If null, JDOHelper loads the PersistenceManagerFactory class using the
> services lookup pattern. That is, resources named
> META-INF/services/<<<javax.jdo.>>>PersistenceManagerFactory are loaded by the
> loader and each class in turn is used to call its static
> getPersistenceManagerFactory method, passing the props as the parameter. If
> one of the resources succeeds in returning a non-null
> PersistenceManagerFactory, it is returned to the user and any exceptions
> (thrown by other resources) are ignored. If no resource succeeds,
> JDOFatalUserException exception is thrown to the user, with a nested
> exception for each failure.
> Comment: The implementation only attempts to find one resource named
> META-INF/services/javax.jdo/PersistenceManagerFactory (via ClassLoader's
> getResourceAsStream(String) method), not all of them. Are you suggesting
> that we change this?
> The standard key values for the properties are found in Section 11.1.
> Comment: To implement support for user-supplied, property-overriding Maps, I
> suggest that we make the existing methods
> getPersistenceManagerFactory(String name)
> getPersistenceManagerFactory(String name, ClassLoader resourceLoader)
> getPersistenceManagerFactory(String name, ClassLoader resourceLoader,
> ClassLoader pmfLoader)
> and the new methods
> getPersistenceManagerFactory(Map overrides, String name)
> getPersistenceManagerFactory(Map overrides, String name, ClassLoader
> resourceLoader)
> convenience methods that delegate to the meaty method
> getPersistenceManagerFactory(Map overrides, String name, ClassLoader
> resourceLoader, ClassLoader pmfLoader)
> If I understand all of this correctly, then the last operation of this method
> before delegating to
> getPersistenceManagerFactory(Map props, ClassLoader resourceLoader,
> ClassLoader pmfLoader)
> is to replace any values in props with values from overrides. If this method
> ends up delegating instead to
> Persistence.createEntityManagerFactory(String,Map), then it will pass the
> overriding properties as the Map in that method.
> I implemented this while going through this post. Please review the attached
> patch to make sure that I got it right.
> Note that it is only in JDOHelper's getPersistenceManagerFactory(Map props,
> ClassLoader resourceLoader, ClassLoader pmfLoader method that
> META-INF/services lookup is used, and then only when there is no
> javax.jdo.PersistenceManagerFactoryClass property in props!
> JDO implementations are permitted to define key values of their own. A8.6-9
> [Any key values not recognized by the implementation must be ignored.]
> A8.6-10 [Key values that are recognized but not supported by an
> implementation must result in a JDOFatalUserException thrown by the method.]
> A8.6-11 [The returned PersistenceManagerFactory is not configurable (the
> setXXX methods will throw an exception).] A8.6-12 [JDO implementations might
> manage a map of instantiated PersistenceManagerFactory instances based on
> specified property key values, and return a previously instantiated
> PersistenceManagerFactory instance. In this case, the properties of the
> returned instance must exactly match the requested properties.]
> A8.6-19 [public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (String jndiLocation, Context context);]
> A8.6-20 [EMAIL PROTECTED] public static
> PersistenceManagerFactory getPersistenceManagerFactory
> (String jndiLocation, Context context, ClassLoader loader);]
> These methods look up the PersistenceManagerFactory using the naming context
> and name supplied. The implementation's factory method is not called. The
> behavior of this method depends on the implementation of the context and its
> interaction with the saved PersistenceManagerFactory object. As with the
> other factory methods, the returned PersistenceManagerFactory is not
> configurable.
> </proposed>
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.