Added: incubator/jdo/trunk/api20/src/java/javax/jdo/spi/I18NHelper.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/I18NHelper.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/I18NHelper.java (added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/I18NHelper.java Mon Mar 28 
10:25:05 2005
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+/*
+ * I18NHelper.java
+ *
+ */
+
+package javax.jdo.spi;
+
+import java.util.*;
+import java.text.MessageFormat;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.jdo.JDOFatalInternalException;
+
+/** Helper class for constructing messages from bundles.  The intended usage
+ * of this class is to construct a new instance bound to a bundle, as in
+ * <P>
+ * <code>I18NHelper msg = I18NHelper.getInstance("javax.jdo.Bundle");</code>
+ * <P>
+ * This call uses the class loader that loaded the I18NHelper class to find
+ * the specified Bundle. The class provides two overloaded getInstance
+ * methods allowing to specify a different class loader: 
+ * [EMAIL PROTECTED] #getInstance(Class cls)} looks for a bundle
+ * called "Bundle.properties" located in the package of the specified class 
+ * object and [EMAIL PROTECTED] #getInstance(String bundleName,ClassLoader 
loader)} 
+ * uses the specified class loader to find the bundle.
+ * <P>
+ * Subsequently, instance methods can be used to format message strings 
+ * using the text from the bundle, as in 
+ * <P>
+ * <code>throw new JDOFatalInternalException (msg.msg("ERR_NoMetadata", 
cls.getName()));</code>
+ * @since 1.0.1
+ * @version 1.0.2
+ */        
+public class I18NHelper {
+
+    /** Bundles that have already been loaded 
+     */
+    private static Hashtable    bundles = new Hashtable();
+    
+    /** Helper instances that have already been created 
+     */
+    private static Hashtable    helpers = new Hashtable();
+    
+    /** The default locale for this VM.
+     */
+    private static Locale       locale = Locale.getDefault();
+    
+    /** The bundle used by this instance of the helper.
+     */
+    private ResourceBundle      bundle = null;
+
+    /** Throwable if ResourceBundle couldn't be loaded
+     */
+    private Throwable           failure = null;
+
+    /** The unqualified standard name of a bundle. */
+    private static final String bundleSuffix = ".Bundle";    // NOI18N
+
+    /** Constructor */
+    private I18NHelper() {
+    }
+
+    /** Constructor for an instance bound to a bundle.
+     * @param bundleName the name of the resource bundle
+     * @param loader the class loader from which to load the resource
+     * bundle
+     */
+    private I18NHelper (String bundleName, ClassLoader loader) {
+        try {
+            bundle = loadBundle (bundleName, loader);
+        }
+        catch (Throwable e) {
+            failure = e;
+        }
+    }
+    
+    /** An instance bound to a bundle. This method uses the current class 
+     * loader to find the bundle.
+     * @param bundleName the name of the bundle
+     * @return the helper instance bound to the bundle
+     */
+    public static I18NHelper getInstance (String bundleName) {
+        return getInstance (bundleName, I18NHelper.class.getClassLoader());
+    }
+
+    /** An instance bound to a bundle. This method figures out the bundle name
+     * for the class object's package and uses the class' class loader to
+     * find the bundle. Note, the specified class object must not be
+     * <code>null</code>.
+     * @param cls the class object from which to load the resource bundle
+     * @return the helper instance bound to the bundle
+     */
+    public static I18NHelper getInstance (final Class cls) {
+        ClassLoader classLoader = (ClassLoader) AccessController.doPrivileged (
+            new PrivilegedAction () {
+                public Object run () {
+                    return cls.getClassLoader();
+                }
+            }
+            );
+        String bundle = getPackageName (cls.getName()) + bundleSuffix;
+        return getInstance (bundle, classLoader);
+    }
+
+    /** An instance bound to a bundle. This method uses the specified class
+     * loader to find the bundle. Note, the specified class loader must not
+     * be <code>null</code>.
+     * @param bundleName the name of the bundle
+     * @param loader the class loader from which to load the resource
+     * bundle
+     * @return the helper instance bound to the bundle
+     */
+    public static I18NHelper getInstance (String bundleName, 
+                                          ClassLoader loader) {
+        I18NHelper helper = (I18NHelper) helpers.get (bundleName);
+        if (helper != null) {
+            return helper;
+        }
+        helper = new I18NHelper(bundleName, loader);
+        helpers.put (bundleName, helper);
+        // if two threads simultaneously create the same helper, return the 
first
+        // one to be put into the Hashtable.  The other will be garbage 
collected.
+        return (I18NHelper) helpers.get (bundleName);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @return the resolved message text
+     */
+    public String msg (String messageKey) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object arg1) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, arg1);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object arg1, Object arg2) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, arg1, arg2);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @param arg3 the third argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object arg1, Object arg2, Object 
arg3) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, arg1, arg2, arg3);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param args the array of arguments
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, Object[] args) {
+        assertBundle (messageKey);
+        return getMessage (bundle, messageKey, args);
+    }
+
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, int arg) {
+        assertBundle (messageKey);
+        return getMessage(bundle, messageKey, arg);
+    }
+    
+    /** Message formatter
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    public String msg (String messageKey, boolean arg) {
+        assertBundle (messageKey);
+        return getMessage(bundle, messageKey, arg);
+    }
+    
+    //========= Internal helper methods ==========
+
+    /**
+     * Load ResourceBundle by bundle name
+     * @param bundleName the name of the bundle
+     * @param loader the class loader from which to load the resource bundle
+     * @return  the ResourceBundle
+     */
+    final private static ResourceBundle loadBundle(
+        String bundleName, ClassLoader loader) {
+        ResourceBundle messages = (ResourceBundle)bundles.get(bundleName);
+
+        if (messages == null) //not found as loaded - add
+        {
+            messages = ResourceBundle.getBundle(bundleName, locale, loader);
+            bundles.put(bundleName, messages);
+        }
+        return messages;
+    }
+
+    /** Assert resources available
+     * @param key the message key 
+     * @since 1.0.2
+     * @throws JDOFatalInternalException if the resource bundle could not
+     * be loaded during construction.
+     */
+    private void assertBundle (String key) {
+        if (failure != null)
+            throw new JDOFatalInternalException (
+                "No resources could be found to annotate error message key:\"" 
+ 
+                key + "\"", failure);
+    }
+
+    /**
+     * Returns message as <code>String</code>
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey) 
+    {
+        return messages.getString(messageKey);
+    }
+
+    /**
+     * Formats message by adding array of arguments
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param msgArgs an array of arguments to substitute into the message
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey, Object msgArgs[]) 
+    {
+        for (int i=0; i<msgArgs.length; i++) {
+            if (msgArgs[i] == null) msgArgs[i] = ""; // NOI18N
+        }
+        MessageFormat formatter = new 
MessageFormat(messages.getString(messageKey));
+        return formatter.format(msgArgs);
+    }
+    
+    /**
+     * Formats message by adding an <code>Object</code> argument.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey, Object arg) 
+    {
+        Object []args = {arg};
+        return getMessage(messages, messageKey, args);
+    }
+    
+    /**
+     * Formats message by adding two <code>Object</code> arguments.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey, Object arg1,
+                                   Object arg2) 
+    {
+        Object []args = {arg1, arg2};
+        return getMessage(messages, messageKey, args);
+    }
+    
+    /**
+     * Formats message by adding three <code>Object</code> arguments.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg1 the first argument
+     * @param arg2 the second argument
+     * @param arg3 the third argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey, Object arg1,
+                                   Object arg2, Object arg3) 
+    {
+        Object []args = {arg1, arg2, arg3};
+        return getMessage(messages, messageKey, args);
+    }
+
+    /**
+     * Formats message by adding an <code>int</code> as an argument.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey, int arg) 
+    {
+        Object []args = {new Integer(arg)};
+        return getMessage(messages, messageKey, args);
+    }
+    
+    /**
+     * Formats message by adding a <code>boolean</code> as an argument.
+     * @param messages the resource bundle
+     * @param messageKey the message key
+     * @param arg the argument
+     * @return the resolved message text
+     */
+    final private static String getMessage(ResourceBundle messages, String 
messageKey, boolean arg) 
+    {
+        Object []args = {String.valueOf(arg)};
+        return getMessage(messages, messageKey, args);
+    }
+
+    /**  
+     * Returns the package portion of the specified class.
+     * @param className the name of the class from which to extract the 
+     * package 
+     * @return package portion of the specified class
+     */   
+    final private static String getPackageName(final String className)
+    { 
+        final int index = className.lastIndexOf('.');
+        return ((index != -1) ? className.substring(0, index) : ""); // NOI18N
+    }
+}

