db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig L Russell <Craig.Russ...@Sun.COM>
Subject Spec updates for 2.3
Date Fri, 12 Mar 2010 01:46:47 GMT
Here is a somewhat readable version of the changes in the  
specification for 2.3 for datastore timeout, exact class  
getObjectById, and the enhancer. Please review and comment.

11.1:
Datastore Timeout
Some datastore operations can exceed the expected or desired time to  
execute, due to conditions that might not be influenced by the  
application directly. In order to allow the application to gracefully  
recover from these conditions, the application can specify timeouts to  
be applied separately to read and write datastore operations.
DatastoreReadTimeoutMillis: the number of milliseconds allowed for  
read operations to complete. Read operations include retrieving  
instances from the datastore, loading fields, and executing queries  
that do not change the datastore.
DatastoreWriteTimeoutMillis: the number of milliseconds allowed for  
write operations to complete. Write operations include flushing  
changes and deleting instances by query.
Timeouts can be specified at three locations: the  
PersistenceManagerFactory, the PersistenceManager, and the Query.  
Timeouts specified at the PersistenceManagerFactory are the defaults  
for timeouts of the PersistenceManager. Timeous specified at the  
PersistenceManager are the defaults for Query. Timeouts specified at  
the Query apply only to that specific query.
If a timeout is specified, the implementation will use the supplied  
value as a timeout for operations where the underlying datastore  
supports it. The timeouts are in milliseconds. If it is not specified  
then there is no timeout.

11.1.1:
"javax.jdo.option.DatastoreReadTimeoutMillis"
"javax.jdo.option.DatastoreWriteTimeoutMillis"

11.1.4:
<!DOCTYPE jdoconfig
     PUBLIC “-//Sun Microsystems, Inc.//DTD Java Data Objects  
Configuration 2.3//EN”
     “http://java.sun.com/dtd/jdoconfig_2_3.dtd”>
-->
<!ELEMENT jdoconfig (persistence-manager-factory+)>

<!ELEMENT persistence-manager-factory (property*, instance-lifecycle- 
listener*)>
<!ATTLIST persistence-manager-factory class CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory name CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory persistence-unit-name CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory optimistic (true|false) CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory readonly (true|false) CDATA  
‘false’>
<!ATTLIST persistence-manager-factory retain-values (true|false) CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory restore-values (true|false)  
CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory ignore-cache (true|false) CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory nontransactional-read (true| 
false) CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory nontransactional-write (true| 
false) CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory multithreaded (true|false) CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory transaction-isolation-level  
CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory connection-driver-name CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory connection-user-name CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory connection-password CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory connection-url CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory connection-factory-name CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory connection-factory2-name CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory mapping CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory detach-all-on-commit (true| 
false) CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory server-time-zone-id CDATA  
#IMPLIED>
<!ATTLIST persistence-manager-factory datastore-read-timeout-millis  
CDATA #IMPLIED>
<!ATTLIST persistence-manager-factory datastore-write-timeout-millis  
CDATA #IMPLIED>

<!ELEMENT property EMPTY>
<!ATTLIST property name CDATA #REQUIRED>
<!ATTLIST property value CDATA #IMPLIED>

<!ELEMENT instance-lifecycle-listener EMPTY>
<!ATTLIST instance-lifecycle-listener listener CDATA #REQUIRED>
<!ATTLIST instance-lifecycle-listener classes CDATA #IMPLIED>


11.6:
javax.jdo.option.QueryCancel
The JDO implementation supports canceling a running query. The  
underlying datastore must also support canceling a running query. The  
cancel support in the datastore must at least free the client thread  
executing the query. The server cancel behavior is not specified.
javax.jdo.option.DatastoreTimeout
The JDO implementation supports datastore timeouts. The underlying  
datastore must also support datastore timeouts. The server timeout  
behavior is not specified.

11.10:
Metadata Access
Metadata can be specified via annotations, xml, or API. These methods  
provide access to metadata managed by the PersistenceManagerFactory.
void registerMetadata(JDOMetadata metadata);
Register metadata with this PersistenceManagerFactory. Metadata can be  
created using the newMetadata method.
JDOMetadata newMetadata();
Return a new JDO metadata object that can be subsequently modified and  
registered with this PersistenceManagerFactory.
ComponentMetadata getMetadata(String className);
Return the class or interface metadata object for the specified class  
or interface, if there is metadata defined for that class or interface.

