db-jdo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Jdo Wiki] Update of "PersistentInterfaces" by CraigRussell
Date Sat, 03 Sep 2005 01:44:13 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Jdo Wiki" for change notification.

The following page has been changed by CraigRussell:
http://wiki.apache.org/jdo/PersistentInterfaces

------------------------------------------------------------------------------
+ = Persistent Interfaces =
- Persistent Interfaces are a feature of JDO 2 that allows users to define their domain object
model in terms of Java interfaces instead of Java classes. For example, this defines a persistence-capable
class called Company with two persistent fields:
+ Persistent Interfaces is a feature of JDO 2 that allows users to define their domain object
model in terms of Java interfaces instead of Java classes. For example, this defines a persistence-capable
class called Company with two persistent fields:
  {{{
  class Company {
    long companyid;
@@ -27, +28 @@

  </interface>
  }}}
  
- A goal is to map the interfaces in package org.apache.jdo.tck.pc.company (hereinafter "the
company package") to exactly the same schema as is used for the classes, and to use the same
{{{CompletenessTest}}} and xml data. This way, any bug fixes to the handling of the schema,
xml data, or comparison of data will be propagated to the interface tests.
+ A goal is to map the interfaces in package {{{org.apache.jdo.tck.pc.company}}} (hereinafter
"the company package") to exactly the same schema as is used for the classes, and to use the
same {{{CompletenessTest}}} and xml data. This way, all of the standard mappings of the company
model can be used as is, and any bug fixes to the handling of the schema, xml data, or comparison
of data will be automatically propagated to the interface tests.
  
+ == XML Test Data ==
  To change the xml test data to use factories, the attribute {{{factory-method}}} is added
to the test data {{{bean}}} elements.
  {{{
-     <bean id="company1" class="org.apache.jdo.tck.pc.company.Company">
+   <bean id="company1" class="org.apache.jdo.tck.pc.company.Company">
-         <constructor-arg index="0" type="long"><value>1</value></constructor-arg>
-         <constructor-arg index="1" type="java.lang.String"><value>Sun Microsystems,
Inc.</value></constructor-arg>
-         <constructor-arg index="2" type="java.util.Date"><value>11/Apr/1952</value></constructor-arg>
+     <constructor-arg index="0" type="long">
+         <value>1</value></constructor-arg>
+     <constructor-arg index="1" type="java.lang.String">
+         <value>Sun Microsystems, Inc.</value></constructor-arg>
+     <constructor-arg index="2" type="java.util.Date">
+         <value>11/Apr/1952</value></constructor-arg>
-     </bean>
+   </bean>
  }}}
  is changed to become
  {{{
-     <bean id="company1" class="org.apache.jdo.tck.pc.company.CompanyFactoryImpl"
+   <bean id="company1" class="org.apache.jdo.tck.pc.company.CompanyFactoryImpl"
-             factory-method="newCompany">
+         factory-method="newCompany">
-         <constructor-arg index="0" type="long"><value>1</value></constructor-arg>
-         <constructor-arg index="1" type="java.lang.String"><value>Sun Microsystems,
Inc.</value></constructor-arg>
-         <constructor-arg index="2" type="java.util.Date"><value>11/Apr/1952</value></constructor-arg>
+     <constructor-arg index="0" type="long">
+         <value>1</value></constructor-arg>
+     <constructor-arg index="1" type="java.lang.String">
+         <value>Sun Microsystems, Inc.</value></constructor-arg>
+     <constructor-arg index="2" type="java.util.Date">
+         <value>11/Apr/1952</value></constructor-arg>
      </bean>
  }}}
+ == Refactoring ==
+ The company package has been refactored to have each domain class implement the corresponding
interface. The algorithm of the Completeness``Test creates an in-memory domain model graph
from xml data and make its elements persistent. Then, a new transient in-memory domain model
graph is constructed from the same xml data and the transient graph is used as the model to
verify that the graph of persistent instances as fetched from the database is isomorphic to
the transient graph.
+ == CompanyFactory Patterns ==
+ Since persistent instances that implement the persistent interfaces use a factory pattern,
we introduce a Company``Factory concept that allows a runtime switch between various factories.
The transient graph that is used to compare to the persistent graph is always constructed
using the factory that creates instances of the concrete classes. The persistent graph is
constructed using one of these patterns:
  
- The package has been refactored to have each domain class implement the corresponding interface.
The algorithm of the CompletenessTest is to create an in-memory domain model graph from xml
data and make its elements persistent. Then, a different in-memory domain model graph is constructed
from the same xml data and the new graph is compared to the persistent graph fetched from
the database.
+  * the factory instantiate new instances of the concrete classes
+  * the factory calls the Persistence``Manager newInstance method with the interfaces as
parameters
+  * the factory calls the Persistence``Manager newInstance method with abstract classes that
implement the interfaces as parameters
+  * the factory calls the Persistence``Manager newInstance method with the concrete classes
as parameters
+ == CompanyFactory Interface ==
+ Company``Factory is the interface that each factory must implement. The methods in the interface
are those that are required by the current xml data implementations. They include constructors
for each concrete class in the model. 
  
- Since persistent instances that implement the persistent interfaces use a factory pattern,
we introduce a CompanyFactory concept that allows a runtime switch between various factories.
The graph that is compared to the persistent graph is always constructed using the class factory.
The persistent graph is constructed using one of these concepts:
+ The strategy for implementation is for a concrete class Company``Factory``Impl that instantiates
a default implementation of Company``Factory that contains methods that instantiate a new
instance of the concrete class as a strategy. 
  
+ The Company``Factory``Impl class implements static methods {{{newAddress}}}...{{{newProject}}}
that are required by the xml data file. It does not itself implement the Company``Factory
interface but delegates to an instance of a class that does implement the Company``Factory
interface.
+ == Abstract Implementation Class ==
+ An abstract class {{{CompanyFactoryAbstractImpl}}} contains skeleton implementations for
each required method, and an abstract method to create a new instance with no properties set.
The properties are then set using setProperty methods. This allows a subclass to implement
the Company``Factory interface simply by implementing the abstract methods.
-  * the factory instantiates a new instance of the class
-  * the factory calls pm.newInstance on the interface
-  * the factory calls pm.newInstance on an abstract class that implements the interface
- 
- CompanyFactory is the interface that each factory must implement. The methods in the interface
are those that are required by the current xml data implementations. They include constructors
for each concrete class in the model. 
- 
- The strategy for implementation is for a concrete class CompanyFactoryImpl that contains
a default implementation that instantiates a new instance of the class. An abstract CompanyFactory
contains skeleton implementations for each required method, and an abstract method to create
a new instance with no properties set. The properties are then set using setProperty methods.
  
  {{{
- public abstract class CompanyFactoryInterfaceAbstractImpl implements CompanyFactory {
+ public abstract class CompanyFactoryAbstractImpl implements CompanyFactory {
      
      protected PersistenceManager pm;
      
-     /** Creates a new instance of CompanyFactoryPersistentInterface */
+     /** Creates a new instance of CompanyFactoryAbstractImpl */
      public CompanyFactoryInterfaceAbstractImpl(PersistenceManager pm) {
          this.pm = pm;
      }
@@ -84, +97 @@

      }
  ...}}}
  
- All a concrete factory implementation has to do is to subclass the abstract CompanyFactoryAbstractImpl
and provide implementations for the interfaces.
+ "All a concrete factory implementation has to do" is to subclass the abstract Company``Factory``Abstract``Impl
and provide implementations for the abstract methods.
  
  {{{
  public class CompanyFactoryPersistentInterface 
@@ -101, +114 @@

  ...
  }}}
  
- 
+ == Build Issues ==
- A new system property {{{jdo.tck.mapping.companyfactory}}} is used to pick the company factory
for the persistent object graph. After constructing the persistent object graph, the default
factory is set so during construction of the compared objects the standard constructor is
used. The maven.xml file needs to pass the system property to the CompletenessTest. 
+ A new system property {{{jdo.tck.mapping.companyfactory}}} is used to pick the company factory
used to create the persistent object graph. After constructing the persistent object graph,
the default factory is reset so that during construction of the compared objects the standard
constructor is used. The maven.xml file needs to pass the system property to the Completeness``Test.

  {{{
    <goal name="doRuntck.jdori">
      <java fork="yes" dir="${jdo.tck.testdir}"
@@ -113, +126 @@

  }}}
  Configurations can specify this property in the .conf file:
  {{{
- cat test/conf/clr.conf
+ %cat test/conf/clr.conf
  jdo.tck.description = Completeness test with factory class
  #jdo.tck.mapping.companyfactory=
  #  org.apache.jdo.tck.pc.company.CompanyFactoryImpl$DefaultCompanyFactoryImpl
@@ -123, +136 @@

  jdo.tck.testdata = org/apache/jdo/tck/pc/company/companyNoRelationships.xml
  jdo.tck.mapping = 0
  }}}
- We also need a factory that uses the persistence manager newInstance method with the persistence-capable
class as the argument.
+ == New Sub-package acompany ==
+ All the components described so far will remain in the company package. I propose to add
the components to instantiate persistent abstract classes into a subpackage, {{{org.apache.jdo.tck.pc.company.acompany}}}
and to implement the abstract classes that implement the interfaces as well as the company
factory that instantiates the abstract classes using the persistence manager newInstance method
with the abstract class as the argument.
+ == Feeback Requested ==
+ The interface Company``Factory is implemented by subclasses of Company``Factory``Abstract``Impl.
We need names for these components:
  
- All the components described so far will remain in the company package. I propose to add
the components to instantiate persistent abstract classes into a subpackage, {{{org.apache.jdo.tck.pc.company.acompany}}}
and to implement the abstract classes that implement the interfaces as well as the company
factory that instantiates the abstract classes using the persistence manager newInstance method
with the abstract class as the argument.
+  * Company``Factory seems reasonable
+  * Company``Factory``Impl isn't quite up to the task. It doesn't implement Company``Factory.
It delegates to a registered object that itself implements Company``Factory. It's a class
that contains static methods called by beans.
+  * Company``Factory``Abstract``Impl isn't quite ok either. It implements Company``Factory
but its name implies that it creates abstract implementations. 
+  * Company``Factory``Concrete``Impl the factory that instantiates new instances of the concrete
classes
+  * Company``Factory``Interface``Impl the factory that calls the Persistence``Manager newInstance
method with the interfaces as parameters
+  * Company``Factory``Abstract``Impl oops, this is already taken... this factory calls the
Persistence``Manager newInstance method with abstract classes that implement the interfaces
as parameters
+  * Company``Factory``Concrete``Impl oops, this is also taken... this factory calls the Persistence``Manager
newInstance method with the concrete classes as parameters
  

Mime
View raw message