Added: incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOImplHelper.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOImplHelper.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOImplHelper.java (added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOImplHelper.java Mon Mar 
28 10:25:05 2005
@@ -0,0 +1,587 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+/*
+ * JDOImplHelper.java
+ *
+ */
+
+package javax.jdo.spi;
+
+import java.util.HashMap;
+import java.util.WeakHashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.jdo.spi.JDOPermission;
+import javax.jdo.JDOFatalUserException;
+import javax.jdo.JDOFatalInternalException;
+
+/** This class is a helper class for JDO implementations.  It contains methods
+ * to register metadata for persistence-capable classes and to perform common
+ * operations needed by implementations, not by end users.
+ * <P><code>JDOImplHelper</code> allows construction of instances of 
persistence-capable
+ * classes without using reflection.
+ * <P>Persistence-capable classes register themselves via a static method 
+ * at class load time.
+ * There is no security restriction on this access.  JDO implementations
+ * get access to the functions provided by this class only if they are
+ * authorized by the security manager.  To avoid having every call go through
+ * the security manager, only the call to get an instance is checked.  Once an 
+ * implementation
+ * has an instance, any of the methods can be invoked without security checks.
+ * @version 1.0.2
+ *
+ */
+public class JDOImplHelper extends java.lang.Object {
+    
+    /** This synchronized <code>HashMap</code> contains a static mapping of
+     * <code>PersistenceCapable</code> class to
+     * metadata for the class used for constructing new instances.  New entries
+     * are added by the static method in each <code>PersistenceCapable</code> 
class.
+     * Entries are never removed.
+     */    
+    private static Map registeredClasses = Collections.synchronizedMap(new 
HashMap ());
+    
+    /** This Set contains all classes that have registered for setStateManager
+     * permissions via authorizeStateManagerClass.
+     */
+    private static Map authorizedStateManagerClasses = new WeakHashMap();
+
+    /** This list contains the registered listeners for 
<code>RegisterClassEvent</code>s.
+     */
+    private static List listeners = new ArrayList();
+
+    /** The singleton <code>JDOImplHelper</code> instance.
+     */    
+    private static JDOImplHelper jdoImplHelper = new JDOImplHelper();
+    
+    /** The Internationalization message helper.
+     */
+    private final static I18NHelper msg = I18NHelper.getInstance 
("javax.jdo.Bundle");
+    
+    /** Creates new JDOImplHelper */
+    private JDOImplHelper() {
+    }
+    
+    /** Get an instance of <code>JDOImplHelper</code>.  This method
+     * checks that the caller is authorized for 
<code>JDOPermission("getMetadata")</code>,
+     * and if not, throws <code>SecurityException</code>.
+     * @return an instance of <code>JDOImplHelper</code>.
+     * @throws SecurityException if the caller is not authorized for 
JDOPermission("getMetadata").
+     */    
+    public static JDOImplHelper getInstance() 
+        throws SecurityException {        
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) { 
+            // throws exception if caller is not authorized
+            sec.checkPermission (JDOPermission.GET_METADATA);
+        }
+        return jdoImplHelper;
+    }
+    
+    /** Get the field names for a <code>PersistenceCapable</code> class.  The 
order 
+     * of fields is the natural ordering of the <code>String</code> class 
(without
+     * considering localization).
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @return the field names for the class.
+     */    
+    public String[] getFieldNames (Class pcClass) {
+        Meta meta = getMeta (pcClass);
+        return meta.getFieldNames();
+    }
+
+    /** Get the field types for a <code>PersistenceCapable</code> class.  The 
order
+     * of fields is the same as for field names.
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @return the field types for the class.
+     */    
+    public Class[] getFieldTypes (Class pcClass) {
+        Meta meta = getMeta (pcClass);
+        return meta.getFieldTypes();
+    }
+            
+    /** Get the field flags for a <code>PersistenceCapable</code> class.  The 
order
+     * of fields is the same as for field names.
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @return the field types for the class.
+     */    
+    public byte[] getFieldFlags (Class pcClass) {
+        Meta meta = getMeta (pcClass);
+        return meta.getFieldFlags();
+    }
+            
+    /** Get the persistence-capable superclass for a 
<code>PersistenceCapable</code> class.
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @return The <code>PersistenceCapable</code> superclass for this class,
+     * or <code>null</code> if there isn't one.
+     */    
+    public Class getPersistenceCapableSuperclass (Class pcClass) {
+        Meta meta = getMeta (pcClass);
+        return meta.getPersistenceCapableSuperclass();
+    }
+            
+    
+    /** Create a new instance of the class and assign its 
<code>jdoStateManager</code>.
+     * The new instance has its <code>jdoFlags</code> set to 
<code>LOAD_REQUIRED</code>.
+     * @see PersistenceCapable#jdoNewInstance(StateManager sm)
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @param sm the <code>StateManager</code> which will own the new instance.
+     * @return the new instance, or <code>null</code> if the class is not 
registered.
+     */    
+    public PersistenceCapable newInstance (Class pcClass, StateManager sm) {
+        Meta meta = getMeta (pcClass);
+        PersistenceCapable pcInstance = meta.getPC();
+        return pcInstance == null?null:pcInstance.jdoNewInstance(sm);
+    }
+    
+    /** Create a new instance of the class and assign its 
<code>jdoStateManager</code> and 
+     * key values from the ObjectId.  If the oid parameter is 
<code>null</code>,
+     * no key values are copied.
+     * The new instance has its <code>jdoFlags</code> set to 
<code>LOAD_REQUIRED</code>.
+     * @see PersistenceCapable#jdoNewInstance(StateManager sm, Object oid)
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @param sm the <code>StateManager</code> which will own the new instance.
+     * @return the new instance, or <code>null</code> if the class is not 
registered.
+     * @param oid the ObjectId instance from which to copy key field values.
+ */    
+    public PersistenceCapable newInstance 
+            (Class pcClass, StateManager sm, Object oid) {
+        Meta meta = getMeta (pcClass);
+        PersistenceCapable pcInstance = meta.getPC();
+        return pcInstance == null?null:pcInstance.jdoNewInstance(sm, oid);
+    }
+    
+    /** Create a new instance of the ObjectId class of this
+     * <code>PersistenceCapable</code> class.
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     * @return the new ObjectId instance, or <code>null</code> if the class is 
not registered.
+     */    
+    public Object newObjectIdInstance (Class pcClass) {
+        Meta meta = getMeta (pcClass);
+        PersistenceCapable pcInstance = meta.getPC();
+        return pcInstance == null?null:pcInstance.jdoNewObjectIdInstance();
+    }
+    
+    /** Create a new instance of the ObjectId class of this 
<code>PersistenceCapable</code>
+     * class, using the <code>String</code> form of the constructor.
+     * @return the new ObjectId instance, or <code>null</code> if the class is 
not registered.
+     * @param str the <code>String</code> form of the object id
+     * @param pcClass the <code>PersistenceCapable</code> class.
+     */    
+    public Object newObjectIdInstance (Class pcClass, String str) {
+        Meta meta = getMeta (pcClass);
+        PersistenceCapable pcInstance = meta.getPC();
+        return pcInstance == null?null:pcInstance.jdoNewObjectIdInstance(str);
+    }
+    
+    /** Copy fields from an outside source to the key fields in the ObjectId.
+     * This method is generated in the <code>PersistenceCapable</code> class to
+     * generate a call to the field manager for each key field in the 
ObjectId.  
+     * <P>For example, an ObjectId class that has three key fields (<code>int 
id</code>, 
+     * <code>String name</code>, and <code>Float salary</code>) would have the 
method generated:
+     * <P><code>
+     * void jdoCopyKeyFieldsToObjectId (Object oid, ObjectIdFieldSupplier fm) {
+     * <BR>    oid.id = fm.fetchIntField (0);
+     * <BR>    oid.name = fm.fetchStringField (1);
+     * <BR>    oid.salary = fm.fetchObjectField (2);
+     * <BR>}</code>
+     * <P>The implementation is responsible for implementing the 
+     * <code>ObjectIdFieldSupplier</code> to provide the values for the key 
fields.
+     * @param pcClass the <code>PersistenceCapable Class</code>.
+     * @param oid the ObjectId target of the copy.
+     * @param fm the field manager that supplies the field values.
+ */    
+    public void copyKeyFieldsToObjectId 
+    (Class pcClass, PersistenceCapable.ObjectIdFieldSupplier fm, Object oid) {
+        Meta meta = getMeta (pcClass);
+        PersistenceCapable pcInstance = meta.getPC();
+        if (pcInstance == null) {
+            throw new JDOFatalInternalException (
+                msg.msg("ERR_AbstractClassNoIdentity", pcClass.getName())); 
//NOI18N
+        }
+        pcInstance.jdoCopyKeyFieldsToObjectId(fm, oid);
+    }
+
+    /** Copy fields to an outside source from the key fields in the ObjectId.
+     * This method is generated in the <code>PersistenceCapable</code> class 
to generate
+     * a call to the field manager for each key field in the ObjectId.  For
+     * example, an ObjectId class that has three key fields (<code>int 
id</code>,
+     * <code>String name</code>, and <code>Float salary</code>) would have the 
method generated:
+     * <P><code>void jdoCopyKeyFieldsFromObjectId
+     * <BR>        (PersistenceCapable oid, ObjectIdFieldConsumer fm) {
+     * <BR>     fm.storeIntField (0, oid.id);
+     * <BR>     fm.storeStringField (1, oid.name);
+     * <BR>     fm.storeObjectField (2, oid.salary);
+     * <BR>}</code>
+     * <P>The implementation is responsible for implementing the
+     * <code>ObjectIdFieldConsumer</code> to store the values for the key 
fields.
+     * @param pcClass the <code>PersistenceCapable</code> class
+     * @param oid the ObjectId source of the copy.
+     * @param fm the field manager that receives the field values.
+     */    
+    public void copyKeyFieldsFromObjectId
+    (Class pcClass, PersistenceCapable.ObjectIdFieldConsumer fm, Object oid) {
+        Meta meta = getMeta (pcClass);
+        PersistenceCapable pcInstance = meta.getPC();
+        if (pcInstance == null) {
+            throw new JDOFatalInternalException (
+                msg.msg("ERR_AbstractClassNoIdentity", pcClass.getName())); 
//NOI18N
+        }
+        pcInstance.jdoCopyKeyFieldsFromObjectId(fm, oid);
+    }
+    
+    /** Register metadata by class.  The registration will be done in the
+     * class named <code>JDOImplHelper</code> loaded by the same or an
+     * ancestor class loader as the <code>PersistenceCapable</code> class
+     * performing the registration. 
+     *
+     * @param pcClass the <code>PersistenceCapable</code> class
+     * used as the key for lookup.
+     * @param fieldNames an array of <code>String</code> field names for 
persistent and transactional fields
+     * @param fieldTypes an array of <code>Class</code> field types
+     * @param fieldFlags the Field Flags for persistent and transactional 
fields
+     * @param pc an instance of the <code>PersistenceCapable</code> class
+     * @param persistenceCapableSuperclass the most immediate superclass that 
is <code>PersistenceCapable</code>
+     */    
+    public static void registerClass (Class pcClass, 
+            String[] fieldNames, Class[] fieldTypes, 
+            byte[] fieldFlags, Class persistenceCapableSuperclass,
+            PersistenceCapable pc) {
+        if (pcClass == null) 
+            throw new NullPointerException(msg.msg("ERR_NullClass"));
+        Meta meta = new Meta (fieldNames, fieldTypes, 
+            fieldFlags, persistenceCapableSuperclass, pc);
+        registeredClasses.put (pcClass, meta);
+
+        // handle class registration listeners
+        synchronized (listeners) {
+            if (!listeners.isEmpty()) {
+                RegisterClassEvent event = new RegisterClassEvent(
+                    jdoImplHelper, pcClass, fieldNames, fieldTypes, 
+                    fieldFlags, persistenceCapableSuperclass);
+                for (Iterator i = listeners.iterator(); i.hasNext();) {
+                    RegisterClassListener crl = 
+                        (RegisterClassListener)i.next();
+                    if (crl != null) {
+                        crl.registerClass(event);
+                    }
+                }
+            }
+        }
+    }
+        
+    /**
+     * Unregister metadata by class loader. This method unregisters all
+     * registered <code>PersistenceCapable</code> classes loaded by the
+     * specified class loader. Any attempt to get metadata for unregistered
+     * classes will result in a <code>JDOFatalUserException</code>. 
+     * @param cl the class loader.
+     * @since 1.0.2
+     */
+    public void unregisterClasses (ClassLoader cl)
+    {
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) { 
+            // throws exception if caller is not authorized
+            sec.checkPermission (JDOPermission.MANAGE_METADATA);
+        }
+        synchronized(registeredClasses) {
+            for (Iterator i = registeredClasses.keySet().iterator(); 
i.hasNext();) {
+                Class pcClass = (Class)i.next();
+                // Note, the pc class was registered by calling the static
+                // method JDOImplHelper.registerClass. This means the
+                // JDOImplHelper class loader is the same as or an ancestor
+                // of the class loader of the pc class. In this case method
+                // getClassLoader does not perform a security check for
+                // RuntimePermission("getClassLoader") and thus we do not 
+                // need a privileged block for the getClassLoader call.
+                if ((pcClass != null) && (pcClass.getClassLoader() == cl)) {
+                    // unregister pc class, if its class loader is the
+                    // specified one.
+                    i.remove();
+                }
+            }
+        }
+    }
+
+    /**
+     * Unregister metadata by class. This method unregisters the specified
+     * class. Any further attempt to get metadata for the specified class will
+     * result in a <code>JDOFatalUserException</code>. 
+     * @param pcClass the <code>PersistenceCapable</code> class to be 
unregistered.
+     * @since 1.0.2
+     */
+    public void unregisterClass (Class pcClass)
+    {
+        if (pcClass == null) 
+            throw new NullPointerException(msg.msg("ERR_NullClass"));
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) { 
+            // throws exception if caller is not authorized
+            sec.checkPermission (JDOPermission.MANAGE_METADATA);
+        }
+        registeredClasses.remove(pcClass);
+    }
+
+    /** 
+     * Add the specified <code>RegisterClassListener</code> to the listener 
list.
+     * @param crl the listener to be added
+     */
+    public void addRegisterClassListener (RegisterClassListener crl) {
+        HashSet alreadyRegisteredClasses = null;
+        synchronized (listeners) {
+            listeners.add(crl);
+            // Make a copy of the existing set of registered classes.
+            // Between these two lines of code, any number of new class 
registrations
+            // might occur, and will then all wait until this synchronized 
block completes.
+            // Some of the class registrations might be delivered twice to
+            // the newly registered listener.
+            alreadyRegisteredClasses = new HashSet 
(registeredClasses.keySet());
+        }
+        // new registrations will call the new listener while the following 
occurs
+        // notify the new listener about already-registered classes
+        for (Iterator it = alreadyRegisteredClasses.iterator(); it.hasNext();) 
{
+            Class pcClass = (Class)it.next();
+            Meta meta = getMeta (pcClass);
+            RegisterClassEvent event = new RegisterClassEvent(
+                this, pcClass, meta.getFieldNames(), meta.getFieldTypes(), 
+                meta.getFieldFlags(), meta.getPersistenceCapableSuperclass());
+            crl.registerClass (event);
+        }
+    }
+
+    /** 
+     * Remove the specified <code>RegisterClassListener</code> from the 
listener list.
+     * @param crl the listener to be removed
+     */
+    public void removeRegisterClassListener (RegisterClassListener crl) {
+        synchronized (listeners) {
+            listeners.remove(crl);
+        }
+    }
+
+    /**
+     * Returns a collection of class objects of the registered 
+     * persistence-capable classes.
+     * @return registered persistence-capable classes
+     */
+    public Collection getRegisteredClasses() {
+        return Collections.unmodifiableCollection(registeredClasses.keySet());
+    }
+
+    /** Look up the metadata for a <code>PersistenceCapable</code> class.
+     * @param pcClass the <code>Class</code>.
+     * @return the <code>Meta</code> for the <code>Class</code>.
+     */    
+    private static Meta getMeta (Class pcClass) {
+        Meta ret = (Meta) registeredClasses.get (pcClass);
+        if (ret == null) {
+            throw new JDOFatalUserException(
+                msg.msg ("ERR_NoMetadata", pcClass.getName())); //NOI18N
+        }
+        return ret;
+    }
+    
+    /** Register a class authorized to replaceStateManager.  The caller of
+     * this method must be authorized for JDOPermission("setStateManager").
+     * During replaceStateManager, a persistence-capable class will call
+     * the corresponding checkAuthorizedStateManager and the class of the
+     * instance of the parameter must have been registered.
+     * @param smClass a Class that is authorized for 
JDOPermission("setStateManager").
+     * @throws SecurityException if the caller is not authorized for 
JDOPermission("setStateManager").
+     * @since 1.0.1
+     */
+    public static void registerAuthorizedStateManagerClass (Class smClass) 
+        throws SecurityException {
+        if (smClass == null) 
+            throw new NullPointerException(msg.msg("ERR_NullClass"));
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(JDOPermission.SET_STATE_MANAGER);
+        }
+        synchronized (authorizedStateManagerClasses) {
+            authorizedStateManagerClasses.put(smClass, null);
+        }
+    }
+    
+    /** Register classes authorized to replaceStateManager.  The caller of
+     * this method must be authorized for JDOPermission("setStateManager").
+     * During replaceStateManager, a persistence-capable class will call
+     * the corresponding checkAuthorizedStateManager and the class of the
+     * instance of the parameter must have been registered.
+     * @param smClasses a Collection of Classes that are authorized for 
JDOPermission("setStateManager").
+     * @throws SecurityException if the caller is not authorized for 
JDOPermission("setStateManager").
+     * @since 1.0.1
+     */
+    public static void registerAuthorizedStateManagerClasses (Collection 
smClasses) 
+        throws SecurityException {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(JDOPermission.SET_STATE_MANAGER);
+            synchronized (authorizedStateManagerClasses) {
+                for (Iterator it = smClasses.iterator(); it.hasNext();) {
+                    Object smClass = it.next();
+                    if (!(smClass instanceof Class)) {
+                        throw new ClassCastException(
+                            msg.msg("ERR_StateManagerClassCast", 
+                                smClass.getClass().getName()));
+                    }
+                    registerAuthorizedStateManagerClass((Class)it.next());
+                }
+            }
+        }
+    }
+    
+    /** Check that the parameter instance is of a class that is authorized for
+     * JDOPermission("setStateManager").  This method is called by the
+     * replaceStateManager method in persistence-capable classes.
+     * A class that is passed as the parameter to replaceStateManager must be
+     * authorized for JDOPermission("setStateManager").  To improve 
performance,
+     * first the set of authorized classes is checked, and if not present, a
+     * regular permission check is made.  The regular permission check requires
+     * that all callers on the stack, including the persistence-capable class
+     * itself, must be authorized for JDOPermission("setStateManager").
+     * @param sm an instance of StateManager whose class is to be checked.
+     * @since 1.0.1
+     */
+    public static void checkAuthorizedStateManager (StateManager sm) {
+        checkAuthorizedStateManagerClass(sm.getClass());
+    }
+
+    /** Check that the parameter instance is a class that is authorized for
+     * JDOPermission("setStateManager").  This method is called by the
+     * constructors of JDO Reference Implementation classes.
+     * @param smClass a Class to be checked for 
JDOPermission("setStateManager")
+     * @since 1.0.1
+     */
+    public static void checkAuthorizedStateManagerClass (Class smClass) {
+        final SecurityManager scm = System.getSecurityManager();
+        if (scm == null) {
+            // if no security manager, no checking.
+            return;
+        }
+        synchronized(authorizedStateManagerClasses) {
+            if (authorizedStateManagerClasses.containsKey(smClass)) {
+                return;
+            }
+        }
+
+        // if not already authorized, perform "long" security checking.
+        scm.checkPermission(JDOPermission.SET_STATE_MANAGER);
+    }
+
+    /** This is a helper class to manage metadata per persistence-capable
+     * class.  The information is used at runtime to provide field names and
+     * field types to the JDO Model.
+     *
+     * This is the value of the <code>HashMap</code> which
+     * relates the <code>PersistenceCapable Class</code>
+     * as a key to the metadata.
+     */    
+    static class Meta {
+        
+        /** Construct an instance of <code>Meta</code>.
+         * @param fieldNames An array of <code>String</code>
+         * @param fieldTypes An array of <code>Class</code>
+         * @param fieldFlags an array of <code>int</code>
+         * @param persistenceCapableSuperclass the most immediate 
<code>PersistenceCapable</code> superclass
+         * @param pc An instance of the <code>PersistenceCapable</code> class
+         */        
+        Meta (String[] fieldNames, Class[] fieldTypes, byte[] fieldFlags,
+              Class persistenceCapableSuperclass, PersistenceCapable pc) {
+            this.fieldNames = fieldNames;
+            this.fieldTypes = fieldTypes;
+            this.fieldFlags = fieldFlags;
+            this.persistenceCapableSuperclass = persistenceCapableSuperclass;
+            this.pc = pc;
+        }
+    
+        /** This is an array of field names used
+         * for the Model at runtime.  The field
+         * is passed by the static class initialization.
+         */
+        String fieldNames[];
+    
+        /** Get the field names from the metadata.
+         * @return the array of field names.
+         */
+        String[] getFieldNames() {
+            return fieldNames;
+        }
+    
+        /** This is an array of field types used
+         * for the Model at runtime.  The field
+         * is passed by the static class initialization.
+         */
+        Class fieldTypes[];
+    
+        /** Get the field types from the metadata.
+         * @return the array of field types.
+         */
+        Class[] getFieldTypes() {
+            return fieldTypes;
+        }
+    
+        /** This is an array of field flags used
+         * for the Model at runtime.  The field
+         * is passed by the static class initialization.
+         */
+        byte fieldFlags[];
+    
+        /** Get the field types from the metadata.
+         * @return the array of field types.
+         */
+        byte[] getFieldFlags() {
+            return fieldFlags;
+        }
+
+        /** This is the <code>Class</code> instance of the 
<code>PersistenceCapable</code> superclass.
+         */
+        Class persistenceCapableSuperclass;
+    
+        /** Return the <code>PersistenceCapable</code> superclass.
+         * @return the <code>PersistenceCapable</code> superclass
+         */
+        Class getPersistenceCapableSuperclass() {
+            return persistenceCapableSuperclass;
+        }
+        /** This is an instance of <code>PersistenceCapable</code>,
+         * used at runtime to create new instances.
+         */
+        PersistenceCapable pc;
+    
+        /** Get an instance of the <code>PersistenceCapable</code> class.
+         * @return an instance of the <code>PersistenceCapable Class</code>.
+         */
+        PersistenceCapable getPC() {
+            return pc;
+        }
+    
+        /** Return the string form of the metadata.
+         * @return the string form
+         */
+        public String toString() {
+            return "Meta-" + pc.getClass().getName(); //NOI18N
+        }
+    }
+}