12.6.3:
void setDatastoreReadTimeoutMillis(Integer milliseconds);
Integer getDatastoreReadTimeoutMillis();
These methods set and get the datastore read timeout value in  
milliseconds. The value might have been set in the  
PersistenceManagerFactory via API or properties. Setting the value to  
null will use the value specified in PersistenceManagerFactory.  
Setting the timeout to a non-null value will override the value  
specified in PersistenceManagerFactory.
void setDatastoreWriteTimeoutMillis(Integer milliseconds);
Integer getDatastoreWriteTimeoutMillis();
These methods set and get the datastore write timeout value in  
milliseconds. The value might have been set in the  
PersistenceManagerFactory via API or properties. Setting the value to  
null will use the value specified in PersistenceManagerFactory.  
Setting the timeout to a non-null value will override the value  
specified in PersistenceManagerFactory.

12.6.5:
If the validate flag is false, the user asserts that the instance  
exists and the object id represents the exact class of the persistent  
instance (specifically not a subclass or an interface):
A12.6.5-2 [If the object id represents an interface or abstract class,  
JDOUserException is thrown.]
A12.5.6-2 [If there is already an instance in the cache with the same  
JDO identity as the oid parameter, then this method returns it.]  
A12.5.6-3 [There is no change made to the state of the returned  
instance.]
A12.5.6-4 [If there is not an instance already in the cache with the  
same JDO identity as the oid parameter, then this method creates an  
instance with the specified JDO identity and returns it. If there is  
no transaction in progress, the returned instance will be hollow or  
persistent-nontransactional, at the choice of the implementation.]
A12.5.6-5 [If there is a transaction in progress, the returned  
instance will be hollow, persistent-nontransactional, or persistent- 
clean, at the choice of the implementation.]
A12.6.5-2 [The implementation must not access the datastore to  
determine the exact class. If the class is not the exact class, then  
an exception must be thrown subsequently if any field other than the  
identity field is accessed. ]
A12.6.5-1 [If the instance does not exist in the datastore, then this  
method will not fail. But A12.5.6-6 [a subsequent access of the fields  
of the instance will throw a JDOObjectNotFoundException if the  
instance does not exist at that time.] Further, if a relationship is  
established to this instance, and the instance does not exist when the  
instance is flushed to the datastore, then the transaction in which  
the association was made will fail.
If the validate flag is true:
A12.5.6-7 [If there is already a transactional instance in the cache  
with the same jdo identity as the oid parameter, then this method  
returns it. There is no change made to the state of the returned  
instance.]
A12.5.6-8 [If there is an instance already in the cache with the same  
jdo identity as the oid parameter, the instance is not transactional,  
and the instance does not exist in the datastore, then a  
JDOObjectNotFoundException is thrown.]
A12.5.6-9 [If there is not an instance already in the cache with the  
same jdo identity as the oid parameter, then this method creates an  
instance with the specified jdo identity, verifies that it exists in  
the datastore, and returns it. A12.6.5-2 [The class in the object id  
might be the exact class or an abstract or concrete superclass of the  
actual instance.] A12.6.5-2 [If the instance does not exist in the  
datastore, then a JDOObjectNotFoundException is thrown.] If the fetch  
plan has been changed from its original value, the fetch plan governs  
which fields are fetched from the datastore and which related objects  
are also fetched with them.
	If there is no transaction in progress, the returned instance will be  
hollow or persistent-nontransactional, at the choice of the  
implementation.
	If there is a datastore transaction in progress, the returned  
instance will be persistent-clean.
	If there is an optimistic transaction in progress, the returned  
instance will be persistent-nontransactional.]

14.6.1:
Query Timeout
Queries may have timeouts associated with them. The timeout values  
might be set in the PersistenceManagerFactory, in the  
PersistenceManager, or in the Query instance.
Integer getDatastoreReadTimeoutMillis();
Integer getDatastoreWriteTimeoutMillis();
A value of null indicates that there is no timeout set for this query.  
A non-null value indicates that the timeout was set by this query, or  
the value was obtained by the default value set in the  
PersistenceManager or the PersistenceManagerFactory. A timeout value  
of 0 indicates that there is no timeout for this query.
void setDatastoreReadTimeoutMillis(Integer timeoutMillis);
void setDatastoreWriteTimeoutMillis(Integer timeoutMillis);
A14.6.1-7 [If a non-null timeout value is specified, a running query  
will be interrupted if it exceeds the execution time of the timeout  
value. The thread executing the query will throw  
JDODatastoreException. Specifying a timeout value of 0 indicates that  
there is no timeout for this query (a setting of 0 overrides the  
default specified in the PersistenceManager or the  
PersistenceManagerFactory).]
If the timeout value is specified as null, then the timeout is  
obtained from the PersistenceManager or the PersistenceManagerFactory.  
If there is no timeout specified in any of the Query, the  
PersistenceManager or the PersistenceManagerFactory, there is no  
timeout for the query.
Query Cancel
Queries might be canceled by a different thread from the thread  
currently executing the query. There is no requirement that the  
Multithreaded flag be set in order to invoke the cancel operation from  
a different thread.
void cancelAll();
void cancel(Thread thread);
A14.6.1-8 [These methods cancel a running query (or queries). The  
thread that has its query canceled will throw a  
JDOQueryInterruptedException.
If cancel is not supported (most likely due to the underlying  
implementation not supporting cancel) then  
JDOUnsupportedOptionException is thrown to the caller. ]

19.2.2

JDO Metadata
JDOMetadata represents the root of the metadata.
/**
  * Represents the top-level JDO metadata.
  * @since 2.3
  */
public interface JDOMetadata extends Metadata {
     /**
      * Method to set the catalog (ORM) to apply to all classes in this
      * JDO Metadata.
      *
      * @param catalog Catalog name
      */
     JDOMetadata setCatalog(String catalog);

     /**
      * Accessor for the catalog (ORM) that all classes in this JDO  
Metadata
      * default to.
      *
      * @return The catalog
      */
     String getCatalog();

     /**
      * Method to set the schema (ORM) to apply to all classes in this  
JDO
      * Metadata.
      *
      * @param schema Schema name
      */
     JDOMetadata setSchema(String schema);

     /**
      * Accessor for the schema (ORM) that all classes in this JDO  
Metadata
      * default to.
      *
      * @return The schema
      */
     String getSchema();

     /**
      * Accessor for all packages defined on the JDO Metadata.
      *
      * @return The packages
      */
     PackageMetadata[] getPackages();

     /**
      * Add a new package to this JDO Metadata.
      *
      * @param pkgName Name of the package
      * @return The PackageMetadata
      */
     PackageMetadata newPackageMetadata(String pkgName);

     /**
      * Add a new package to this JDO Metadata.
      *
      * @param pkg The package
      * @return The PackageMetadata
      */
     PackageMetadata newPackageMetadata(Package pkg);

     /**
      * Accessor for the number of packages defined in this JDO  
Metadata.
      *
      * @return The number of packages.
      */
     int getNumberOfPackages();

     /**
      * Add a new class to this JDO Metadata.
      * Adds its package also if not yet existing.
      *
      * @param cls Class to add
      * @return The ClassMetadata
      */
     ClassMetadata newClassMetadata(Class cls);

     /**
      * Add a new interface to this JDO Metadata.
      * Adds its package also if not yet existing.
      *
      * @param cls Class to add
      * @return The InterfaceMetadata
      */
     InterfaceMetadata newInterfaceMetadata(Class cls);

     /**
      * Accessor for any named queries defined on the JDO Metadata.
      *
      * @return The queries
      */
     QueryMetadata[] getQueries();

     /**
      * Add a new named query to this JDO Metadata.
      *
      * @param name Name of the query
      * @return The QueryMetadata
      */
     QueryMetadata newQueryMetadata(String name);

     /**
      * Accessor for the number of named queries defined in this JDO  
Metadata.
      *
      * @return The number of queries.
      */
     int getNumberOfQueries();

     /**
      * Accessor for any fetch plans defined on the JDO Metadata.
      *
      * @return The fetch plans
      */
     FetchPlanMetadata[] getFetchPlans();

     /**
      * Add a new fetch plan to this JDO Metadata.
      *
      * @param name Name of the query
      * @return The FetchPlanMetadata
      */
     FetchPlanMetadata newFetchPlanMetadata(String name);

     /**
      * Accessor for the number of fetch plans defined in this JDO  
Metadata.
      *
      * @return The number of fetch plans.
      */
     int getNumberOfFetchPlans();
}

Package Metadata
PackageMetadata represents the collection of metadata that share the  
same package.
/**
  * Represents a package within a JDOMetadata.
  * @since 2.3
  */
public interface PackageMetadata extends Metadata {
     /**
      * Accessor for the name of this package (set on construction).
      *
      * @return The name
      */
     String getName();

     /**
      * Method to set the catalog (ORM) to apply to all classes in  
this package.
      *
      * @param catalog Catalog name
      */
     PackageMetadata setCatalog(String catalog);

     /**
      * Accessor for the catalog (ORM) that all classes in this  
package default
      * to.
      *
      * @return The catalog
      */
     String getCatalog();

     /**
      * Method to set the schema (ORM) to apply to all classes in this  
package.
      *
      * @param schema Schema name
      */
     PackageMetadata setSchema(String schema);

     /**
      * Accessor for the schema (ORM) that all classes in this package  
default to.
      *
      * @return The schema
      */
     String getSchema();

     /**
      * Accessor for all classes defined in this package.
      *
      * @return The classes
      */
     ClassMetadata[] getClasses();

     /**
      * Add a new class to this package.
      *
      * @param name Name of the class
      * @return The ClassMetadata
      */
     ClassMetadata newClassMetadata(String name);

     /**
      * Add a new class to this package.
      *
      * @param cls The class
      * @return The ClassMetadata
      */
     ClassMetadata newClassMetadata(Class cls);

     /**
      * Accessor for the number of classes defined in this package.
      *
      * @return The number of classes.
      */
     int getNumberOfClasses();

     /**
      * Accessor for all interfaces defined in this package.
      *
      * @return The interfaces
      */
     InterfaceMetadata[] getInterfaces();

     /**
      * Add a new interface to this package.
      *
      * @param name The interface name
      * @return The InterfaceMetadata
      */
     InterfaceMetadata newInterfaceMetadata(String name);

     /**
      * Add a new interface to this package.
      *
      * @param cls The class
      * @return The ClassMetadata
      */
     InterfaceMetadata newInterfaceMetadata(Class cls);

     /**
      * Accessor for the number of interfaces defined in this package.
      *
      * @return The number of interfaces.
      */
     int getNumberOfInterfaces();

     /**
      * Accessor for any sequences defined on the package.
      *
      * @return The sequences
      */
     SequenceMetadata[] getSequences();

     /**
      * Add a new sequence to this package.
      *
      * @param name Name of the sequence
      * @param strategy Strategy for the sequence
      * @return The SequenceMetadata
      */
     SequenceMetadata newSequenceMetadata(String name,
             SequenceStrategy strategy);

     /**
      * Accessor for the number of sequences defined for this package.
      *
      * @return The number of sequences.
      */
     int getNumberOfSequences();
}

Component Metadata
ComponentMetadata represents the metadata for classes and interfaces.
/**
  * Represents a class or interface. Extended for the specifics of  
those cases.
  * @since 2.3
  */
public interface ComponentMetadata extends Metadata {
     /**
      * Accessor for the name of this component (set on construction).
      *
      * @return The name
      */
     String getName();

     /**
      * Method to define the identity type to use.
      *
      * @param id identity type
      */
     ComponentMetadata setIdentityType(IdentityType id);

     /**
      * Accessor for the identity type to use.
      *
      * @return identity type
      */
     IdentityType getIdentityType();

     /**
      * Method to set the object-id (PK) class.
      *
      * @param idclass Object-id class
      */
     ComponentMetadata setObjectIdClass(String idclass);

     /**
      * Accessor for the object-id class (if defined).
      *
      * @return The object-id class
      */
     String getObjectIdClass();

     /**
      * Method to set whether the component requires an extent.
      *
      * @param extent Requires extent?
      */
     ComponentMetadata setRequiresExtent(boolean extent);

     /**
      * Accessor for whether the component requires an extent.
      *
      * @return Requires extent?
      */
     boolean getRequiresExtent();

     /**
      * Method to set whether this is detachable
      *
      * @param detachable Detachable?
      */
     ComponentMetadata setDetachable(boolean detachable);

     /**
      * Accessor for whether this is detachable.
      *
      * @return Detachable?
      */
     boolean getDetachable();

     /**
      * Method to set whether this is cacheable
      *
      * @param cacheable Cacheable?
      */
     ComponentMetadata setCacheable(boolean cacheable);

     /**
      * Accessor for whether this is cacheable.
      *
      * @return Cacheable?
      */
     boolean getCacheable();

     /**
      * Method to set whether this is serializeRead
      *
      * @param serializeRead serializeRead?
      */
     ComponentMetadata setSerializeRead(boolean serializeRead);

     /**
      * Accessor for whether this is serializeRead.
      *
      * @return serializeRead?
      */
     boolean getSerializeRead();

     /**
      * Method to set whether it is stored only as embedded in other  
objects.
      *
      * @param embedded Whether it is only stored embedded
      */
     ComponentMetadata setEmbeddedOnly(boolean embedded);

     /**
      * Accessor for whether this is embedded only.
      *
      * @return Only stored as embedded
      */
     Boolean getEmbeddedOnly();

     /**
      * Method to set the catalog (ORM) for this component
      *
      * @param catalog Catalog name
      */
     ComponentMetadata setCatalog(String catalog);

     /**
      * Accessor for the catalog (ORM) for this component
      *
      * @return The catalog
      */
     String getCatalog();

     /**
      * Method to set the schema (ORM) for this component
      *
      * @param schema Schema name
      */
     ComponentMetadata setSchema(String schema);

     /**
      * Accessor for the schema (ORM) for this component
      *
      * @return The schema
      */
     String getSchema();

     /**
      * Method to set the table name.
      *
      * @param table Table name
      */
     ComponentMetadata setTable(String table);

     /**
      * Accessor for the name of the table.
      *
      * @return The name
      */
     String getTable();

     /**
      * Method to define the inheritance metadata.
      *
      * @return The InheritanceMetadata
      */
     InheritanceMetadata newInheritanceMetadata();

     /**
      * Accessor for the inheritance (if any).
      *
      * @return inheritance
      */
     InheritanceMetadata getInheritanceMetadata();

     /**
      * Method to define the version metadata.
      *
      * @return The VersionMetadata
      */
     VersionMetadata newVersionMetadata();

     /**
      * Accessor for the version (if any).
      *
      * @return version
      */
     VersionMetadata getVersionMetadata();

     /**
      * Method to define the datastore identity metadata details.
      *
      * @return The DatastoreIdentityMetadata
      */
     DatastoreIdentityMetadata newDatastoreIdentityMetadata();

     /**
      * Accessor for the datastore identity details.
      *
      * @return datastore identity details
      */
     DatastoreIdentityMetadata getDatastoreIdentityMetadata();

     /**
      * Method to define the primary key details.
      *
      * @return The PrimaryKeyMetadata
      */
     PrimaryKeyMetadata newPrimaryKeyMetadata();

     /**
      * Accessor for the primary key (if any).
      *
      * @return primary key details
      */
     PrimaryKeyMetadata getPrimaryKeyMetadata();

     /**
      * Accessor for all joins(s) defined on the component.
      *
      * @return The join(s)
      */
     JoinMetadata[] getJoins();

     /**
      * Add a join for this component.
      *
      * @return The JoinMetadata
      */
     JoinMetadata newJoinMetadata();

     /**
      * Accessor for the number of join(s) defined for this component.
      *
      * @return The number of join(s)
      */
     int getNumberOfJoins();

     /**
      * Accessor for all fk(s) defined on the component.
      *
      * @return The fk(s)
      */
     ForeignKeyMetadata[] getForeignKeys();

     /**
      * Add a new FK for this component.
      *
      * @return The ForeignKeyMetadata
      */
     ForeignKeyMetadata newForeignKeyMetadata();

     /**
      * Accessor for the number of FKs defined for this component.
      *
      * @return The number of FKs
      */
     int getNumberOfForeignKeys();

     /**
      * Accessor for all index(s) defined on the component.
      *
      * @return The index(s)
      */
     IndexMetadata[] getIndices();

     /**
      * Add a new index for this component.
      *
      * @return The IndexMetadata
      */
     IndexMetadata newIndexMetadata();

     /**
      * Accessor for the number of indices defined for this component.
      *
      * @return The number of indices
      */
     int getNumberOfIndices();

     /**
      * Accessor for all unique constraints defined on the component.
      *
      * @return The unique constraints
      */
     UniqueMetadata[] getUniques();

     /**
      * Add a new unique constraint for this component.
      *
      * @return The UniqueMetadata
      */
     UniqueMetadata newUniqueMetadata();

     /**
      * Accessor for the number of unique constraints defined for this  
component.
      *
      * @return The number of unique constraints
      */
     int getNumberOfUniques();

     /**
      * Accessor for all fields/properties defined on the component.
      *
      * @return The members
      */
     MemberMetadata[] getMembers();

     /**
      * Accessor for the number of fields/properties defined for this  
component.
      *
      * @return The number of members
      */
     int getNumberOfMembers();

     /**
      * Add a new property for this component.
      *
      * @param name Name of the property
      * @return The PropertyMetadata
      */
     PropertyMetadata newPropertyMetadata(String name);

     /**
      * Add a new property for this component.
      *
      * @param method Java bean getter/setter method
      * @return The PropertyMetadata
      */
     PropertyMetadata newPropertyMetadata(Method method);

     /**
      * Accessor for all named queries defined on the component.
      *
      * @return The queries
      */
     QueryMetadata[] getQueries();

     /**
      * Add a new query for this component.
      *
      * @param name
      *            Name of the query to add
      * @return The QueryMetadata
      */
     QueryMetadata newQueryMetadata(String name);

     /**
      * Accessor for the number of named queries defined for this  
component.
      *
      * @return The number of named queries
      */
     int getNumberOfQueries();

     /**
      * Accessor for all FetchGroup defined on the component.
      *
      * @return The FetchGroups
      */
     FetchGroupMetadata[] getFetchGroups();

     /**
      * Add a new FetchGroup for this component.
      *
      * @param name Name of the FetchGroup
      * @return The FetchGroupMetadata
      */
     FetchGroupMetadata newFetchGroupMetadata(String name);

     /**
      * Accessor for the number of fetchGroups defined for this  
component.
      *
      * @return The number of fetch groups
      */
     int getNumberOfFetchGroups();

     /**
      * Accessor for all column(s) defined on the join.
      *
      * @return The column(s)
      */
     ColumnMetadata[] getColumns();

     /**
      * Add a new column for this join.
      *
      * @return The ColumnMetadata
      */
     ColumnMetadata newColumnMetadata();

     /**
      * Accessor for the number of columns defined for this join.
      *
      * @return The number of columns
      */
     int getNumberOfColumns();
}

Class Metadata
ClassMetadata represents metadata for a specific persistence-capable  
class.
/**
  * Represents a class.
  * @since 2.3
  */
public interface ClassMetadata extends ComponentMetadata {
     /**
      * Method to define the persistence modifier.
      * @param mod persistence modifier
      */
     ClassMetadata setPersistenceModifier(ClassPersistenceModifier mod);

     /**
      * Accessor for the persistence modifier.
      * @return persistence modifier
      */
     ClassPersistenceModifier getPersistenceModifier();

     /**
      * Add a new field to this class.
      * @param name Name of the field
      * @return The FieldMetadata
      */
     FieldMetadata newFieldMetadata(String name);

     /**
      * Add a new field to this class.
      * @param fld The field
      * @return The FieldMetadata
      */
     FieldMetadata newFieldMetadata(Field fld);
}

Interface Metadata
InterfaceMetadata represents metadata for a specific persistence- 
capable interface.
/**
  * Represents a persistent-interface.
  * @since 2.3
  */
public interface InterfaceMetadata extends ComponentMetadata {

}

Field Metadata
FieldMetadata represents metadata for persistent fields.
/**
  * Represents a field in a class.
  * @since 2.3
  */
public interface FieldMetadata extends MemberMetadata {

}

Property Metadata
PropertyMetadata represents metadata for persistent properties.
/**
  * Represents a property in a class/persistent-interface.
  * @since 2.3
  */
public interface PropertyMetadata extends MemberMetadata {
     /**
      * Method to set the field name (persistent interfaces)
      *
      * @param name field name
      */
     PropertyMetadata setFieldName(String name);

     /**
      * Accessor for the field name
      *
      * @return Field name
      */
     String getFieldName();
}

Query Metadata
QueryMetadata represents metadata for queries.
/**
  * Represents a named query.
  * @since 2.3
  */
public interface QueryMetadata extends Metadata {
     /**
      * Accessor for the name of the query (set on construction).
      *
      * @return The name
      */
     String getName();

     /**
      * Method to set the language of the query.
      *
      * @param lang Query language
      */
     QueryMetadata setLanguage(String lang);

     /**
      * Accessor for the query language.
      *
      * @return The language
      */
     String getLanguage();

     /**
      * Method to set the single-string query.
      *
      * @param query The query
      */
     QueryMetadata setQuery(String query);

     /**
      * Accessor for the single-string query.
      *
      * @return The query
      */
     String getQuery();

     /**
      * Method to set the result class name for the query
      *
      * @param clsName Result class name
      */
     QueryMetadata setResultClass(String clsName);

     /**
      * Accessor for the result class name for the query.
      *
      * @return The result class name
      */
     String getResultClass();

     /**
      * Method to set if the query results are unique
      *
      * @param unique Whether they are unique
      */
     QueryMetadata setUnique(boolean unique);

     /**
      * Accessor for whether results from the query are unique
      *
      * @return Results are unique?
      */
     Boolean getUnique();

     /**
      * Method to set the query as not being modifiable from now.
      */
     QueryMetadata setUnmodifiable();

     /**
      * Accessor for whether the query is unmodifiable.
      *
      * @return Can’t be changed?
      */
     boolean getUnmodifiable();

     /**
      * Method to set the FetchPlan to use for this named query.
      *
      * @param fetchPlanName name of the FetchPlan
      */
     QueryMetadata setFetchPlan(String fetchPlanName);

     /**
      * Accessor for the name of a fetch plan to use (if any).
      *
      * @return The fetch plan name
      */
     String getFetchPlan();
}


23.1
Standard Enhancement
The enhancement process consists of two distinct functions: analyzing  
user input as to how and what to enhance; and performing the  
enhancement of the persistent classes. A Java main program is  
distributed as part of the java specification jar. Plugins for  
Interactive Development Environments are anticipated by the  
architecture but not provided by the JDO specification jar itself.  
Enhancing the persistent classes is the function of a JDO  
implementation, and in particular, the Reference Implementation. The  
Enhancer main program calls a standard enhancer by using the services  
locator architecture. Thus, the Enhancer main program can call any  
enhancer provided by a JDO implementation and made available on the  
class path.
The name of the class that implements the JDOEnhancer API must be in  
the class path in the file called META-INF/services/ 
javax.jdo.JDOEnhancer.
The enhancer operates on the byte code representation of persistent  
classes, and creates new byte code representations of the classes. The  
input byte code representations can come from four sources:
a byte array such as might be created by a dynamic class generator;
a file that contains the byte codes as generated by the javac compiler;
a jar file containing multiple classes and metadata files;
a resource loaded from a class loader that contains the byte codes as  
generated by the javac compiler
The output byte code representations can be written to one of three  
destinations:
the same file as was provided as input;
the same jar file as was provided as input, in which case all contents  
of the jar file that are not enhanced are preserved intact;
a directory that contains package names as directory names with  
identical semantics to the javac compiler's output directive.
Restrictions: if a resource is used as input, then the only output  
possible is a directory. If a class file or jar file is used as input,  
the file must be read/write. If a byte array is used as input, then  
the enhanced byte array is available via a separate method call and is  
not written to output.
Enhancer Main
The Enhancer main class is intended to be run from an interactive  
shell (command line). It analyzes arguments and delegates to an  
implementation. The implementation must be identified via an entry in  
the class loader's resource file META-INF/services/ 
javax.jdo.JDOEnhancer. If multiple such files exist, the Enhancer main  
uses the first file containing the name of a class that can be loaded  
by the Class.forName method, containing a public no-args constructor,  
that returns an instance that implements javax.jdo.JDOEnhancer.
The enhancer is invoked with the following command line:
java -cp <classpath> javax.jdo.Enhancer <options> <directory, class,  
jdo, or jar file names>
<classpath> must contain the jdo specification jar, the implementation  
jar and any implementation dependencies, the statically-compiled  
classes, and the jdo metadata files loadable as resources
<options> include:
-pu <persistence-unit-name> : the name of a persistence unit
-d <target directory> : write the enhanced classes to the specified  
directory
-checkonly : just check the classes for enhancement status
-v : verbose output
-r : recurse through directories to find all classes and metadata  
files to enhance
-cp <enhancer class loader path> : if not already included in the java  
class loader, this parameter must contain the statically-compiled  
classes, and the jdo metadata files loadable as resources
<directory, file, or resource names>

Each entry following the options must be a directory, a file, or a  
resource name.
The enhancer main program processes the command line and passes the  
parameters to the enhancer found via services lookup.
Parameters are processed until the first non-option parameter is  
found. All subsequent parameters are treated as directory, file, or  
resource names. Parameters beginning with "-" are considered to be  
options. If an option is not a standard option, it is added to the non- 
standard options list. If a non-standard option is not recognized, the  
enhancer program exits with error code 3 (ENHANCER_USAGE_ERROR).
Parameters are processed as follows:
-cp <enhancer class loader path>: If this option is present, a new  
class loader is constructed, parented with the context class loader,  
to which the urls in the <enhancer class loader path> are added. The  
format of <enhancer class loader path> is the same as the -cp option  
of the java command. The class loader is passed to the enhancer via  
the setClassLoader method.
-pu <persistence-unit-name>: If this option is present, each  
persistence-unit-name is passed to the enhancer via the  
addPersistenceUnit method.
-d <target directory>: If this option is present, the target directory  
is passed to the enhancer via the setOutputDirectory method.
-v: If this option is present, the verbose flag is set via the  
setVerbose method.
-r: If this option is present, directories are recursively searched  
for files.
-checkonly: If this option is present, the files are not enhanced, but  
verified via the validate method. If this option is absent, the files  
are enhanced via the enhance method.
Parameters that follow the last option are passed to the enhancer. The  
enhancer handles the files as follows:
For a .class file, the file must contain the byte codes of a  
persistent class consistent with the file name. Metadata is found  
using the algorithm detailed in Chapter 18, using the path specified  
for the .class file and recursing through parent directories in the  
file system. All class file names are passed to the enhancer via the  
addClasses method.
For a .jdo file, the file must be a valid metadata file and the  
classes described in the file are treated as described (persistence- 
capable, persistence-aware, or not persistent).  Metadata is found  
using the algorithm detailed in Chapter 18. All file names are passed  
to the enhancer via the addFiles method.
For a .jar file, the file may contain .class files and .jdo metadata  
files. Each jar file name is passed to the enhancer via the addJar  
method.
For a directory, the contents of the directory are analyzed  
for .class, .jdo, and .jar files which are then treated as if they  
were passed directly, as directory/*.class directory/*.jdo or  
directory/*.jar. If the -r option is specified, each subdirectory of  
the directory is treated as if it were itself the directory parameter,  
recursively. Thus, every .class file, .jdo file, and .jar file in the  
directory are included as files for enhancement.
Files that are not recognized as above are silently ignored.

23.22
Enhancer API
/**
  * Interface for a JDO Enhancer.
  * @since 2.3
  */
public interface JDOEnhancer extends ClassFileTransformer
{
     /**
      * Return non-configurable properties of this JDOEnhancer.
      * Properties with keys “VendorName” and “VersionNumber” are  
required.
      * Other keys are optional.
      * @return the non-configurable properties of this JDOEnhancer.
      */
     Properties getProperties();

     /**
      * Whether to provide verbose output
      * @param flag Verbose?
      * @return The enhancer
      */
     JDOEnhancer setVerbose(boolean flag);

     /**
      * Mutator to set the location where enhanced classes are written.
      * Mutator to set the location where enhanced classes are written.
      * If this method is not called, classes will be enhanced in place,
      * overwriting the existing classes. If overwriting classes in a  
jar file,
      * the existing files in the jar file will be written unchanged  
except
      * for the enhanced classes. The directory name can be absolute  
or relative.
      * @param dirName Name of the directory
      * @return The enhancer
      */
     JDOEnhancer setOutputDirectory(String dirName);

     /**
      * Mutator to set the class loader to use for loading classes.
      * @param loader ClassLoader to use
      * @return The enhancer
      */
     JDOEnhancer setClassLoader(ClassLoader loader);

     /**
      * Add a persistence-unit to the items to be enhanced.
      * @param persistenceUnit Name of the persistence unit
      * @return The enhancer
      */
     JDOEnhancer addPersistenceUnit(String persistenceUnit);

     /**
      * Add an in-memory class to the items to be enhanced.
      * The class name should be of the form “mydomain.MyClass”.
      * @param className Name of the class
      * @param bytes The bytes of the class
      * @return The enhancer
      */
     JDOEnhancer addClass(String className, byte[] bytes);

     /**
      * Add class(es) to the items to be enhanced.
      * The class names can be absolute file names, relative file  
names, or
      * names of CLASSPATH resources.
      * @param classNames Names of the classes
      * @return The enhancer
      */
     JDOEnhancer addClasses(String... classNames);

     /**
      * Add metadata file(s) to the items to be enhanced.
      * The metadata file names can be absolute file names, relative  
file names, or
      * names of CLASSPATH resources. They should be JDO XML metadata  
files.
      * @param metadataFiles Names of the files
      * @return The enhancer
      */
     JDOEnhancer addFiles(String... metadataFiles);

     /**
      * Add a jar file to the items to be enhanced.
      * The jar file name can be absolute, or relative or a CLASSPATH  
resource.
      * @param jarFileName Name of the jar file
      * @return The enhancer
      */
     JDOEnhancer addJar(String jarFileName);

     /**
      * Method to enhance the items specified using addJar, addFiles,  
addClasses, addClass,
      * addPersistenceUnit.
      * @return Number of classes enhanced
      * @throws JDOEnhanceException if an error occurs during  
enhancement. If multiple
      * errors occur then the nested exceptions provides this detail.
      */
     int enhance();

     /**
      * Method to validate the items specified using addJar, addFiles,  
addClasses, addClass,
      * addPersistenceUnit.
      * @return Number of classes validated
      * @throws JDOEnhanceException if an error occurs during  
validation. If multiple
      * errors occur then the nested exceptions provides this detail.
      */
     int validate();

     /**
      * Method to retrieve the (enhanced) bytes of the specified class.
      * Only applies to the classes enhanced in the most recent  
enhance() call.
      * If no enhance has yet been performed will throw a  
JDOEnhanceException.
      * If the specified class hasn’t been enhanced then will throw a  
JDOEnhanceException.
      * @param className Name of the class (of the form  
“mydomain.MyClass”)
      * @return Enhanced bytes
      */
     byte[] getEnhancedBytes(String className);

     /**
      * Method to register metadata with the enhancement process  
managed by this
      * <code>JDOEnhancer</code>.
      * Metadata can be created using the method {@link #newMetadata}.
      * If there is already metadata registered for a class contained  
in this metadata
      * object then a JDOUserException will be thrown.
      * @param metadata The Metadata to register.
      * @since 2.3
      */
     void registerMetadata(JDOMetadata metadata);

     /**
      * Method to return a new metadata object that can be  
subsequently modified
      * and registered with the enhancement process using the method  
{@link #registerMetadata}.
      * @return The metadata
      * @since 2.3
      */
     JDOMetadata newMetadata();
}

Craig L Russell
Architect, Sun Java Enterprise System http://db.apache.org/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Mime
View raw message