db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Matthew T. Adams (JIRA)" <j...@apache.org>
Subject [jira] Updated: (JDO-545) Allow users to supply property-overriding Map instances when configuring from resources (properties, jdoconfig.xml, or persistence.xml)
Date Wed, 10 Oct 2007 06:18:50 GMT

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

Matthew T. Adams updated JDO-545:
---------------------------------

    Attachment: JDO-545.patch

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 [@deprecated 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.


Mime
View raw message