db-jdo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m..@apache.org
Subject svn commit: r171352 [4/11] - in /incubator/jdo/trunk/runtime20: ./ src/ src/conf/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/jdo/ src/java/org/apache/jdo/ejb/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/model/ src/java/org/apache/jdo/impl/model/java/ src/java/org/apache/jdo/impl/model/java/runtime/ src/java/org/apache/jdo/impl/model/jdo/ src/java/org/apache/jdo/impl/model/jdo/xml/ src/java/org/apache/jdo/impl/pm/ src/java/org/apache/jdo/impl/sco/ src/java/org/apache/jdo/impl/state/ src/java/org/apache/jdo/pm/ src/java/org/apache/jdo/query/ src/java/org/apache/jdo/sco/ src/java/org/apache/jdo/state/ src/java/org/apache/jdo/store/
Date Sun, 22 May 2005 18:01:48 GMT
Added: incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/PersistenceManagerWrapper.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/PersistenceManagerWrapper.java?rev=171352&view=auto
==============================================================================
--- incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/PersistenceManagerWrapper.java (added)
+++ incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/PersistenceManagerWrapper.java Sun May 22 11:01:45 2005
@@ -0,0 +1,764 @@
+/*
+ * 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.
+ */
+
+/*
+ * PersistenceManagerWrapper.java
+ *
+ * Created on January 16, 2001
+ */
+ 
+package org.apache.jdo.impl.pm;
+
+import java.util.*;
+
+import javax.jdo.*;
+
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+
+/**  
+ * This is a thin wrapper for the current implemetation of javax.jdo.PersistenceManager
+ * interface. Delegates most of method execution to the corresponding instance of 
+ * the PersistenceManagerImpl. Becomes invalid after PersistenceManager is closed.
+ *  
+ * @author Marina Vatkina 
+ */  
+public class PersistenceManagerWrapper implements PersistenceManager {
+
+    // Previous  PersistenceManagerWrapper
+    private PersistenceManagerWrapper prev = null;
+
+    // Actual  PersistenceManager
+    private PersistenceManagerImpl pm = null;
+
+    // Boolean flag that allows to use this wrapper
+    private boolean isValid = false;
+
+    /**
+     * I18N message handler
+     */
+     private final static I18NHelper msg = 
+        I18NHelper.getInstance("org.apache.jdo.impl.pm.Bundle"); // NOI18N
+
+    // Constructed by  PersistenceManagerFactoryImpl
+    PersistenceManagerWrapper(PersistenceManagerImpl pm) {
+        this.pm = pm;
+        prev = (PersistenceManagerWrapper)pm.getCurrentWrapper();
+        pm.pushCurrentWrapper(this);
+        isValid = true;
+    }
+
+    /** 
+     * @see javax.jdo.PersistenceManager#isClosed()
+     */
+    public boolean isClosed() {
+        if (isValid) {
+            return pm.isClosed();
+        } else {
+            return true;
+        }
+    }
+
+
+   /**
+    * @see javax.jdo.PersistenceManager#close()
+    */
+    public void close() {
+        if (isValid) { 
+            pm.popCurrentWrapper(prev);
+            isValid = false;
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+
+     /** 
+      * @see javax.jdo.PersistenceManager#currentTransaction()
+      */
+    public Transaction currentTransaction() {
+        if (isValid) { 
+            return pm.currentTransaction();
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+
+    /**
+     * @see javax.jdo.PersistenceManager#setIgnoreCache(boolean flag)
+     */
+    public void setIgnoreCache(boolean flag) {
+        if (isValid) {
+            pm.setIgnoreCache(flag);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#getIgnoreCache()
+     */
+    public boolean getIgnoreCache() {
+        if (isValid) {
+            return pm.getIgnoreCache();
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#getMultithreaded()
+     */
+    public boolean getMultithreaded() {
+        if (isValid) {
+            return pm.getMultithreaded();
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#setMultithreaded(boolean flag)
+     */
+    public void setMultithreaded(boolean flag) {
+        if (isValid) {
+            pm.setMultithreaded(flag);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#evict(Object pc)
+     */
+    public  void evict(Object pc) {
+        if (isValid) {
+            pm.evict(pc);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#evictAll(Object[] pcs)
+     */
+    public  void evictAll(Object[] pcs) {
+        if (isValid) {
+            pm.evictAll(pcs);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#evictAll(Collection pcs)
+     */
+    public  void evictAll(Collection pcs) {
+        if (isValid) {
+            pm.evictAll(pcs);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#evictAll()
+     */
+    public  void evictAll() {
+        if (isValid) {
+            pm.evictAll();
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#refresh(Object pc)
+     */
+    public  void refresh(Object pc) {
+        if (isValid) {
+            pm.refresh(pc);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#refreshAll(Object[] pcs)
+     */
+    public  void refreshAll(Object[] pcs) {
+        if (isValid) {
+            pm.refreshAll(pcs);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#refreshAll(Collection pcs)
+     */
+    public  void refreshAll(Collection pcs) {
+        if (isValid) {
+            pm.refreshAll(pcs);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /**
+     * @see javax.jdo.PersistenceManager#refreshAll()
+     */
+    public  void refreshAll() {
+        if (isValid) {
+            pm.refreshAll();
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        }
+    }
+
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery()
+     */
+    public Query newQuery(){
+        if (isValid) { 
+            return pm.newQuery();
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Object compiled)
+     */
+    public Query newQuery(Object compiled){
+        if (isValid) { 
+            return pm.newQuery(compiled);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Class cls)
+     */
+    public Query newQuery(Class cls){
+        if (isValid) { 
+            return pm.newQuery(cls);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Extent cln)
+     */
+    public Query newQuery(Extent cln){
+        if (isValid) { 
+            return pm.newQuery(cln);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Class cls,Collection cln)
+     */
+    public Query newQuery(Class cls,Collection cln){
+        if (isValid) { 
+            return pm.newQuery(cls, cln);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(String language, Object query)
+     */
+    public Query newQuery (String language, Object query){
+        if (isValid) { 
+            return pm.newQuery(language, query);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Class cls, String filter)
+     */
+    public Query newQuery (Class cls, String filter){
+        if (isValid) { 
+            return pm.newQuery(cls, filter);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Class cls, Collection cln, String filter)
+     */
+    public Query newQuery (Class cls, Collection cln, String filter){
+        if (isValid) { 
+            return pm.newQuery(cls, cln, filter);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newQuery(Extent cln, String filter)
+     */
+    public Query newQuery (Extent cln, String filter){
+        if (isValid) { 
+            return pm.newQuery(cln, filter);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#getExtent(Class persistenceCapableClass,
+     * boolean subclasses)
+     */
+    public Extent getExtent(Class persistenceCapableClass,boolean subclasses){
+        if (isValid) { 
+            return pm.getExtent(persistenceCapableClass, subclasses);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+
+    /** 
+     * @see javax.jdo.PersistenceManager#getObjectById(Object oid, boolean validate)
+     */
+    public Object getObjectById(Object oid, boolean validate){
+        if (isValid) { 
+            return pm.getObjectById(oid, validate);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#getObjectId(Object pc)
+     */
+    public Object getObjectId(Object pc){
+        if (isValid) { 
+            return pm.getObjectId(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#getTransactionalObjectId (Object pc)
+     */
+    public Object getTransactionalObjectId (Object pc) {
+        if (isValid) { 
+            return pm.getTransactionalObjectId(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#newObjectIdInstance (Class pcClass, String str)
+     */
+    public Object newObjectIdInstance (Class pcClass, String str) {
+        if (isValid) { 
+            return pm.newObjectIdInstance (pcClass, str);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makePersistent(Object pc)
+     */
+    public void makePersistent(Object pc){
+        if (isValid) { 
+            pm.makePersistent(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makePersistentAll(Object[] pc)
+     */
+    public void makePersistentAll(Object[] pcs){
+        if (isValid) { 
+            pm.makePersistentAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makePersistentAll(Collection pcs)
+     */
+    public void makePersistentAll (Collection pcs){
+        if (isValid) { 
+            pm.makePersistentAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#deletePersistent(Object pc)
+     */
+    public void deletePersistent(Object pc){
+        if (isValid) { 
+            pm.deletePersistent(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#deletePersistentAll(Object[] pc)
+     */
+    public void deletePersistentAll (Object[] pcs){
+        if (isValid) { 
+            pm.deletePersistentAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#deletePersistentAll(Collection pc)
+     */
+    public void deletePersistentAll (Collection pcs){
+        if (isValid) { 
+            pm.deletePersistentAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeTransient(Object pc)
+     */
+    public void makeTransient(Object pc){
+        if (isValid) { 
+            pm.makeTransient(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeTransientAll(Object[] pc)
+     */
+    public void makeTransientAll(Object[] pcs){
+        if (isValid) { 
+            pm.makeTransientAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeTransientAll(Collection pcs)
+     */
+    public void makeTransientAll (Collection pcs){
+        if (isValid) { 
+            pm.makeTransientAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeTransactional(Object pc)
+     */
+    public void makeTransactional(Object pc){
+        if (isValid) { 
+            pm.makeTransactional(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeTransactionalAll(Object[] pc)
+     */
+    public void makeTransactionalAll(Object[] pcs){
+        if (isValid) { 
+            pm.makeTransactionalAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeTransactionalAll(Collection pcs)
+     */
+    public void makeTransactionalAll (Collection pcs){
+        if (isValid) { 
+            pm.makeTransactionalAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /*
+     * @see javax.jdo.PersistenceManager#makeNontransactional(Object pc)
+     */
+    public void makeNontransactional(Object pc){
+        if (isValid) { 
+            pm.makeNontransactional(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeNontransactionalAll(Object[] pc)
+     */
+    public void makeNontransactionalAll(Object[] pcs){
+        if (isValid) { 
+            pm.makeNontransactionalAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#makeNontransactionalAll(Collection pcs)
+     */
+    public void makeNontransactionalAll (Collection pcs){
+        if (isValid) { 
+            pm.makeNontransactionalAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** Retrieve an instance from the store.  This is only a hint to
+     * the PersistenceManager that the application intends to use the
+     * instance, and its field values should be retrieved.
+     * <P>The PersistenceManager might use policy information about the
+     * class to retrieve associated instances.
+     */
+    public void retrieve(Object pc) {
+        if (isValid) { 
+            pm.retrieve(pc);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+    
+    /** Retrieve field values of instances from the store.  This tells
+     * the <code>PersistenceManager</code> that the application intends to use the
+     * instances, and all field values must be retrieved.
+     * <P>The <code>PersistenceManager</code> might use policy information about the
+     * class to retrieve associated instances.
+     * @param pcs the instances
+     */
+    public void retrieveAll(Object[] pcs) {
+        if (isValid) { 
+            pm.retrieveAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+    
+    /** Retrieve field values of instances from the store.  This tells
+     * the <code>PersistenceManager</code> that the application intends to use the
+     * instances, and their field values should be retrieved.  The fields
+     * in the default fetch group must be retrieved, and the implementation
+     * might retrieve more fields than the default fetch group.
+     * <P>The <code>PersistenceManager</code> might use policy information about the
+     * class to retrieve associated instances.
+     * @param pcs the instances
+     * @param DFGOnly whether to retrieve only the default fetch group fields
+     * @since 1.0.1
+     */
+    public void retrieveAll (Object[] pcs, boolean DFGOnly) {
+        if (isValid) { 
+            pm.retrieveAll(pcs, DFGOnly);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+           
+    /** Retrieve field values of instances from the store.  This tells
+     * the <code>PersistenceManager</code> that the application intends to use the
+     * instances, and all field values must be retrieved.
+     * <P>The <code>PersistenceManager</code> might use policy information about the
+     * class to retrieve associated instances.
+     * @param pcs the instances
+     */
+    public void retrieveAll(Collection pcs) {
+        if (isValid) { 
+            pm.retrieveAll(pcs);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+
+    /** Retrieve field values of instances from the store.  This tells
+     * the <code>PersistenceManager</code> that the application intends to use the
+     * instances, and their field values should be retrieved.  The fields
+     * in the default fetch group must be retrieved, and the implementation
+     * might retrieve more fields than the default fetch group.
+     * <P>The <code>PersistenceManager</code> might use policy information about the
+     * class to retrieve associated instances.
+     * @param pcs the instances
+     * @param DFGOnly whether to retrieve only the default fetch group fields
+     * @since 1.0.1
+     */
+    public void retrieveAll (Collection pcs, boolean DFGOnly) {
+        if (isValid) {
+            pm.retrieveAll(pcs, DFGOnly);
+        } else {
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+            
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#getPersistenceManagerFactory()
+     */
+    public PersistenceManagerFactory getPersistenceManagerFactory(){
+        if (isValid) { 
+            return pm.getPersistenceManagerFactory();
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+   }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#setUserObject(Object o)
+     */
+    public void setUserObject(Object o){
+        if (isValid) { 
+            pm.setUserObject(o);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#getUserObject()
+     */
+    public Object getUserObject(){
+        if (isValid) { 
+            return pm.getUserObject();
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+    
+    /** 
+     * @see javax.jdo.PersistenceManager#getObjectIdClass(Class cls)
+     */
+    public Class getObjectIdClass(Class cls){
+        if (isValid) { 
+            return pm.getObjectIdClass(cls);
+        } else { 
+            throw new JDOFatalUserException(msg.msg(
+                "EXC_PersistenceManagerClosed"));// NOI18N
+        } 
+    }
+
+    /**
+     * Returns PersistenceManagerInternal associated with this wrapper.
+     * This method should be accessed by the PersistenceManagerInternal
+     * only.
+     * @return PersistenceManagerInternal.
+     */
+    protected PersistenceManagerInternal getPersistenceManager() {
+        return (PersistenceManagerInternal)pm;
+    }
+
+    /** 
+     * Returns a hash code value for this PersistenceManagerWrapper.
+     * @return  a hash code value for this PersistenceManagerWrapper.
+     */
+    public int hashCode() {
+        return pm.hashCode();
+    }
+
+    /**  
+     * Indicates whether some other object is "equal to" this one.
+     * @param   obj   the reference object with which to compare.
+     * @return  <code>true</code> if this object is the same as the obj
+     *          argument; <code>false</code> otherwise.
+     */  
+    public boolean equals(Object obj) {
+        if (obj instanceof PersistenceManagerWrapper) {
+            return (((PersistenceManagerWrapper)obj).pm == this.pm);
+
+        } else if (obj instanceof PersistenceManagerImpl) {
+            return (((PersistenceManagerImpl)obj) == this.pm);
+        }
+        return false;
+    }
+}

Added: incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionImpl.java?rev=171352&view=auto
==============================================================================
--- incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionImpl.java (added)
+++ incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionImpl.java Sun May 22 11:01:45 2005
@@ -0,0 +1,1160 @@
+/*
+ * 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.
+ */
+
+/*
+ * TransactionImpl.java
+ *
+ * Create on December 1, 2000
+ */
+
+package org.apache.jdo.impl.pm;
+
+import java.util.*;
+import javax.transaction.*;
+
+import javax.jdo.*;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.ejb.EJBImplHelper;
+import org.apache.jdo.store.Connector;
+import org.apache.jdo.store.StoreManager;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+ *
+ * The Transaction interface allows operations to be performed against
+ * the transaction in the target Transaction object. A Transaction 
+ * object is created corresponding to each PersistentManagerImpl creation.
+ * The Transaction object can be used for synchronization registration, 
+ * transaction completion and status query operations.
+ *
+ * This implementation is StoreManager independent.
+ *
+ * @author Marina Vatkina
+ */
+class TransactionImpl implements javax.jdo.Transaction {
+
+    /**
+     * Transaction status (from javax.transaction.Status).
+     */
+    private int            status;
+
+    /**
+     * The commit process has already begun (even though the status is still
+     * STATUS_ACTIVE).  This is the first thing set during commit or rollback.
+     */
+    private boolean        startedCommit;
+
+    /**
+     * Registered Synchronization object.
+     */
+    private Object    synchronization;
+
+    /**
+     * Synchronisation object associated with this transaction instance
+     */
+    private Object txSync = null;
+    
+    /**
+     * PersistenceManagerFactory associated with this transaction 
+     */
+    private PersistenceManagerFactoryImpl pmFactory = null;
+    
+    /**
+     * PersistenceManager associated with this transaction (1-1)
+     */
+    private PersistenceManagerImpl    persistenceManager     = null;
+
+    /**
+     * Connector associated with this transaction 
+     */
+    private Connector    connector     = null;
+
+    /**
+     * javax.transaction.Transaction instance associated with the current
+     * thread or null if there is none.
+     */
+    private javax.transaction.Transaction jta = null;
+
+    /**
+     * Flag that indicates how to handle objects after commit.
+     * If true, at commit instances retain their values and the instances
+     */
+    private boolean retainValues = true;
+
+    /**
+     * Flag that indicates how to handle objects after rollback.
+     * If true, at rollback instances have their values restored.
+     */
+    private boolean restoreValues = true;
+
+    /**
+     * Flag that indicates type of the transaction.
+     * Optimistic transactions do not hold data store locks until commit time.
+     */
+    private boolean optimistic = true;
+
+    /**
+     * Flag that indicates if queries and navigation are allowed
+     * without an active transaction
+     */
+    private boolean nontransactionalRead = true;    
+
+    /**
+     * Flag that indicates if write access is allowed
+     * without an active transaction
+     */
+    private boolean nontransactionalWrite = true;
+
+    /** values for the datasource user and user password to access
+     * security connections
+     */
+    private String         username     = null;
+    private String         password     = null;
+
+    /**
+     * Possible values of txType
+     */
+    protected static final int NON_MGD = 0;
+    protected static final int CMT = 1;
+    protected static final int BMT_UT = 2;
+    protected static final int BMT_JDO = 3;
+
+    /**
+     * Flag to indicate usage mode (non-managed versus managed, and so on).
+     */
+    private int txType = -1;
+
+    /**
+     * Logger instance
+     */
+    private static final Log logger = LogFactory.getFactory().getInstance(
+        "org.apache.jdo.impl.pm"); // NOI18N
+
+    /**
+     * I18N message handler
+     */
+     private final static I18NHelper msg = 
+        I18NHelper.getInstance("org.apache.jdo.impl.pm.Bundle"); // NOI18N
+    
+    /**
+     * Constructors new instance of TransactionImpl for the corresponding
+     * PersistenceManagerImpl. Username and password are provided for future
+     * validation and Connector request.
+     *
+     * @param pm calling instance of PersistenceManagerImpl
+     * @param pmf PersistenceManagerFactoryImpl associated with the instance of
+     * PersistenceManagerImpl
+     * @param username user name for Connector request
+     * @param password user password for Connector request
+     */
+    TransactionImpl(PersistenceManagerImpl pm, PersistenceManagerFactoryImpl pmf,
+        String username, String password) {
+
+        this.status = Status.STATUS_NO_TRANSACTION;
+        this.startedCommit = false;
+        this.persistenceManager = pm;
+
+        pmFactory = pmf;
+        optimistic = pmFactory.getOptimistic();
+        retainValues = pmFactory.getRetainValues();
+        restoreValues = pmFactory.getRestoreValues();
+        nontransactionalRead = pmFactory.getNontransactionalRead();
+        nontransactionalWrite = pmFactory.getNontransactionalWrite();
+
+        this.username = username;
+        this.password = password;
+
+    }
+
+    //
+    // ----- Methods from javax.jdo.Transaction interface ------
+    //
+
+    /**
+     * Returns PersistenceManager associated with this transaction
+     * @see javax.jdo.Transaction#getPersistenceManager()
+     */
+    public javax.jdo.PersistenceManager getPersistenceManager() {
+        persistenceManager.assertIsOpen();
+        return (javax.jdo.PersistenceManager) persistenceManager.getCurrentWrapper();
+    }
+
+    /**
+     * @see javax.jdo.Transaction#isActive()
+     */
+    public boolean isActive() {
+        persistenceManager.assertIsOpen();
+        return !isTerminated();
+    }
+
+    /**
+     * @see javax.jdo.Transaction#setRetainValues(boolean flag)
+     */
+    public void setRetainValues(boolean flag) {
+        persistenceManager.assertIsOpen();
+
+        // Cannot change flag value when transaction commit is in progress.
+        if (startedCommit)
+            throw new JDOUserException(msg.msg(
+                "EXC_CannotSetFlag")); // NOI18N
+
+        this.retainValues = flag;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#getRetainValues()
+     */
+    public boolean getRetainValues() {
+        persistenceManager.assertIsOpen();
+        return retainValues;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#setRestoreValues(boolean flag)
+     */
+    public void setRestoreValues(boolean flag) {
+        persistenceManager.assertIsOpen();
+        // Cannot change flag if transaction is active.
+        if (isActive()) {
+            throw new JDOUserException(msg.msg(
+                "EXC_CannotSetFlagIfActive")); // NOI18N
+        }
+        this.restoreValues = flag;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#getRestoreValues()
+     */
+    public boolean getRestoreValues() {
+        persistenceManager.assertIsOpen();
+        return restoreValues;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#setNontransactionalRead(boolean flag)
+     */
+    public synchronized void setNontransactionalRead (boolean flag) {
+        persistenceManager.assertIsOpen();
+
+        // Cannot change flag value when transaction commit is in progress.
+        if (startedCommit)
+            throw new JDOUserException(msg.msg(
+                "EXC_CannotSetFlag")); // NOI18N
+
+        this.nontransactionalRead = flag;
+
+    }
+
+    /**
+     * @see javax.jdo.Transaction#getNontransactionalRead()
+     */
+    public boolean getNontransactionalRead() {
+        persistenceManager.assertIsOpen();
+        return nontransactionalRead;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#setNontransactionalWrite(boolean flag)
+     */
+    public synchronized void setNontransactionalWrite (boolean flag) {
+        persistenceManager.assertIsOpen();
+
+        // Cannot change flag value when transaction commit is in progress.
+        if (startedCommit)
+            throw new JDOUserException(msg.msg(
+                "EXC_CannotSetFlag")); // NOI18N
+
+        this.nontransactionalWrite = flag;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#getNontransactionalWrite()
+     */
+    public boolean getNontransactionalWrite() {
+        persistenceManager.assertIsOpen();
+        return nontransactionalWrite;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#setOptimistic(boolean flag)
+     */
+    public synchronized void setOptimistic(boolean flag) {
+        persistenceManager.assertIsOpen();
+
+        if (isTerminated()) {
+            this.optimistic = flag;
+        } else {
+            // Cannot change flag value inside an active transaction.
+            throw new JDOUserException(msg.msg(
+                "EXC_CannotChangeType")); // NOI18N
+        }
+
+        // Notify PM about Tx type change
+        persistenceManager.notifyOptimistic(flag);
+    }
+
+    /**
+     * @see javax.jdo.Transaction#getOptimistic()
+     */
+    public boolean getOptimistic() {
+        persistenceManager.assertIsOpen();
+        return optimistic;
+    }
+
+    /**
+     * @see javax.jdo.Transaction#setSynchronization(Synchronization sync)
+     */
+    public void setSynchronization(Synchronization sync) {
+        persistenceManager.assertIsOpen();
+        if (sync == synchronization) {
+            return; // the same Synchronization.
+
+        } else if (sync != null && synchronization != null) {
+            throw new JDOUserException(msg.msg(
+                "EXC_SynchronizationNotNull")); // NOI18N
+        }
+
+        this.registerSynchronization(sync);
+    }
+
+    /**
+     * @see javax.jdo.Transaction#getRetainValues()
+     */
+    public Synchronization getSynchronization() {
+        persistenceManager.assertIsOpen();
+        return (Synchronization)synchronization;
+    }
+
+    public void assertReadAllowed() {
+        if ((!isActive()) && (!getNontransactionalRead())) {
+            throw new JDOUserException(msg.msg(
+                "EXC_NontransactionalRead"));// NOI18N
+        }
+    }
+    
+    /**
+     * Begin a transaction.
+     * @see javax.jdo.Transaction#begin()
+     */
+    public void begin() {
+        // Check and set status...
+        beginInternal();
+
+       // BMT with JDO Transaction
+       if (EJBImplHelper.isManaged()) {
+           txType = BMT_JDO;
+           try {
+                EJBImplHelper.getUserTransaction().begin();
+                jta = EJBImplHelper.getTransaction();
+                if (txSync == null)
+                    txSync = new TransactionSynchronization(this);
+
+                jta.registerSynchronization((Synchronization)txSync);
+                pmFactory.registerPersistenceManager(persistenceManager, jta);
+
+            } catch (JDOException e) {
+                throw e;     // re-throw it.
+            } catch (Exception e) {
+                throw new JDOFatalInternalException(
+                    "EXC_ErrorRegister", e); // NOI18N
+            }
+        } else {
+            // Mark as non-managed transaction.
+            txType = NON_MGD;
+        }
+        
+    }
+
+    /**
+     * Commit the transaction represented by this Transaction object
+     * @see javax.jdo.Transaction#commit()
+     */
+    public void commit() {
+        persistenceManager.assertIsOpen();
+
+        if (txType == CMT || txType == BMT_UT) {
+            // Error - should not be called
+            throw new JDOUserException(msg.msg(
+                 "EXC_WrongMgdOperation", "commit")); //NOI18N
+        } else if (txType == BMT_JDO) {
+            // Send request to the container:
+            try {
+                EJBImplHelper.getUserTransaction().commit();
+                return;
+            } catch (Exception e) { 
+                throw new JDOException("", e); // NOI18N
+            }
+        }
+ 
+        // Proceede with non-managed environment call.
+        synchronized (this) {
+            //
+            // Disallow parallel transaction completion calls:
+            //
+            if (startedCommit) {
+                throw new JDOUserException(msg.msg(
+                    "EXC_TransactionCommitting")); // NOI18N
+            }
+        
+            // This flag prevents user from making any changes to the transaction object.
+            this.startedCommit = true;
+        }
+
+        if (debugging())
+            this.traceCall("commit"); // NOI18N
+
+        try {
+            this.prepareFlush(true); // do actual beforeComplition.
+            this.commitPrepare(); // check internal status.
+            this.commitComplete(); // commitConnector and set status to success.
+
+        } catch (Throwable e) {
+            try {
+                this.internalRollback();
+            } catch (Exception re) {
+                // Do not rethrow the rollback exception - just log it.
+                if (debugging())
+                    logger.debug("Exception during rollback after failed commit: " + re);
+            }
+
+            if (e instanceof JDOException) {
+                throw (JDOException)e;
+            }
+            throw new JDOException("", e); // NOI18N
+        } finally {
+            this.internalAfterCompletion(); // do afterCompletion and cleanup.
+        }
+    }
+
+    /**
+     * Rollback the transaction represented by this transaction object.
+     * @see javax.jdo.Transaction#rollback()
+     */
+    public void rollback() {
+        persistenceManager.assertIsOpen();
+        if (txType == CMT || txType == BMT_UT) {
+            // Error - should not be called
+            throw new JDOUserException(msg.msg(
+                 "EXC_WrongMgdOperation", "rollback")); //NOI18N
+        }
+
+        if (debugging())
+            this.traceCall("rollback"); // NOI18N
+
+        synchronized (this) {
+            //
+            // Disallow parallel transaction completion calls:
+            //
+            if (startedCommit) {
+                throw new JDOUserException(msg.msg(
+                    "EXC_TransactionCommitting")); // NOI18N
+
+            } else if ((this.status != Status.STATUS_ACTIVE) &&    
+                (this.status != Status.STATUS_MARKED_ROLLBACK)) {
+
+                throw new JDOUserException(msg.msg(
+                    "EXC_TransactionNotActive")); // NOI18N
+            }
+        
+            // This flag prevents user from making any changes to the transaction object.
+            this.startedCommit = true;
+        }
+
+        try {
+            this.internalRollback();
+
+            if (txType == BMT_JDO) {
+                // Send request to the container:
+                EJBImplHelper.getUserTransaction().rollback();
+            }
+        } catch (JDOException e) { 
+            throw e;
+
+        } catch (Exception e) { 
+            throw new JDOException("", e); // NOI18N
+
+        } finally {
+            if (txType == NON_MGD) {
+                // afterCompletion and cleanup in case of the managed env. had been
+                // done already.
+                this.internalAfterCompletion(); 
+            }
+        }
+    }
+
+    //
+    // ----- Other public methods ------
+    //
+
+    /**
+     * Modify the transaction object such that the only possible outcome of
+     * the transaction is to roll back.
+     */
+    public void setRollbackOnly() {
+        if (debugging())
+            this.traceCall("setRollbackOnly"); // NOI18N
+
+        if ((this.status == Status.STATUS_ROLLING_BACK)
+                ||    (this.status == Status.STATUS_ROLLEDBACK)
+                ||     (this.status == Status.STATUS_MARKED_ROLLBACK)) {
+            //
+            // Already rolled back, rollback in progress or already marked.
+            //
+            return;
+        }
+
+        if (txType == NON_MGD) {
+            this.setStatus(Status.STATUS_MARKED_ROLLBACK);
+        } else {
+            try {
+                jta.setRollbackOnly();
+            } catch (Exception e) { 
+                throw new JDOException("", e); // NOI18N
+            }
+        }
+
+    }
+
+    /**
+     * Obtain the status of this transaction object.
+     * 
+     * @return The transaction status. 
+     */
+    public int getStatus() {
+        synchronized (this) {
+            return this.status;
+        }
+    }
+
+    /**
+     * Translates a javax.transaction.Status value into a string. 
+     *
+     * @param   status   Status object to translate.
+     * @return  Printable String for a Status object.
+     */
+    public static String statusString(int status) {
+        switch (status) {
+            case Status.STATUS_ACTIVE:            return "STATUS_ACTIVE"; // NOI18N
+            case Status.STATUS_MARKED_ROLLBACK:    return "STATUS_MARKED_ROLLBACK"; // NOI18N
+            case Status.STATUS_PREPARED:        return "STATUS_PREPARED"; // NOI18N
+            case Status.STATUS_COMMITTED:        return "STATUS_COMMITTED"; // NOI18N
+            case Status.STATUS_ROLLEDBACK:        return "STATUS_ROLLEDBACK"; // NOI18N
+            case Status.STATUS_UNKNOWN:            return "STATUS_UNKNOWN"; // NOI18N
+            case Status.STATUS_NO_TRANSACTION:    return "STATUS_NO_TRANSACTION"; // NOI18N
+            case Status.STATUS_PREPARING:        return "STATUS_PREPARING"; // NOI18N
+            case Status.STATUS_COMMITTING:        return "STATUS_COMMITTING"; // NOI18N
+            case Status.STATUS_ROLLING_BACK:    return "STATUS_ROLLING_BACK"; // NOI18N
+            default:                            break;
+        }
+        return "STATUS_Invalid[" + status + "]"; // NOI18N
+    }
+
+    /**
+     * Returns a string representation of this transaction object.
+     *
+     * @return  String describing contents of this Transaction object.
+     */
+    public String toString() {
+        StringBuffer    s = new StringBuffer();
+
+        s.append("  Transaction: \n   status        = " + this.statusString(this.status)+ "\n"); // NOI18N
+        if (this.startedCommit)
+            s.append("   startedCommit = true\n"); // NOI18N
+
+        if (synchronization != null) 
+            s.append("   sync          = " + synchronization.getClass().getName() + "\n"); // NOI18N
+        
+        return s.toString();
+    }
+
+    //
+    // ----- protected methods ------
+    //
+
+    /**
+     * Returns current transaction type
+     * @return current transaction type as int.
+     */
+    protected int getTransactionType() {
+        return txType;
+    }
+
+    /** Verify that username and password are equal to ones stored before
+     *
+     * @param username as String
+     * @param password as String
+     * @return true if they are equal
+     */
+    protected boolean verify(String username, String password) {
+        if ((this.username != null && !this.username.equals(username)) ||
+            (this.username == null && username != null) ||
+            (this.password != null && !this.password.equals(password)) ||
+            (this.password  == null && password != null)) {
+            return false;
+        }
+        return true;
+    }
+
+    /** Returns true if commit has started
+     * @return true if commit has started
+     */
+    protected boolean startedCommit() {
+        return startedCommit;
+    } 
+
+    /**
+     * Flush changes to the datastore. Performed in an active datastore 
+     * transaction only.
+     */
+    protected void internalFlush() {
+        if (this.status != Status.STATUS_ACTIVE) { 
+            throw new JDOUserException(msg.msg(
+                "EXC_TransactionNotActive")); // NOI18N
+        }
+
+        this.prepareFlush(false); // prepare the flush.
+    }
+
+    /**
+     * Begin a transaction in a managed environment. Called by 
+     * PersistenceManagerFactoryImpl when JTA Transaction associated with 
+     * the current thread is active.
+     *
+     * @param t JTA Transaction associated with the current thread
+     */
+    protected void begin(javax.transaction.Transaction t) {
+
+        beginInternal();
+        try {
+            jta = t;
+            if (txSync == null) 
+                txSync = new TransactionSynchronization(this); 
+
+            jta.registerSynchronization((Synchronization)txSync);
+        } catch (Exception e) {
+            throw new JDOFatalInternalException(msg.msg(
+                "EXC_ErrorRegister")); //NOI18N
+        }
+
+        // Set transaction type.
+        txType = CMT;
+    }
+
+    /** 
+     * Called in the managed environment only for transaction completion
+     * by TransactionSynchronization#beforeCompletion().
+     */
+    protected void beforeCompletion() {
+    
+        if (txType == NON_MGD) {
+            // Error - should not be called
+            throw new JDOUserException(msg.msg(
+                "EXC_WrongNonMgdOperation", "beforeCompletion")); //NOI18N
+        }      
+ 
+        Object o = null;
+ 
+        // This flag prevents user from making any changes to the transaction object.
+        this.startedCommit = true;
+
+        try {
+            o = EJBImplHelper.enlistBeforeCompletion(
+                new Object[] {this, persistenceManager, jta});
+            this.prepareFlush(true); // do actual beforeComplition.
+            this.commitPrepare(); // check internal status.
+
+            // do not do commitConnector() in the managed environment:
+            this.setStatus(Status.STATUS_COMMITTED); 
+
+        } finally {
+            EJBImplHelper.delistBeforeCompletion(o);
+        }
+    }
+ 
+    /** 
+     * Called in the managed environment only for transaction completion
+     * by TransactionSynchronization#afterCompletion(int st).
+     */
+    protected void afterCompletion(int st) {
+        if (txType == NON_MGD) {
+            // Error - should not be called
+            throw new JDOUserException(msg.msg(
+                "EXC_WrongNonMgdOperation", "afterCompletion")); //NOI18N
+        }
+        st = EJBImplHelper.translateStatus(st); // translate Status
+
+        if (debugging()) {
+            this.traceCall("afterCompletion", st); // NOI18N
+        }
+
+        if (st == Status.STATUS_ROLLEDBACK) {
+            this.internalRollback();
+        } 
+
+        if (st != this.status) {
+            // Status mismatch - should not happen.
+            throw new JDOUserException(msg.msg(
+                 "EXC_InvalidStatus", // NOI18N
+                 "afterCompletion", this.statusString(this.status),  // NOI18N
+                 this.statusString(st)));
+         }
+
+         this.internalAfterCompletion();
+
+    }
+
+    //
+    // ----- private methods ------
+    //
+
+    /** 
+     * Status change and validation. Called by begin methods.
+     */
+    private void beginInternal() {
+        persistenceManager.assertIsOpen();
+
+        if (debugging())
+            this.traceCall("begin");  // NOI18N
+
+        if (this.isActive()) {
+            throw new JDOUserException(msg.msg(
+                "EXC_ErrorBegin"));  // NOI18N
+
+        }
+        this.setStatus(Status.STATUS_ACTIVE);
+
+            connector = this.getConnector();
+            connector.begin(optimistic);
+    }
+
+    /**
+     * Lower-level before-commit method - phase 1.
+     *
+     * This is called to flush changes to the store.
+     * State transition:
+     *        STATUS_ACTIVE        starting state
+     *        internalBeforeCompletion()    called while still active
+     *        STATUS_PREPARING    no longer active, about to "really" commit
+     *
+     * @param _commit true if called during the commit processing
+     * For exceptions see commit() method.
+     */
+    private void prepareFlush(boolean _commit) {
+        boolean        rollbackOnly = false; //marked for rollback
+
+        if (debugging())
+            this.traceCall("prepareFlush"); // NOI18N
+        //
+        // Prepare connection
+        //
+        connector = this.getConnector();
+
+        //
+        // Validate transaction state before we commit
+        //
+
+        if ((this.status == Status.STATUS_ROLLING_BACK)
+            ||    (this.status == Status.STATUS_ROLLEDBACK)) {
+            throw new JDOUserException(msg.msg(
+                "EXC_TransactionRolledback")); // NOI18N
+        }
+
+        if (connector.getRollbackOnly() ||
+            this.status == Status.STATUS_MARKED_ROLLBACK) {
+            rollbackOnly = true;
+
+        } else if (this.status != Status.STATUS_ACTIVE) {
+            throw new JDOUserException(msg.msg(
+                "EXC_TransactionNotActive")); // NOI18N
+        }
+
+        //
+        // User notifications done outside of lock - check for concurrent
+        // rollback or setRollbackOnly during notification.
+        //
+        if (!rollbackOnly) {
+            this.flushInstances(_commit);
+
+            if (this.status == Status.STATUS_ACTIVE) {        // All ok
+                if (this.startedCommit) { // inside commit - change status.
+                    this.setStatus(Status.STATUS_PREPARING);
+                }
+
+            } else if (this.status == Status.STATUS_MARKED_ROLLBACK) {
+                // This could happen only if this.setRollbackOnly() was called 
+                // during flushInstances() without throwing an
+                // exception.
+                rollbackOnly = true;
+
+            } else {    // concurrently rolled back - should not happen.
+                throw new JDOUserException(msg.msg(
+                    "EXC_TransactionRolledback")); // NOI18N
+            }
+        }
+        if (rollbackOnly) {
+            // Do not rollback here, but throw the exception and the rollback
+            // will happen in the 'catch' block. Usually happens if the
+            // connector was set rollback-only before the commit.
+            this.setRollbackOnly();
+
+            throw new JDOUserException(msg.msg(
+               "EXC_MarkedRolledback")); // NOI18N
+
+        }
+    }
+
+    /**
+     * Lower-level prepare-commit method - phase 2. 
+     *
+     * This is called when flush is finished but before connectorCommit.
+     * Will allow to support 2-phase commit.
+     * State transition:
+     *        STATUS_PREPARING    starting state
+     *        STATUS_PREPARED
+     *
+     * For exceptions see commit() method.
+     */
+    private void commitPrepare() {
+        if (debugging())
+            this.traceCall("commitPrepare"); // NOI18N
+        //
+        // Once we've reached the Status.STATUS_PREPARING state we do not need
+        // to check for concurrent state changes.  All user-level methods
+        // (rollback, setRollbackOnly, register, enlist, etc) are no longer
+        // allowed.
+        //
+
+        //
+        // Validate initial state
+        //
+        if (this.status != Status.STATUS_PREPARING) {
+            throw new JDOUserException(msg.msg(
+               "EXC_WrongStateCommit")); // NOI18N
+        }
+
+        this.setStatus(Status.STATUS_PREPARED);
+    }
+
+    /**
+     * Lower-level commit method - phase 3. Called only in a non-
+     * managed environment.
+     *
+     * State transition:
+     *        STATUS_PREPARED        starting state
+     *        STATUS_COMMITTING    starting to do final phase
+     *        commitConnector()        commit the flush.
+     *        STATUS_COMMITTED
+     *
+     */
+    private void commitComplete() {
+        if (debugging())
+            this.traceCall("commitComplete"); // NOI18N
+
+        //
+        // Validate initial state
+        //
+        if (this.status == Status.STATUS_ROLLING_BACK) {
+            this.setStatus(Status.STATUS_ROLLING_BACK); 
+
+            this.setStatus(Status.STATUS_ROLLEDBACK);
+
+        } else if (this.status == Status.STATUS_PREPARED) {
+            this.setStatus(Status.STATUS_COMMITTING);
+            this.commitConnector();
+            this.setStatus(Status.STATUS_COMMITTED);
+
+        } else {
+            throw new JDOUserException(msg.msg(
+                "EXC_WrongStateCommit")); // NOI18N
+        }
+    }
+
+    /**
+     * Lower-level internal rollback method. This is to avoid concurrent rollbacks.
+     *
+     */
+    private void internalRollback() {
+        if (debugging())
+            this.traceCall("internalRollback"); // NOI18N
+
+        this.setStatus(Status.STATUS_ROLLING_BACK);
+        try {
+            if (txType == NON_MGD) {
+                this.rollbackConnector();
+            }
+        } catch (JDOException ex) {
+            throw ex;
+
+        } catch (Exception ex) {
+            throw new JDOException("", ex);
+
+        } finally {
+            this.setStatus(Status.STATUS_ROLLEDBACK);
+        }
+    }
+
+    /**
+     *
+     * Force rollback.  This is called when something goes wrong during
+     * a late state check (i.e. some failure occurred during the prepare
+     * stage).  Unless we're not already rolling back (or rolled back) this
+     * will blindly change the state of the transaction and complete the
+     * latter stage of rollback.
+     *
+     * @return the final status of the transaction.
+     *
+     * See internalRollback() for exceptions
+     */
+    private int forceRollback() {
+        if (debugging())
+            this.traceCall("forceRollback"); // NOI18N
+
+        if ((this.status == Status.STATUS_ROLLING_BACK)        // Already
+            ||    (this.status == Status.STATUS_ROLLEDBACK)        // Done
+            ||    (this.status == Status.STATUS_COMMITTED)        // Too late
+            ||    (this.status == Status.STATUS_NO_TRANSACTION)    // Never was
+           ) {
+            return this.status;
+        }
+        try {
+            this.internalRollback();
+        } finally {
+            this.internalAfterCompletion();
+        }
+
+        return this.status;
+    }
+
+    /** 
+     * Register a Synchronization object for this transaction object.
+     * The transction manager invokes the beforeCompletion method prior to
+     * starting the transaction commit process. After the transaction is
+     * completed (or aborted), the transaction manager invokes the
+     * afterCompletion method.
+     *
+     * @param sync The Synchronization object for the transaction.
+     */
+    private void registerSynchronization(Synchronization sync) {
+        if (debugging())
+            this.traceCall("registerSynchronization"); // NOI18N
+        synchronized (this) {
+            //
+            // Disallow registration of new synchronization objects during
+            // beforeCompletion or afterCompletion processing.  Synchronizations
+            // are themselves involved in the process.
+            //
+            if (this.startedCommit) {
+                throw new JDOUserException(msg.msg(
+                    "EXC_TransactionCommitting")); // NOI18N
+            }
+
+            synchronization = sync;
+
+            if (debugging()) {
+                this.traceCall("registerSynchronization"); // NOI18N
+            }
+        }
+    }
+
+
+    /**
+     * Confirm that transaction is terminated.
+     * 
+     * @return True if transaction is completed or not started.
+     */
+    private boolean isTerminated() {
+        synchronized (this) {
+            return (    (this.status == Status.STATUS_COMMITTED)
+                    ||    (this.status == Status.STATUS_ROLLEDBACK)
+                    ||    (this.status == Status.STATUS_NO_TRANSACTION));
+        }
+    }
+
+    /**
+     * Flush dirty persistent instances to the datastore.
+     * If called during the commit processing, notifies registered 
+     * Synchronization interfaces with beforeCompletion().
+     */
+    private void flushInstances(boolean commit) {
+        if (commit) {
+            this.getConnector().beforeCompletion();
+            if (synchronization != null) {
+                ((Synchronization)synchronization).beforeCompletion();
+            }
+        }
+
+        persistenceManager.flushInstances();
+    }
+
+    /**
+     * Notify Connector, PersistenceManager, and registered Synchronization 
+     * instances about afterCompletion(). 
+     * All status changes occured before executing this method.
+     */
+    private void internalAfterCompletion() {
+        //
+        // This will execute w/o an active transaction context
+        //
+        persistenceManager.afterCompletion(status);
+
+        try {
+            if (synchronization != null)
+                ((Synchronization)synchronization).afterCompletion(status);
+        } catch (Exception ex) {
+            //
+            // Exceptions ignored
+            //
+        }
+        
+        this.finish();
+    }
+
+    /**
+     * Set status under lock (may be a nested lock which is ok)
+     */
+    private void setStatus(int status) {
+        if (debugging()) {
+            logger.debug(
+                "Tran[" + this.toString() + "].setStatus: " + // NOI18N
+                this.statusString(this.status) + " => " + // NOI18N
+                this.statusString(status));
+        }
+
+        synchronized(this) {
+            this.status = status;
+            persistenceManager.notifyStatusChange(!isTerminated());
+        }
+    }
+
+    /**
+     * Finish this transaction
+     */
+    private void finish() {
+        if (debugging())
+            this.traceCall("finish"); // NOI18N
+
+        //
+        // Do not clear:
+        //
+        //    .status            -- users can still check status
+        //
+        this.startedCommit = false;
+
+        if (txType == CMT || txType == BMT_UT) {
+            persistenceManager.forceClose();
+        } else if (txType == BMT_JDO) {
+            persistenceManager.deregisterJTA();
+        }
+
+        jta = null;
+        txType = NON_MGD;       // Restore the flag
+    }
+
+    //
+    // ----- Connector utilities -----
+    //
+
+    /**
+     * Get a connector 
+     */
+    private Connector getConnector() {
+        StoreManager srm = persistenceManager.getStoreManager();
+
+        if (username != null) {
+            return srm.getConnector(username, password);
+        }
+        return srm.getConnector();
+    }
+
+    /**
+     * Close a connector does flush of the changes and close
+     */
+    private void flushConnector() {
+            connector = this.getConnector();
+            connector.flush();
+    }
+
+    /** 
+     * Rollback a connector does rollback and close
+     */
+    private void rollbackConnector() {
+        connector = this.getConnector();
+        connector.rollback();
+    }
+
+    /** 
+     * Commit a connector does flush if necessary, commit and close
+     */
+    private void commitConnector() {
+        connector = this.getConnector();
+        connector.commit();
+    }
+ 
+    //
+    // ----- Debugging utilities -----
+    //
+
+    /**
+     * Verifies if debugging is enabled.
+     * @return true if debugging is enabled.
+     */
+    private boolean debugging() {
+        return logger.isDebugEnabled();
+    }
+
+
+    /**
+     * Trace method call.
+     */
+    private void traceCall(String call) {
+        logger.debug(
+            "Tran[" + this.toString() + "]." + call + // NOI18N
+            ": status = " + this.statusString(this.status) + // NOI18N
+            ", txType: " + txTypeString()); // NOI18N
+    }
+
+    /**
+     * Trace method call with a provided status.
+     */
+    private void traceCall(String call, int st) {
+        logger.debug(
+            "Tran[" + this.toString() + "]." + call + // NOI18N
+            ": status = " + this.statusString(st) + // NOI18N
+            ", txType: " + txTypeString()); // NOI18N
+    }
+
+    /**
+     * Translates a txType value into a string.
+     * 
+     * @return  Printable String for a txType value
+     */
+    private String txTypeString() {
+        switch (txType) {
+            case NON_MGD:                   return "NON_MGD"; // NOI18N
+            case CMT:                       return "CMT"; // NOI18N
+            case BMT_UT:                    return "BMT_UT"; // NOI18N
+            case BMT_JDO:                   return "BMT_JDO"; // NOI18N
+            default:                        break;
+        }
+        return "UNKNOWN"; // NOI18N
+    }      
+}
+
+
+

Added: incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionSynchronization.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionSynchronization.java?rev=171352&view=auto
==============================================================================
--- incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionSynchronization.java (added)
+++ incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/TransactionSynchronization.java Sun May 22 11:01:45 2005
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+/*
+ * TransactionSynchronization.java
+ *
+ * Create on August 1, 20001
+ */
+
+package org.apache.jdo.impl.pm;
+
+import javax.transaction.*;
+
+
+/**   
+ * This is a Synchronization instance associated with the corresponding instance
+ * of the TransactionImpl. Is used for synchronization callbacks in a managed
+ * environment. This is a separate object to avoid a requirement for a non-managed
+ * application have JTA classes in its classpath.
+ *  
+ * @author Marina Vatkina  
+ */ 
+class TransactionSynchronization implements Synchronization {
+    /** Reference to TransactionImpl instance associated
+     * with this instance of TransactionSynchronization
+     */
+    private TransactionImpl tx = null;
+
+    TransactionSynchronization(TransactionImpl newtx) {
+        tx = newtx;
+    }
+
+    /**
+     * @see javax.transaction.Synchronization#beforeCompletion()
+     */
+    public void beforeCompletion() {
+        tx.beforeCompletion();
+    }
+
+    /** 
+     * @see javax.transaction.Synchronization#afterCompletion(int status) 
+     */ 
+    public void afterCompletion(int status) { 
+        tx.afterCompletion(status); 
+    } 
+
+}

Added: incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/package.html
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/package.html?rev=171352&view=auto
==============================================================================
--- incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/package.html (added)
+++ incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/pm/package.html Sun May 22 11:01:45 2005
@@ -0,0 +1,28 @@
+<!--
+ 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.
+-->
+
+<html>
+<head>
+<title>Package org.apache.jdo.impl.pm</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
+</head>
+
+<body bgcolor="#FFFFFF">
+<p>This package contains classes that are for use across all kinds of implementations 
+  of the JDO Reference Implementation. The classes herein by and large implement 
+  the interfaces defined in <a href="../package-summary.html">org.apache.jdo.pm</a>. 
+</body>
+</html>

Added: incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/ArrayList.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/ArrayList.java?rev=171352&view=auto
==============================================================================
--- incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/ArrayList.java (added)
+++ incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/ArrayList.java Sun May 22 11:01:45 2005
@@ -0,0 +1,605 @@
+/*
+ * 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.
+ */
+
+/*
+ * sco.ArrayList.java
+ */
+
+package org.apache.jdo.impl.sco;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.jdo.JDOUserException;
+import javax.jdo.JDOFatalInternalException;
+
+import org.apache.jdo.sco.SCO;
+import org.apache.jdo.sco.SCOCollection;
+import org.apache.jdo.state.StateManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+ * A mutable 2nd class object that represents ArrayList.
+ * @author Marina Vatkina
+ * @version 1.0.1
+ * @see java.util.ArrayList
+ */
+public class ArrayList extends java.util.ArrayList
+    implements SCOCollection {
+
+    private transient StateManagerInternal owner;
+
+    private transient int fieldNumber = -1;
+
+    private transient     Class elementType;
+ 
+    private transient boolean allowNulls;
+
+    private transient java.util.Vector added = new java.util.Vector();
+
+    private transient java.util.Vector removed = new java.util.Vector();
+
+    /**
+     * I18N message handler
+     */  
+    private final static I18NHelper msg = I18NHelper.getInstance(
+        "org.apache.jdo.impl.sco.Bundle"); // NOI18N
+
+    private final static String _ArrayList = "ArrayList"; // NOI18N
+
+    /**
+     * Constructs an empty <code>ArrayList</code> object.
+     *
+     * @param elementType     the element types allowed 
+     * @param allowNulls     true if nulls are allowed 
+     */
+    public ArrayList(Class elementType, boolean allowNulls) {
+        super();
+
+        this.elementType = elementType;
+        this.allowNulls = allowNulls;
+    }
+
+    /**
+     * Constructs an empty <code>ArrayList</code> object that the specified 
+     * initial capacity.
+     *
+     * @param elementType     the element types allowed 
+     * @param allowNulls     true if nulls are allowed 
+     * @param initialCapacity   the initial capacity of the list.
+     * @exception IllegalArgumentException if the specified initial capacity
+     *               is negative
+     */
+    public ArrayList(Class elementType, boolean allowNulls,
+                     int initialCapacity) {
+        super(initialCapacity);
+        this.elementType = elementType;
+        this.allowNulls = allowNulls;
+    }
+
+    /** ------------------Public Methods----------------*/
+
+    /**
+     * Replaces the element at the specified position in this ArrayList with the
+     * specified element.
+     *   
+     * @param index index of element to replace.
+     * @param element element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @exception IndexOutOfBoundsException index out of range
+     *            (index &lt; 0 || index &gt;= size()).
+     * @exception IllegalArgumentException fromIndex &gt; toIndex.
+     * @see java.util.ArrayList 
+     */  
+    public Object set(int index, Object element) {
+        SCOHelper.debug(_ArrayList, "set"); // NOI18N
+
+        if (element == null) {
+            SCOHelper.assertNullsAllowed(element, allowNulls);
+            // It is actualy remove
+            return this.remove(index);
+        }
+        SCOHelper.assertElementType(element, elementType);
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        Object o = super.set(index, element);
+        if (added.remove(o) == false) {
+            removed.add(o);
+        }
+        if (removed.remove(element) == false) {
+            added.add(element);
+        }
+        // Apply updates
+        this.trackUpdates(true);
+        
+        return o;
+    } 
+
+
+    /**
+     * Appends the specified element to the end of this ArrayList.
+     *   
+     * @param o element to be appended to this ArrayList.
+     * @return true (as per the general contract of Collection.add).
+     * @see java.util.ArrayList
+     */  
+    public boolean add(Object o) {
+        SCOHelper.debug(_ArrayList, "add"); // NOI18N
+
+        SCOHelper.assertNullsAllowed(o, allowNulls);
+        SCOHelper.assertElementType(o, elementType);
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        if (removed.remove(o) == false) {
+            added.add(o);
+        }
+
+        boolean modified = super.add(o);
+
+        // Apply updates
+        this.trackUpdates(modified);
+
+        return modified;
+    }    
+
+    /**
+     * Removes the first occurrence of the specified element in this ArrayList
+     * If the ArrayList does not contain the element, it is unchanged.  
+     *
+     * @param o element to be removed from this ArrayList, if present.
+     * @return true if the ArrayList contained the specified element.
+     * @see java.util.ArrayList 
+     */   
+    public boolean remove(Object o) {
+        SCOHelper.debug(_ArrayList, "remove"); // NOI18N
+
+        // Because java.util.AbstractCollection.remove(Object)
+        // delegates remove() to remove(int) which is not supported,
+        // we cannot rely on jdk. We need to process remove here. 
+
+        // Mark the field as dirty
+        this.makeDirty();
+
+        int i = super.indexOf(o);
+        Object obj = null;
+        if (i > -1) {
+            obj = super.remove(i);
+            if (added.remove(obj) == false) {
+                removed.add(obj);
+            }
+            // Apply updates
+            this.trackUpdates(true);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this ArrayList.
+     *   
+     * @param index index at which the specified element is to be inserted.
+     * @param element element to be inserted.
+     * @exception IndexOutOfBoundsException index is out of range
+     *            (index &lt; 0 || index &gt; size()).
+     * @see java.util.ArrayList
+     */  
+    public void add(int index, Object element) {
+        SCOHelper.debug(_ArrayList, "add by index"); // NOI18N
+
+        SCOHelper.assertNullsAllowed(element, allowNulls);
+        SCOHelper.assertElementType(element, elementType);
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        super.add(index, element);
+        if (removed.remove(element) == false) {
+            added.add(element);
+        }
+        // Apply updates
+        this.trackUpdates(true);
+    
+    }
+
+    /**
+     * Removes the element at the specified position in this ArrayList.
+     * shifts any subsequent elements to the left (subtracts one from their
+     * indices).  Returns the element that was removed from the ArrayList.
+     *   
+     * @param index the index of the element to removed.
+     * @exception IndexOutOfBoundsException index out of range (index
+     *            &lt; 0 || index &gt;= size()).
+     * @see java.util.ArrayList 
+     */   
+    public Object remove(int index) {
+        SCOHelper.debug(_ArrayList, "remove by index"); // NOI18N
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        Object obj = super.remove(index);
+        if (added.remove(obj) == false) {
+            removed.add(obj);
+        }
+        // Apply updates
+        this.trackUpdates(true);
+
+        return obj;
+    } 
+
+    /**
+     * Removes all of the elements from this ArrayList.  The ArrayList will
+     * be empty after this call returns (unless it throws an exception).
+     *   
+     * @see java.util.ArrayList
+     */ 
+    public void clear() {
+        SCOHelper.debug(_ArrayList, "clear"); // NOI18N
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        for (Iterator iter = super.iterator(); iter.hasNext();) {
+            Object o = iter.next();
+            if (added.remove(o) == false) {
+                removed.add(o);
+            }
+        }
+        added.clear();
+        super.clear();
+
+        // Apply updates
+        this.trackUpdates(true);
+    }
+
+    /**
+     * Appends all of the elements in the specified Collection to the end of
+     * this ArrayList, in the order that they are returned by the specified
+     * Collection's Iterator.  
+     *   
+     * @param c elements to be inserted into this ArrayList.
+     * @exception IndexOutOfBoundsException index out of range (index
+     *            &lt; 0 || index &gt; size()).
+     * @see java.util.ArrayList
+     */  
+    public boolean addAll(Collection c) {
+        SCOHelper.debug(_ArrayList, "addAll"); // NOI18N
+
+        // iterate the collection and make a list of wrong elements.
+        Throwable[] err = new Throwable[c.size()];
+        int l = 0;
+
+        Iterator i = c.iterator();
+        while (i.hasNext()) {
+            Object o = i.next();
+            try {
+                SCOHelper.assertNullsAllowed(o, allowNulls);
+                SCOHelper.assertElementType(o, elementType);
+            } catch (Throwable e) {
+                err[l++] = e;
+            }
+        }
+        SCOHelper.validateResult(l, err);
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        removed.removeAll(c);
+        added.addAll(c);
+
+        boolean modified = super.addAll(c);
+
+        // Apply updates
+        this.trackUpdates(modified);
+
+        return modified;
+    }
+
+    /**
+     * Removes from this ArrayList all of its elements that are contained in the
+     * specified Collection.
+     *
+     * @return true if this ArrayList changed as a result of the call.
+     * @see java.util.ArrayList 
+     */   
+    public boolean removeAll(Collection c) {
+        SCOHelper.debug(_ArrayList, "removeAll"); // NOI18N
+
+        boolean modified = false;
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        Iterator e = c.iterator();
+        while (e.hasNext()) {
+            Object o = e.next();
+            if(super.contains(o)) {
+                removeInternal(o);
+                if (added.remove(o) == false) {
+                    removed.add(o);
+                }
+                modified = true;
+            }
+        }
+
+        // Apply updates
+        this.trackUpdates(modified);
+
+        return modified;
+    } 
+
+    /**
+     * Inserts all of the elements in in the specified Collection into this
+     * ArrayList at the specified position.  Shifts the element currently at
+     * that position (if any) and any subsequent elements to the right
+     * (increases their indices).  The new elements will appear in the ArrayList
+     * in the order that they are returned by the specified Collection's
+     * iterator.
+     *   
+     * @param index index at which to insert first element
+     *              from the specified collection.
+     * @param c elements to be inserted into this ArrayList.
+     * @exception IndexOutOfBoundsException index out of range (index
+     *            &lt; 0 || index &gt; size()).
+     * @see java.util.ArrayList  
+     */   
+    public boolean addAll(int index, Collection c) {
+        SCOHelper.debug(_ArrayList, "addAll from index"); // NOI18N
+
+        // iterate the collection and make a list of wrong elements.
+        Throwable[] err = new Throwable[c.size()];
+        int l = 0;
+
+        Iterator i = c.iterator();
+        while (i.hasNext()) {
+            Object o = i.next();
+            try {
+                SCOHelper.assertNullsAllowed(o, allowNulls);
+                SCOHelper.assertElementType(o, elementType);
+            } catch (Throwable e) {
+                err[l++] = e;
+            }
+        }
+        SCOHelper.validateResult(l, err);
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        removed.removeAll(c); 
+        added.addAll(c); 
+
+        boolean modified = super.addAll(index, c);
+
+        // Apply updates
+        this.trackUpdates(modified);
+
+        return modified;
+    }    
+
+    /**
+     * Retains only the elements in this ArrayList that are contained in the
+     * specified Collection.  
+     *   
+     * @return true if this ArrayList changed as a result of the call.
+     * @see java.util.ArrayList   
+     */    
+    public boolean retainAll(Collection c) {
+        SCOHelper.debug(_ArrayList, "retainAll"); // NOI18N
+
+        boolean modified = false;
+        java.util.ArrayList v = new java.util.ArrayList();
+
+        // Mark the field as dirty
+        this.makeDirty();
+        
+        for (Iterator iter = super.iterator(); iter.hasNext();) { 
+            Object o = iter.next(); 
+            if (!c.contains(o))  {   
+                v.add(o);
+                if (added.remove(o) == false) {
+                    removed.add(o);  
+                }
+                modified = true;
+            } 
+        } 
+
+        // Now remove the rest (stored in "v")
+        for (Iterator iter = v.iterator(); iter.hasNext();) {
+            removeInternal(iter.next());
+        }
+
+        // Apply updates
+        this.trackUpdates(modified);
+
+        return modified;
+    }
+
+    /**
+     * Creates and returns a copy of this object.
+     *
+     * <P>Mutable Second Class Objects are required to provide a public
+     * clone method in order to allow for copying PersistenceCapable
+     * objects. In contrast to Object.clone(), this method must not throw a
+     * CloneNotSupportedException.
+     */
+    public Object clone() {
+        SCOHelper.debug(_ArrayList, "clone"); // NOI18N
+
+        Object obj = super.clone();
+        if (obj instanceof SCO)
+            ((SCO)obj).unsetOwner(owner, fieldNumber);
+
+        return obj;
+    }
+
+    /**
+     * @see SCOCollection#reset()
+     */  
+    public void reset() {
+        added.clear();
+        removed.clear();
+    }
+
+    /**
+     * @see SCOCollection#addInternal(Object o)
+     */
+    public void addInternal(Object o) {
+        super.add(o);
+    }
+
+ 
+    /** 
+     * @see SCOCollection#addAllInternal(Collection c)
+     */ 
+    public void addAllInternal(Collection c) { 
+        super.addAll(c); 
+    } 
+ 
+    /**
+     * @see SCOCollection#getAdded()
+     */ 
+    public Collection getAdded() {
+        return (Collection)added;
+    }    
+
+    /** 
+     * @see SCOCollection#getRemoved()
+     */ 
+    public Collection getRemoved() { 
+        return (Collection)removed; 
+    }     
+
+
+    /** 
+     * @see SCOCollection#clearInternal()
+     */   
+    public void clearInternal() {    
+        super.clear(); 
+        this.reset(); 
+    }  
+
+    /** 
+     * @see SCOCollection#removeInternal(Object o)
+     */   
+    public void removeInternal(Object o) {    
+        int i = super.indexOf(o);
+        super.remove(i); 
+    }  
+
+    /**
+     * @see SCO#unsetOwner(Object owner, int fieldNumber)
+     */
+    public void unsetOwner(Object owner, int fieldNumber) {
+        // Unset only if owner and fieldNumber match.
+        if (this.owner == owner && this.fieldNumber == fieldNumber) {
+            this.owner = null;
+            this.fieldNumber = -1;
+        }
+    }
+
+    /**
+     * Marks object dirty
+     */
+    private void makeDirty() {
+        if (owner != null) {
+            owner.makeDirty(fieldNumber); 
+        }
+    }
+
+    /**
+     * Apply changes 
+     * @param modified true if content of this list has been changed.
+     */
+    private void trackUpdates(boolean modified) {
+        if (modified && owner != null) {
+            owner.trackUpdates(fieldNumber, this);
+        }
+    }
+
+    /**
+     * @see SCO#setOwner (Object owner, int fieldNumber)
+     */
+    public void setOwner (Object owner, int fieldNumber) {
+        // Set only if it was not set before.
+        if (this.owner == null && owner instanceof StateManagerInternal) {
+            this.owner = (StateManagerInternal)owner;
+            this.fieldNumber = fieldNumber;
+        }
+    }
+    
+    /**
+     * @see SCO#getOwner ()
+     */  
+    public Object getOwner() {
+        return SCOHelper.getOwner(owner);
+    }
+
+    /**
+     * @see SCO#getFieldName()
+     */  
+    public String getFieldName() {
+        return SCOHelper.getFieldName(owner, fieldNumber);
+    }
+
+    /**
+     * @see SCOCollection#getElementType() {
+     */  
+    public Class getElementType() {
+        return elementType;
+    }
+ 
+    /**   
+     * @see SCOCollection#allowNulls() { 
+     */  
+    public boolean allowNulls() {
+        return allowNulls; 
+    } 
+
+    /** Get an iterator over the frozen elements of this collection. 
+     * This class does not require freezing, so this method returns 
+     * a standard iterator.
+     * @since 1.0.1
+     * @return an iterator over the elements.
+     */
+    public Iterator frozenIterator() {
+        return iterator();
+    }
+    
+    /** Set the contents of this Collection from the frozen elements.
+     * This class does not support explicit frozen operations, and this method
+     * always throws an exception.
+     * @since 1.0.1
+     * @param elements not used.
+     */
+    public void setFrozen(Object[] elements) {
+        throw new JDOFatalInternalException(
+            msg.msg("EXC_UnsupportedFreezerOperation")); //NOI18N
+    }
+    
+    /** Get an iterator regardless of whether the collection is frozen. 
+     * This class does not support frozen operations and always returns 
+     * a regular iterator.
+     * @since 1.0.1
+     * @return an iterator over the elements.
+     */
+   public Iterator eitherIterator() {
+        return iterator();
+    }
+    
+}

Added: incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/Bundle.properties
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/Bundle.properties?rev=171352&view=auto
==============================================================================
--- incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/Bundle.properties (added)
+++ incubator/jdo/trunk/runtime20/src/java/org/apache/jdo/impl/sco/Bundle.properties Sun May 22 11:01:45 2005
@@ -0,0 +1,34 @@
+#
+# 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.
+
+# Exceptions for allowNulls validation:
+EXC_ElementNullsNotAllowed=Nulls are not allowed as elements of this Collection.
+EXC_KeyNullsNotAllowed=Nulls are not allowed as keys of this Map.
+EXC_ValueNullsNotAllowed=Nulls are not allowed as values of this Map.
+
+# Exceptions for type validation:
+EXC_ElementClassCastException=New element cannot be cast to {0}.
+EXC_KeyClassCastException=New key cannot be cast to {0}.
+EXC_ValueClassCastException=New value cannot be cast to {0}.
+
+# Exception processing Collection or Map as an argument:
+EXC_FailedToProcessAll=Failed to process all parameters.
+
+# Exceptions for freezing Set and Map
+EXC_OidNotComparable=Object id classes must be comparable. Class {0} does not implement Comparable.
+EXC_ConcurrentModification=This collection was thawed during iteration of the frozen contents.
+EXC_RemoveNotSupported=Optional method remove() is not supported for frozen Iterator.
+EXC_UnsupportedFreezerOperation=This class does not support operations for freezing and thawing.
+



Mime
View raw message