[ 
http://issues.apache.org/jira/browse/OPENJPA-24?page=comments#action_12435915 ] 
            
Pinaki Poddar commented on OPENJPA-24:
--------------------------------------

I had made certain changes for extending OpenJPA with alternative 
implementaions via ProductDerivations mechanics. Let me present my 
understanding of this issue raised orginally by Kevin on this discussion 
thread. 

org.apache.openjpa.lib.conf.Configuration carries the properties that 
determines configurable behaviour e.g. which concrete PersistenceProvider to 
create or whether to synchronize the object schema with that of the database or 
whether to apply JPA or JDO style mapping primitives and so on. It is a rich 
and powerful construct with support for Plugin.  

The purpose of OpenJPA configuration subsystem is to create one such 
Configuration instance that is essential for any particular instantiation of 
the generic kernel known as BrokerFactory. In fact, BrokerFactory and 
Configuration enjoy a 1:1 till-detah-do-us-apart sort of relationship.    

ProductDerivation, ProductDerivations, ConfigurationProvider, Configurations 
are abstractions that participate in creating this Configuration instance. Let 
us see the roles played by each of them.

ConfigurationProvider locates where the configuration information is and then 
reads it. The information can be in a META-INF/persistence.xml file inside a 
jar, a kodo.properties file available in classpath, a -Dxyz=myValue style Java 
system property, in a Map instance constructed programatically - the 
possibilities are not constrained by design. Because OpenJPA -- notwithstanding 
its name -- is by design capable of supporting multiple specifications that 
differs in configuration grammar -- multiple ConfigurationProvider classes are 
provided. Given the varied nature of how configuration information can be made 
available to the runtime, the basic interface 
org.apache.openjpa.lib.conf.ConfigurationProvider provides the discipline of 
reading configuration from 'global' or 'default' or named resources. Of course, 
each concrete implementation would interpret what 'global' or 'default' would 
mean. ConfigurationProvider after locating the information resource, reads its 
content and temporarilly stores in an internal name-value map. Eventually it 
pours this content into a Configuration instance via 
ConfigurationProvider.setInto(Configuration conf) method. 

ProductDerivation faciliates how Configuration will deal with this content -- 
which MetaDataFactory to set, which EntityManagerFactory (or 
PersistenceManagerFactory) to instantiate as a facade to the kernel according 
to active specification and so on. This tunning is accomplished by hooks during 
the life of a Configuration before being put to active duty i.e. before a 
Configuration instance is constructed, before the content carried by 
ConfigurationProvider is poured in Configuration and after a Configuration is 
set to represent a specification. For example, the spec-agnostic core 
configuration implementation ConfigurationImpl nor its derivation 
OpenJPAConfigurationImpl declares a plugin for which concrete 
EntityManagerFactory to construct as a facade. But PersistenceProductDerivation 
inserts org.apache.openjpa.persistence.EntityManagerFactoryImpl as the concrete 
implementation class for EMF in beforeConfigurationConstruct() hook and adds a 
EMF-plugin value via beforeConfigurationLoaded() hook i.e. before 
ConfigurationProvider pours its content into a Configuration. This allows the 
PersistenceProviderImpl to instantiate a 
org.apache.openjpa.persistence.EntityManagerFactoryImpl as a facade to 
BrokerFactory.  

Given that OpenJPA supports an extensive set of configurable parameters it is 
logical to separate them into categories such as SPEC, PRODUCT, STORE etc -- 
and that lead to a host of ProductDerivation classes each tunning the 
configuration from its own perspective. 
org.apache.openjpa.lib.conf.ProductDerivations is the harness that locates each 
ProductDerivation available to the system, order them up sequentially to give a 
chance to modify Configuration/ConfigurationProvider. ProductDerivations finds 
ProductDerivation by looking up one or more 
"org.apache.openjpa.lib.conf.ProductDerivation" resources in the classpath and 
interpreting each line of this simple text-based resource as a class name for a 
particular org.apache.openjpa.lib.conf.ProductDerivation implementation. 

Configurations hold a bunch of static utility methods to instantiate plugin, 
pour system properties into Configuration and so on. I have not looked into 
this class due dilligence and it may even be a candidate for being refactored 
out completely later. 


Given this scheme, the most visible (and mechanical) change is to drive the 
loading of configuration data by the ConfigurationProvider via 
ProductDerivations. It used to be such that different ConfigurationProvider 
were activated by Configurations and different ProductDerivation were activated 
by ProductDerivations. Now ProductDerivations is the only driver of 
configuration subsystem. Each ProductDerivation can supply its own 
ConfigurationProvider to locate/parse/read configuration information and 
supplying a null imply that this ProductDerivation does not read resource at 
all. In fact, most of them don't. 

This ProductDerivation-as-driver-of-ConfigurationProvider notion is coded into 
AbstractProductDerivation.  

The other change as outlined by Abe is to move 
ProductDerivations/ProductDerivation/Configuration to lib and factor out STORE 
specifc details in kerenl.OpenJPAProductDerivation. 

With all these machinery and refactoring -- now let us go back to the issue 
Kevin originally raised -- how does one extend OpenJPA?
The use case became real when we needed a backward compatibility support for 
Kodo 4.0. Kodo 4.0 was released few months ago in pre-OpenJPA era. Obviously, a 
mechanism is needed such that applications written on Kodo 4.0 but running on 
Kodo 4.1 based on OpenJPA must be able to use the old API of 
kodo.persistence.PersistenceProviderImpl instead of org.apache.... 
In my next post, I will describe how that was done with ProductDerivation, I 
have to now attend to booth duty at BEAWorld. 
 

        
 

> Allow OpenJPA to be extensible
> ------------------------------
>
>                 Key: OPENJPA-24
>                 URL: http://issues.apache.org/jira/browse/OPENJPA-24
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>            Reporter: Kevin Sutter
>         Assigned To: Kevin Sutter
>
> The current OpenJPA architecture is not extendable to other implementations.  
> For example, if somebody wanted to provide their own PersistenceProvider 
> implementation, simply extending the 
> org.apache.openjpa.PersistenceProviderImpl would not suffice due to the 
> dependencies in the ConfigurationProviderImpl.  The discussion for this 
> improvement was started on the dev mailing list.  Once it was determined that 
> there was more to this request than a simple conditional or two, we decided 
> to open a JIRA report.
> The complete history of this request can be found in the OpenJPA dev mailing 
> list.  The first message was posted by me (Kevin Sutter) on August 14, titled 
> "Extending the OpenJPA Implementation".  I will attempt to paraphrase the 
> current state of the problem...
> We have three main players in this issue.  The PersistenceProvider, the 
> ConfigurationProvider, and the ProductDerivation (along with the various 
> implementations of these interfaces).  Currently, the ConfigurationProvider 
> is in the lib and is unaware of any specific persistence requirements.  The 
> ProductDerivation is in the kernel and, unfortunately, is aware of 
> persistence requirements, specifically the spec and store types.  Abe's 
> postings have indicated that we need to make these two interfaces more aware 
> of each other and work with each other.  We need to start with either making 
> ConfigurationProvider more persistence-aware and move it into kernel, or make 
> ProductDerivations less persistence-aware and move it into lib.  The latter 
> approach is preferred.
> After we get this re-organization of the base framework complete, we still 
> have a couple of other issues ot resolve:
>     *  Still need the ability to extend EMF's through a ProductDerivation.  
> This should be doable by adding a new PluginValue to indicate what class of 
> EMF to load.
>     *  There is still a question as to whether we will need to provide a 
> custom PersistenceProviderImpl and ConfigurationProviderImpl pair.  I still 
> think this will be necessary.   And, one of Abe's posts indicated that this 
> might help with class loading issues when multiple versions of OpenJPA-based 
> implementations are available in the same system.
> I also posted these questions last Friday.  (Abe has responded with some 
> answers, but I wanted to get this JIRA report created before trying to 
> paraphrase his answers.)
>     *  You mention in several places about separating away the notion of 
> specs and stores.  In a general sense, I understand what these are.  But, can 
> you elaborate on how these types are used in the ConfigurationProvider and 
> ProductDerivation interfaces?
>     * I've moved the ProductDerivation interface to the lib and added the 
> "load" methods from the ConfigurationProvider (as described in your previous 
> notes).  And, I've started to clean up the implementations that depend on 
> these interfaces.  But, concerning the implementation of the load methods...  
> Now that we need to return a ConfigurationProvider, would you expect that we 
> just new up a ConfigurationProviderImpl and then just call across to the 
> "load" methods on the implementation?  Since we want to keep the 
> ProductDerivations stateless, I'm not sure how else you were expecting to 
> create a ConfigurationProvider to return on these "load" methods.
>     * Now that ConfigurationProvider is bare, the 
> ConfigurationTestConfigurationProvider doesn't have much function.  I'll need 
> to take a look to see if this is even required any longer.
>     * Can you shed a bit more light on the Configurations class?  It doesn't 
> implement nor extend any interfaces or classes, but it seems to provide many 
> of the same methods as ConfigurationProvider, but as statics.  And, it's 
> dependent on having a Provider.  Can you explain the relationship of this 
> class in the bigger picture and how you think it might be affected by thes 
> changes?
> That's enough for the initial JIRA report.  We will now track this problem 
> here instead of the dev mailing list.  Thanks.
> Kevin

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira


Reply via email to