[ 
https://issues.apache.org/jira/browse/JDO-545?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12545558
 ] 

Matthew T. Adams commented on JDO-545:
--------------------------------------

Patch on prior comment includes indicated updates in comments submitted with 
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
>
>         Attachments: jdo-545.patch
>
>
> 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.

Reply via email to