Added: incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOPermission.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOPermission.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOPermission.java (added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/JDOPermission.java Mon Mar 
28 10:25:05 2005
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package javax.jdo.spi;
+
+/**
+ * The <code>JDOPermission</code> class is for operations that are reserved 
for JDO 
+ * implementations and should not be called by other code.  A
+ * <code>JDOPermission</code> is a <em>named permission</em> and has no
+ * actions.  There are two names currently defined.  Each named permission
+ * has a corresponding public static final field which contains an instance
+ * of the named permission.
+ * <P>
+ * The following table
+ * provides a summary description of what each named permission allows,
+ * and discusses the risks of granting code the permission.
+ * <P>
+ *
+ * <table border=1 cellpadding=5>
+ * <tr>
+ * <th>Permission Target Name</th>
+ * <th>What the Permission Allows</th>
+ * <th>Risks of Allowing this Permission</th>
+ * </tr>
+ *
+ * <tr>
+ *   <td><code>setStateManager</code></td>
+ *   <td>This allows setting the <code>StateManager</code> for an instance of 
<code>PersistenceCapable</code>. 
+ *   The <code>StateManager</code>
+ *   has unlimited access to get and set persistent and transactional fields of
+ *   the <code>PersistenceCapable</code> instance.</td>
+ *   <td>This is dangerous in that information (possibly confidential) 
+ *   normally unavailable would be accessible to malicious code.</td>
+ * </tr>
+ *
+ * <tr>
+ *   <td><code>getMetadata</code></td>
+ *   <td>This allows getting metadata for any <code>PersistenceCapable</code> 
class that has
+ *   registered with <code>JDOImplHelper</code>.</td>
+ *   <td>This is dangerous in that metadata information (possibly 
confidential) 
+ *   normally unavailable would be accessible to malicious code.</td>
+ * </tr>
+ *
+ * <tr>
+ *   <td><code>manageMetadata</code></td>
+ *   <td>This allows managing metadata for any <code>PersistenceCapable</code> 
class that has
+ *   registered with <code>JDOImplHelper</code>.</td>
+ *   <td>This is dangerous in that metadata information (possibly 
confidential) 
+ *   normally unavailable would be manageable (modifiable) by malicious 
code.</td>
+ * </tr>
+ *
+ * <tr>
+ *   <td><code>closePersistenceManagerFactory</code></td>
+ *   <td>This allows closing a <code>PersistenceManagerFactory</code>,
+ *       thereby releasing resources.</td> 
+ *   <td>This is dangerous in that resources bound to the
+ *       <code>PersistenceManagerFactory</code> would be releaseable by
+ *       malicious code.</td>  
+ * </tr>
+ *
+ * </table>
+ *
+ * @see java.security.Permission
+ * @see java.security.BasicPermission
+ * @see javax.jdo.spi.JDOImplHelper
+ * @see javax.jdo.spi.PersistenceCapable
+ * @version 1.0.2
+ */
+public final
+class JDOPermission extends java.security.BasicPermission {
+    
+    /**
+     * Constructs a <code>JDOPermission</code> with the specified name.
+     *
+     * @param name the name of the <code>JDOPermission</code>
+     */
+    public JDOPermission(String name) {
+        super(name);
+    }
+
+    /**
+     * Constructs a <code>JDOPermission</code> with the specified name and 
actions.
+     * The actions should be <code>null</code>; they are ignored. This
+     * constructor exists for use by the <code>Policy</code> object
+     * to instantiate new <code>Permission</code> objects.
+     *
+     * @param name the name of the <code>JDOPermission</code>
+     * @param actions should be <code>null</code>.
+     */
+    public JDOPermission(String name, String actions) {
+        super(name, actions);
+    }
+
+    /** An instance of <code>JDOPermission</code> to be used for
+     * <code>getMetadata</code> permission checking.
+     */
+    public final static JDOPermission GET_METADATA = 
+        new JDOPermission("getMetadata"); // NOI18N
+    
+    /** An instance of <code>JDOPermission</code> to be used for
+     * <code>manageMetadata</code> permission checking.
+     * @since 1.0.2
+     */
+    public final static JDOPermission MANAGE_METADATA = 
+        new JDOPermission("manageMetadata"); // NOI18N
+    
+    /** An instance of <code>JDOPermission</code> to be used for
+     * <code>setStateManager</code> permission checking.
+     */
+    public final static JDOPermission SET_STATE_MANAGER = 
+        new JDOPermission("setStateManager"); // NOI18N
+    
+    /** An instance of <code>JDOPermission</code> to be used for
+     * <code>closePersistenceManagerFactory</code> permission checking.
+     * @since 1.0.1
+     */
+    public final static JDOPermission CLOSE_PERSISTENCE_MANAGER_FACTORY = 
+        new JDOPermission("closePersistenceManagerFactory"); // NOI18N
+    
+}

Added: incubator/jdo/trunk/api20/src/java/javax/jdo/spi/PersistenceCapable.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/PersistenceCapable.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/PersistenceCapable.java 
(added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/PersistenceCapable.java 
Mon Mar 28 10:25:05 2005
@@ -0,0 +1,564 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package javax.jdo.spi;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.JDOHelper; // for javadoc
+
+/**
+ *
+ * @version 2.0
+ */
+
+/**
+ * A class that can be managed by a JDO implementation must implement this 
interface.
+ *
+ * <P>Every class whose instances can be managed by a JDO PersistenceManager 
must
+ * implement the PersistenceCapable interface.
+ *
+ * <P>This interface defines methods that allow the implementation to manage
+ * the instances.  It also defines methods that allow a JDO aware
+ * application to examine the runtime state of instances.  For example,
+ * an application can discover whether the instance is persistent, 
transactional,
+ * dirty, new, or deleted; and to get its associated
+ * PersistenceManager if it has one.
+ *
+ * <P>In the Reference Implementation, the JDO Enhancer modifies the class
+ * to implement PersistenceCapable prior to loading the class into the runtime
+ * environment.  The Reference Enhancer also adds code to implement the
+ * methods defined by PersistenceCapable.
+ *
+ *<P>The extra methods in the PersistenceCapable interface might be generated
+ * by pre-processing a .java file, or might be generated from a tool directly.
+ * The exact technique for generating the extra methods is not specified by
+ * JDO.
+ *
+ * <P>The PersistenceCapable interface is designed to avoid name conflicts
+ * in the scope of user-defined classes.  All of its declared method
+ * names are prefixed with 'jdo'.
+ */
+public interface PersistenceCapable {
+    /** If jdoFlags is set to READ_WRITE_OK, then the fields in the default 
fetch group
+     * can be accessed for read or write without notifying the StateManager.
+     */
+    static final byte READ_WRITE_OK = 0;
+    
+    /** If jdoFlags is set to LOAD_REQUIRED, then the fields in the default 
fetch group
+     * cannot be accessed for read or write without notifying the StateManager.
+     */
+    static final byte LOAD_REQUIRED = 1;
+    
+    /** If jdoFlags is set to READ_OK, then the fields in the default fetch 
group
+     * can be accessed for read without notifying the StateManager.
+     */
+    static final byte READ_OK = -1;
+    
+    /** If jdoFieldFlags for a field includes CHECK_READ, then
+     * the field has been enhanced to call the jdoStateManager on read
+     * if the jdoFlags setting is not READ_OK or READ_WRITE_OK.
+     */
+    static final byte CHECK_READ = 1;
+    
+    /** If jdoFieldFlags for a field includes MEDIATE_READ, then
+     * the field has been enhanced to always call the jdoStateManager
+     * on all reads.
+     */
+    static final byte MEDIATE_READ = 2;
+    
+    /** If jdoFieldFlags for a field includes CHECK_WRITE,
+     * then the field has been enhanced to call the
+     * jdoStateManager on write if the jdoFlags setting is not
+     * READ_WRITE_OK;.
+     */
+    static final byte CHECK_WRITE = 4;
+    
+    /** If jdoFieldFlags for a field includes MEDIATE_WRITE, then
+     * the field has been enhanced to always call the jdoStateManager
+     * on all writes.
+     */
+    static final byte MEDIATE_WRITE = 8;
+    
+    /** If jdoFieldFlags for a field includes SERIALIZABLE,
+     * then the field is not declared as TRANSIENT.
+     */
+    static final byte SERIALIZABLE = 16;
+    
+    /** Return the associated PersistenceManager if there is one.
+     * Transactional and persistent instances return the associated
+     * PersistenceManager.
+     *
+     * <P>Transient non-transactional instances return null.
+     * <P>This method always delegates to the StateManager if it is non-null.
+     * @return the PersistenceManager associated with this instance.
+     */
+    PersistenceManager jdoGetPersistenceManager();
+    
+    /** This method sets the StateManager instance that manages the state
+     * of this instance. This method is normally used by the StateManager
+     * during the process of making an instance persistent, transient,
+     * or transactional.
+     *
+     * The caller of this method must have JDOPermission for the instance,
+     * if the instance is not already owned by a StateManager.
+     * If the parameter is null, and the StateManager approves the change,
+     * then the jdoFlags field will be reset to READ_WRITE_OK.
+     * If the parameter is not null, and the security manager approves
+     * the change, then the jdoFlags field will be reset to LOAD_REQUIRED.
+     * @param sm The StateManager which will own this instance, or null
+     * to reset the instance to transient state
+     * @throws SecurityException if the caller does not have JDOPermission
+     * @see JDOPermission
+     */
+    void jdoReplaceStateManager(StateManager sm)
+    throws SecurityException;
+    
+    /** The owning StateManager uses this method to ask the instance to
+     * provide the value of the single field identified by fieldNumber.
+     * @param fieldNumber the field whose value is to be provided by
+     * a callback to the StateManager's
+     * providedXXXField method
+     */
+    void jdoProvideField(int fieldNumber);
+    
+    /** The owning StateManager uses this method to ask the instance to
+     * provide the values of the multiple fields identified by fieldNumbers.
+     * @param fieldNumbers the fields whose values are to be provided by
+     * multiple callbacks to the StateManager's
+     * providedXXXField method
+     */
+    void jdoProvideFields(int[] fieldNumbers);
+    
+    /** The owning StateManager uses this method to ask the instance to
+     * replace the value of the single field identified by number.
+     * @param fieldNumber the field whose value is to be replaced by
+     * a callback to the StateManager's
+     * replacingXXXField method
+     */
+    void jdoReplaceField(int fieldNumber);
+    
+    /** The owning StateManager uses this method to ask the instance to
+     * replace the values of the multiple fields identified by number.
+     * @param fieldNumbers the fields whose values are to be replaced by
+     * multiple callbacks to the StateManager's
+     * replacingXXXField method
+     */
+    void jdoReplaceFields(int[] fieldNumbers);
+    
+    /** The owning StateManager uses this method to ask the instance to
+     * replace the value of the flags by calling back the StateManager
+     * replacingFlags method.
+     */
+    void jdoReplaceFlags();
+    
+    /** Copy field values from another instance of the same class
+     * to this instance.
+     *<P>This method will throw an exception if the other instance is
+     * not managed by the same StateManager as this instance.
+     * @param other the PC instance from which field values are to be copied
+     * @param fieldNumbers the field numbers to be copied into this instance
+     */
+    void jdoCopyFields(Object other, int[] fieldNumbers);
+    
+    /** Explicitly mark this instance and this field dirty.
+     * Normally, PersistenceCapable classes are able to detect changes made
+     * to their fields.  However, if a reference to an array is given to a
+     * method outside the class, and the array is modified, then the
+     * persistent instance is not aware of the change.  This API allows the
+     * application to notify the instance that a change was made to a field.
+     *
+     *<P>The field name should be the fully qualified name, including package
+     * name and class name of the class declaring the field.  This allows
+     * unambiguous identification of the field to be marked dirty.
+     * If multiple classes declare the same field, and
+     * if the package and class name are not provided by the parameter in
+     * this API, then the field marked
+     * dirty is the field declared by the most derived class.
+     * <P>Transient instances ignore this method.
+     *<P>
+     * @param fieldName the name of the field to be marked dirty.
+     */
+    void jdoMakeDirty(String fieldName);
+    
+    /** Return a copy of the JDO identity associated with this instance.
+     *
+     * <P>Persistent instances of PersistenceCapable classes have a JDO 
identity
+     * managed by the PersistenceManager.  This method returns a copy of the
+     * ObjectId that represents the JDO identity.
+     *
+     * <P>Transient instances return null.
+     *
+     * <P>The ObjectId may be serialized
+     * and later restored, and used with a PersistenceManager from the same JDO
+     * implementation to locate a persistent instance with the same data store
+     * identity.
+     *
+     * <P>If the JDO identity is managed by the application, then the ObjectId 
may
+     * be used with a PersistenceManager from any JDO implementation that 
supports
+     * the PersistenceCapable class.
+     *
+     * <P>If the JDO identity is not managed by the application or the data 
store,
+     * then the ObjectId returned is only valid within the current transaction.
+     * <P>If the JDO identity is being changed in the transaction, this method
+     * returns the object id as of the beginning of the current transaction.
+     *
+     * @see PersistenceManager#getObjectId(Object pc)
+     * @see PersistenceManager#getObjectById(Object oid, boolean validate)
+     * @return a copy of the ObjectId of this instance as of the beginning of 
the transaction.
+     */
+    Object jdoGetObjectId();
+    
+    /** Return a copy of the JDO identity associated with this instance.
+     * This method is the same as jdoGetObjectId if the identity of the
+     * instance has not changed in the current transaction.
+     * <P>If the JDO identity is being changed in the transaction, this method
+     * returns the current object id as modified in the current transaction.
+     *
+     * @see #jdoGetObjectId()
+     * @see PersistenceManager#getObjectId(Object pc)
+     * @see PersistenceManager#getObjectById(Object oid, boolean validate)
+     * @return a copy of the ObjectId of this instance as modified in the 
transaction.
+     */
+    Object jdoGetTransactionalObjectId();
+    
+    /** Return the version of this instance.
+     * @return the version
+     * @since 2.0
+     */
+    Object jdoGetVersion();
+    
+    /** Tests whether this object is dirty.
+     *
+     * Instances that have been modified, deleted, or newly
+     * made persistent in the current transaction return true.
+     *
+     *<P>Transient instances return false.
+     *<P>
+     * @see JDOHelper#isDirty(Object pc)
+     * @see JDOHelper#makeDirty(Object pc, String fieldName)
+     * @see #jdoMakeDirty(String fieldName)
+     * @return true if this instance has been modified in the current 
transaction.
+     */
+    boolean jdoIsDirty();
+    
+    /** Tests whether this object is transactional.
+     *
+     * Instances whose state is associated with the current transaction
+     * return true.
+     *
+     *<P>Transient instances return false.
+     *<P>
+     * @see JDOHelper#isTransactional(Object pc)
+     * @see PersistenceManager#makeTransactional(Object pc)
+     * @return true if this instance is transactional.
+     */
+    boolean jdoIsTransactional();
+    
+    /** Tests whether this object is persistent.
+     * Instances that represent persistent objects in the data store
+     * return true.
+     * @see JDOHelper#isPersistent(Object pc)
+     * @see PersistenceManager#makePersistent(Object pc)
+     * @return true if this instance is persistent.
+     */
+    boolean jdoIsPersistent();
+    
+    /** Tests whether this object has been newly made persistent.
+     *
+     * Instances that have been made persistent in the current transaction
+     * return true.
+     *
+     *<P>Transient instances return false.
+     *<P>
+     * @see JDOHelper#isNew(Object pc)
+     * @see PersistenceManager#makePersistent(Object pc)
+     * @return true if this instance was made persistent
+     * in the current transaction.
+     */
+    boolean jdoIsNew();
+    
+    /** Tests whether this object has been deleted.
+     *
+     * Instances that have been deleted in the current transaction return true.
+     *
+     *<P>Transient instances return false.
+     *<P>
+     * @see JDOHelper#isDeleted(Object pc)
+     * @see PersistenceManager#deletePersistent(Object pc)
+     * @return true if this instance was deleted
+     * in the current transaction.
+     */
+    boolean jdoIsDeleted();
+    
+    /** Tests whether this object has been detached.
+     *
+     * Instances that have been detached return true.
+     *
+     *<P>Transient instances return false.
+     *<P>
+     * @see JDOHelper#isDetached(Object pc)
+     * @return true if this instance is detached.
+     * @since 2.0
+     */
+    boolean jdoIsDetached();
+    
+    /** Return a new instance of this class, with the jdoStateManager set to 
the
+     * parameter, and jdoFlags set to LOAD_REQUIRED.
+     * <P>This method is used as a performance optimization as an alternative 
to
+     * using reflection to construct a new instance.  It is used by the
+     * JDOImplHelper class method newInstance.
+     * @return a new instance of this class.
+     * @see JDOImplHelper#newInstance(Class pcClass, StateManager sm)
+     * @param sm the StateManager that will own the new instance.
+     */
+    PersistenceCapable jdoNewInstance(StateManager sm);
+    
+    /** Return a new instance of this class, with the jdoStateManager set to 
the
+     * parameter, key fields initialized to the values in the oid, and jdoFlags
+     * set to LOAD_REQUIRED.
+     * <P>This method is used as a performance optimization as an alternative 
to
+     * using reflection to construct a new instance of a class that uses
+     * application identity.  It is used by the
+     * JDOImplHelper class method newInstance.
+     * @return a new instance of this class.
+     * @see JDOImplHelper#newInstance(Class pcClass, StateManager sm)
+     * @param sm the StateManager that will own the new instance.
+     * @param oid an instance of the object id class (application identity).
+     */
+    PersistenceCapable jdoNewInstance(StateManager sm, Object oid);
+    
+    /** Create a new instance of the ObjectId class for this 
PersistenceCapable class.
+     * The fields will have their Java default values.
+     * @return the new instance created.
+     */
+    Object jdoNewObjectIdInstance();
+    
+    /** Create a new instance of the class used for JDO identity, using the
+     * key constructor of the object id class. It is intended only for single
+     * field identity. The identity
+     * instance returned has no relationship with the values of the primary key
+     * fields of the persistence-capable instance on which the method is 
called.
+     * If the key is the wrong class for the object id class, null is returned.
+     * @return the new instance created.
+     * @param o the String form of the object identity
+     * @since 2.0
+     */
+    Object jdoNewObjectIdInstance(Object o);
+    
+    /** Copy fields from this PersistenceCapable instance to the Object Id 
instance.
+     * @param oid the ObjectId target of the key fields
+     */
+    void jdoCopyKeyFieldsToObjectId(Object oid);
+    
+    /** Copy fields from an outside source to the key fields in the ObjectId.
+     * This method is generated in the PersistenceCapable class to generate
+     * a call to the field manager for each key field in the ObjectId.  For
+     * example, an ObjectId class that has three key fields (int id,
+     * String name, and Float salary) would have the method generated:
+     * <P>void jdoCopyKeyFieldsToObjectId
+     * <P>        (ObjectIdFieldSupplier fm, Object objectId) {
+     * <P>    EmployeeKey oid = (EmployeeKey)objectId;
+     * <P>    oid.id = fm.fetchIntField (0);
+     * <P>    oid.name = fm.fetchStringField (1);
+     * <P>    oid.salary = fm.fetchObjectField (2);
+     * <P>}
+     * <P>The implementation is responsible for implementing the
+     * ObjectIdFieldSupplier to produce the values for the key fields.
+     * @param oid the ObjectId target of the copy.
+     * @param fm the field supplier that supplies the field values.
+     */
+    void jdoCopyKeyFieldsToObjectId(ObjectIdFieldSupplier fm, Object oid);
+    
+    /** Copy fields to an outside source from the key fields in the ObjectId.
+     * This method is generated in the PersistenceCapable class to generate
+     * a call to the field manager for each key field in the ObjectId.  For
+     * example, an ObjectId class that has three key fields (int id,
+     * String name, and Float salary) would have the method generated:
+     * <P>void copyKeyFieldsFromObjectId
+     * <P>        (ObjectIdFieldConsumer fm, Object objectId) {
+     * <P>     EmployeeKey oid = (EmployeeKey)objectId;
+     * <P>     fm.storeIntField (0, oid.id);
+     * <P>     fm.storeStringField (1, oid.name);
+     * <P>     fm.storeObjectField (2, oid.salary);
+     * <P>}
+     * <P>The implementation is responsible for implementing the
+     * ObjectIdFieldManager to store the values for the key fields.
+     * @param oid the ObjectId source of the copy.
+     * @param fm the field manager that receives the field values.
+     */
+    void jdoCopyKeyFieldsFromObjectId(ObjectIdFieldConsumer fm, Object oid);
+    
+    /** This interface is a convenience interface that allows an instance to
+     * implement both ObjectIdFieldSupplier and ObjectIdFieldConsumer.
+     */
+    static interface ObjectIdFieldManager extends ObjectIdFieldConsumer, 
ObjectIdFieldSupplier {}
+    
+    /** This interface is used to provide fields to the Object id instance.  
It is used
+     * by the method copyKeyFieldsToObjectId.  When the method is called, the
+     * generated code calls the instance of ObjectIdFieldManager for each 
field in
+     * the object id.
+     */
+    static interface ObjectIdFieldSupplier {
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        boolean fetchBooleanField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        char fetchCharField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        byte fetchByteField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        short fetchShortField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        int fetchIntField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        long fetchLongField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        float fetchFloatField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        double fetchDoubleField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        String fetchStringField(int fieldNumber);
+        
+        /** Fetch one field from the field manager.  This field will be stored 
in the
+         * proper field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @return the value of the field to be stored into the ObjectId.
+         */
+        Object fetchObjectField(int fieldNumber);
+    }
+    
+    /** This interface is used to store fields from the Object id instance.  
It is used
+     * by the method copyKeyFieldsFromObjectId.  When the method is called, the
+     * generated code calls the instance of ObjectIdFieldManager for each 
field in
+     * the object id.
+     */
+    static interface ObjectIdFieldConsumer {
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeBooleanField(int fieldNumber, boolean value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeCharField(int fieldNumber, char value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeByteField(int fieldNumber, byte value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeShortField(int fieldNumber, short value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeIntField(int fieldNumber, int value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeLongField(int fieldNumber, long value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeFloatField(int fieldNumber, float value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeDoubleField(int fieldNumber, double value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeStringField(int fieldNumber, String value);
+        
+        /** Store one field into the field manager.  This field was retrieved 
from
+         * the field of the ObjectId.
+         * @param fieldNumber the field number of the key field.
+         * @param value the value of the field from the ObjectId.
+         */
+        void storeObjectField(int fieldNumber, Object value);
+    }
+}

Added: incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassEvent.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassEvent.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassEvent.java 
(added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassEvent.java 
Mon Mar 28 10:25:05 2005
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+/*
+ * RegisterClassEvent.java
+ *
+ */
+
+package javax.jdo.spi;
+
+import java.util.EventObject;
+
+/**
+ * A <code>RegisterClassEvent</code> event gets delivered whenever a 
persistence-capable
+ * class registers itself with the <code>JDOImplHelper</code>.
+ *
+ * @version 1.0
+ */
+public class RegisterClassEvent 
+    extends EventObject
+{
+    /** The class object of the registered persistence-capable class */
+    protected Class pcClass;
+
+    /** The names of managed fields of the persistence-capable class */
+    protected String[] fieldNames;  
+
+    /** The types of managed fields of the persistence-capable class */
+    protected Class[] fieldTypes;
+
+    /** The flags of managed fields of the persistence-capable class */
+    protected byte[] fieldFlags;
+
+    /** */
+    protected Class persistenceCapableSuperclass; 
+
+    /** 
+     * Constructs a new <code>RegisterClassEvent</code>.
+     * @param helper the <code>JDOImplHelper</code> instance
+     * @param registeredClass the persistence-capable class
+     * @param fieldNames the names of the managed fields
+     * @param fieldTypes the types of the managed fields
+     * @param fieldFlags the flags of the managed fields
+     * @param persistenceCapableSuperclass the persistence-capable superclass
+     **/
+    public RegisterClassEvent(JDOImplHelper helper,
+                              Class registeredClass, 
+                              String[] fieldNames, 
+                              Class[] fieldTypes,
+                              byte[] fieldFlags,
+                              Class persistenceCapableSuperclass)
+    {
+        super(helper);
+        this.pcClass = registeredClass;
+        this.fieldNames = fieldNames;
+        this.fieldTypes = fieldTypes;
+        this.fieldFlags = fieldFlags;
+        this.persistenceCapableSuperclass = persistenceCapableSuperclass;
+    }
+
+    /**
+     * Returns the class object of the registered persistence-capable class.
+     * @return the persistence-capable class.
+     */
+    public Class getRegisteredClass()
+    {
+        return pcClass;
+    }
+    
+    /**    
+     * Returns the names of the managed field of the persistence-capable class.
+     * @return the names of the managed fields
+     */
+    public String[] getFieldNames()
+    {
+        return fieldNames;
+    }
+
+    /**
+     * Returns the types of the managed field of the persistence-capable class.
+     * @return the types of the managed fields
+     */
+    public Class[] getFieldTypes()
+    {
+        return fieldTypes;
+    }
+
+    /**
+     * Returns the flags of the managed field of the persistence-capable class.
+     * @return the flags of the managed fields
+     */
+    public byte[] getFieldFlags()
+    {
+        return fieldFlags;
+    }
+
+    /**
+     * Returns the class object of the persistence-capable superclass.
+     * @return the persistence-capable superclass.
+     */
+    public Class getPersistenceCapableSuperclass()
+    {
+        return persistenceCapableSuperclass;
+    }
+    
+}
+
+
+

Added: 
incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassListener.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassListener.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassListener.java 
(added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/RegisterClassListener.java 
Mon Mar 28 10:25:05 2005
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+/*
+ *  RegisterClassListener.java
+ *
+ */
+
+package javax.jdo.spi;
+
+import java.util.EventListener;
+
+/**
+ * A "RegisterClassEvent" event gets fired whenever a persistence-capable 
class 
+ * is loaded and gets registered with the <code>JDOImplHelper</code>. You can 
register a 
+ * <code>RegisterClassListener</code> so as to be notified of any registration 
of a 
+ * persistence-capable class.
+ *
+ * @version 1.0
+ */
+public interface RegisterClassListener 
+    extends EventListener
+{
+    /**
+     * This method gets called when a persistence-capable class is registered.
+     * @param event a <code>RegisterClassEvent</code> instance describing the 
registered 
+     * class plus metadata.
+     */
+    public void registerClass(RegisterClassEvent event);
+}

Added: incubator/jdo/trunk/api20/src/java/javax/jdo/spi/StateInterrogation.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/api20/src/java/javax/jdo/spi/StateInterrogation.java?view=auto&rev=159273
==============================================================================
--- incubator/jdo/trunk/api20/src/java/javax/jdo/spi/StateInterrogation.java 
(added)
+++ incubator/jdo/trunk/api20/src/java/javax/jdo/spi/StateInterrogation.java 
Mon Mar 28 10:25:05 2005
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+/*
+ * StateInterrogation.java
+ *
+ */
+ 
+package javax.jdo.spi;
+
+import javax.jdo.PersistenceManager;
+
+/**
+ * This interface is implemented by a non-binary-compatible JDO implementation
+ * to provide state interrogation for non-enhanced persistent classes.
+ *
+ * An instance that implements this interface is registered with the
+ * [EMAIL PROTECTED] JDOImplHelper}.
+ * @version 2.0
+ * @since 2.0
+ */
+public interface StateInterrogation {
+
+
+    /** Tests whether the parameter instance is persistent.
+     *
+     * Instances that represent persistent objects in the data store 
+     * return <code>true</code>. 
+     *
+     *<P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>false</code>.
+     *<P>
+     * @see PersistenceManager#makePersistent(Object pc)
+     * @see PersistenceCapable#jdoIsPersistent()
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return <code>true</code> if the parameter instance is persistent.
+     */
+       Boolean isPersistent (Object pc);
+
+    /** Tests whether the parameter instance is transactional.
+     *
+     * Instances whose state is associated with the current transaction 
+     * return true. 
+     *
+     *<P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>false</code>.
+     * @see PersistenceCapable#jdoIsTransactional()
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return <code>true</code> if the parameter instance is transactional.
+     */
+       Boolean isTransactional (Object pc);
+    
+    /** Tests whether the parameter instance is dirty.
+     *
+     * Instances that have been modified, deleted, or newly 
+     * made persistent in the current transaction return <code>true</code>.
+     *
+     *<P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>false</code>.
+     *<P>
+     * @see StateManager#makeDirty(PersistenceCapable pc, String fieldName)
+     * @see PersistenceCapable#jdoIsDirty()
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return <code>true</code> if the parameter instance has been modified 
in the current transaction.
+     */
+       Boolean isDirty (Object pc);
+
+    /** Tests whether the parameter instance has been newly made persistent.
+     *
+     * Instances that have been made persistent in the current transaction 
+     * return <code>true</code>.
+     *
+     *<P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>false</code>.
+     *<P>
+     * @see PersistenceManager#makePersistent(Object pc)
+     * @see PersistenceCapable#jdoIsNew()
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return <code>true</code> if the parameter instance was made persistent
+     * in the current transaction.
+     */
+       Boolean isNew (Object pc);
+
+    /** Tests whether the parameter instance has been deleted.
+     *
+     * Instances that have been deleted in the current transaction return 
<code>true</code>.
+     *
+     *<P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>false</code>.
+     *<P>
+     * @see PersistenceManager#deletePersistent(Object pc)
+     * @see PersistenceCapable#jdoIsDeleted()
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return <code>true</code> if the parameter instance was deleted
+     * in the current transaction.
+     */
+       Boolean isDeleted (Object pc);
+        
+    /** Return the associated <code>PersistenceManager</code> if there is one.
+     * Transactional and persistent instances return the associated
+     * <code>PersistenceManager</code>.  
+     *
+     * <P>Transient non-transactional instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>null</code>.
+     * @see PersistenceCapable#jdoGetPersistenceManager()
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return the <code>PersistenceManager</code> associated with the 
parameter instance.
+     */
+       PersistenceManager getPersistenceManager (Object pc);
+    
+    /** Return a copy of the JDO identity associated with the parameter 
instance.
+     *
+     * <P>Persistent instances of <code>PersistenceCapable</code> classes have 
a JDO identity
+     * managed by the <code>PersistenceManager</code>.  This method returns a 
copy of the
+     * ObjectId that represents the JDO identity.  
+     * 
+     * <P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> return 
<code>null</code>.
+     *
+     * <P>The ObjectId may be serialized
+     * and later restored, and used with a <code>PersistenceManager</code> 
from the same JDO
+     * implementation to locate a persistent instance with the same data store
+     * identity.
+     *
+     * <P>If the JDO identity is managed by the application, then the ObjectId 
may
+     * be used with a <code>PersistenceManager</code> from any JDO 
implementation that supports
+     * the <code>PersistenceCapable</code> class.
+     *
+     * <P>If the JDO identity is not managed by the application or the data 
store,
+     * then the ObjectId returned is only valid within the current transaction.
+     *<P>
+     * @see PersistenceManager#getObjectId(Object pc)
+     * @see PersistenceCapable#jdoGetObjectId()
+     * @see PersistenceManager#getObjectById(Object oid, boolean validate)
+     * @param pc the PersistenceCapable instance.
+     * @return a copy of the ObjectId of the parameter instance as of the 
beginning of the transaction.
+     */
+       Object getObjectId (Object pc);
+
+    /** Return a copy of the JDO identity associated with the parameter 
instance.
+     *
+     * @see PersistenceCapable#jdoGetTransactionalObjectId()
+     * @see PersistenceManager#getObjectById(Object oid, boolean validate)
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @return a copy of the ObjectId of the parameter instance as modified in 
this transaction.
+     */
+       Object getTransactionalObjectId (Object pc);
+    
+    /** Explicitly mark the parameter instance and field dirty.
+     * Normally, <code>PersistenceCapable</code> classes are able to detect 
changes made
+     * to their fields.  However, if a reference to an array is given to a
+     * method outside the class, and the array is modified, then the
+     * persistent instance is not aware of the change.  This API allows the
+     * application to notify the instance that a change was made to a field.
+     *
+     * <P>Transient instances and instances of classes 
+     * that do not implement <code>PersistenceCapable</code> ignore this 
method.
+     * @see PersistenceCapable#jdoMakeDirty(String fieldName)
+     * @param pc the <code>PersistenceCapable</code> instance.
+     * @param fieldName the name of the field to be marked dirty.
+     */
+       boolean makeDirty (Object pc, String fieldName);
+
+}
\ No newline at end of file


Reply via email to