svn commit: r158176 [19/79] - in incubator/jdo/trunk/ri11: ./ 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/enhancer/ src/java/org/apache/jdo/impl/ src/java/org/apache/jdo/impl/enhancer/ src/java/org/apache/jdo/impl/enhancer/classfile/ src/java/org/apache/jdo/impl/enhancer/core/ src/java/org/apache/jdo/impl/enhancer/generator/ src/java/org/apache/jdo/impl/enhancer/meta/ src/java/org/apache/jdo/impl/enhancer/meta/model/ src/java/org/apache/jdo/impl/enhancer/meta/prop/ src/java/org/apache/jdo/impl/enhancer/meta/util/ src/java/org/apache/jdo/impl/enhancer/util/ src/java/org/apache/jdo/impl/fostore/ src/java/org/apache/jdo/impl/jdoql/ src/java/org/apache/jdo/impl/jdoql/jdoqlc/ src/java/org/apache/jdo/impl/jdoql/scope/ src/java/org/apache/jdo/impl/jdoql/tree/ 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/caching/ src/java/org/apache/jdo/impl/model/jdo/util/ 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/jdoql/ src/java/org/apache/jdo/jdoql/tree/ src/java/org/apache/jdo/model/ src/java/org/apache/jdo/model/java/ src/java/org/apache/jdo/model/jdo/ src/java/org/apache/jdo/pm/ src/java/org/apache/jdo/sco/ src/java/org/apache/jdo/state/ src/java/org/apache/jdo/store/ src/java/org/apache/jdo/util/ test/ test/conf/ test/enhancer/ test/enhancer/sempdept/ test/enhancer/sempdept/src/ test/enhancer/sempdept/src/empdept/ test/fsuid2/ test/fsuid2/org/ test/fsuid2/org/apache/ test/fsuid2/org/apache/jdo/ test/fsuid2/org/apache/jdo/pc/ test/java/ test/java/org/ test/java/org/apache/ test/java/org/apache/jdo/ test/java/org/apache/jdo/impl/ test/java/org/apache/jdo/impl/fostore/ test/java/org/apache/jdo/pc/ test/java/org/apache/jdo/pc/appid/ test/java/org/apache/jdo/pc/empdept/ test/java/org/apache/jdo/pc/serializable/ test/java/org/apache/jdo/pc/xempdept/ test/java/org/apache/jdo/test/ test/java/org/apache/jdo/test/query/ test/java/org/apache/jdo/test/util/ test/jdo/ test/jdo/org/ test/jdo/org/apache/ test/jdo/org/apache/jdo/ test/jdo/org/apache/jdo/pc/ test/jdo/org/apache/jdo/pc/appid/ test/jdo/org/apache/jdo/pc/empdept/ test/jdo/org/apache/jdo/pc/serializable/ test/jdo/org/apache/jdo/pc/xempdept/ xdocs/

19 Mar 2005 05:00:13 -0000

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DBInfo.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DBInfo.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DBInfo.java 
(added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DBInfo.java 
Fri Mar 18 17:02:29 2005
@@ -0,0 +1,430 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.util.I18NHelper;
+import org.netbeans.mdr.persistence.Streamable;
+import org.netbeans.mdr.persistence.StorageException;
+import org.netbeans.mdr.persistence.StorageIOException;
+
+/**
+* This class represents the information about the contents of the store
+* itself which must be durable across JVMs.
+* <p>
+* This class is <code>public</code> so that it can be used as a
+* <code>Streamable</code> and stored in the database.
+*
+* @author Dave Bristor
+*/
+// Streamable requires that the class be public.  I think!.
+// This class is server-side only, not needed in client.
+public class DBInfo implements Streamable {
+    // There is only ever one instance of DBInfo in a store.
+    //
+    // When a database is first created, we use the initial values here
+    // specified.  If the database is being brought up from an existing
+    // backing store, then the read method below will provide the correct
+    // values from the store.
+    //
+    private FOStoreDatabase fodb = null;
+
+    /**
+    * This is the OID of the DBInfo.
+    */
+    // See CLID.java: This relies on the facts that (a) CLID's less than 100
+    // are reserved, and (b) the primitive types are final and cannot be
+    // subclassed.
+    private static final OID dbInfoOID = new OID(0);
+    
+    // Next available CLID.
+    private CLID nextCLID = CLID.firstCLID;
+
+    // For the OID of the DBClass corresponding to a given CLID.
+    private static final int DBCLASS_UID = 0;
+
+    // For the OID of the OID's which are of DBClass instances that are
+    // subclasses of an OID's CLID's class.  Got that?  No?  Then see
+    // GetExtentHandler.java.
+    private static final int SUBCLASS_UID = 1;
+
+    // For the OID of the extent of instances of the class indicated by a
+    // CLID.
+    private static final int EXTENT_UID = 2;
+
+    // Reserve the first N UID's in each OID for future use.
+    //
+    // Note to maintainers: Make sure that this is greater than
+    // LAST_RESERVED_UID.
+    private static final int FIRST_CLASS_UID = 10;
+
+    // Indexed by CLID: the value in a given position is the value of the
+    // next available UID for that CLID.  That is, when we need a new
+    // datastore OID for a particular CLID, we use that CLID's id value as an
+    // index into this list, and extract the value there.  We use that value
+    // as the UID part of the OID being created.  And we update the list
+    // element by incrementing the value in the list by 1.
+    private ArrayList nextUIDs = new ArrayList(CLID.firstCLID.getId());
+
+    /** Set of extents that are currently modified and need to be stored when
+     * a transaction commits.
+     */
+    // XXX This relies on the fact that transactions are serialized.  Once
+    // that goes away, index a set of dirtyExtents HashSets by some kind of
+    // transaction id.
+    private HashSet dirtyExtents = new HashSet();
+
+    /** I18N support. */
+    private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+    /** Logger */
+    static final Log logger = LogFactory.getFactory().getInstance(
+        "org.apache.jdo.impl.fostore"); // NOI18N
+    
+    /**
+    * Create a new instance. 
+    * Use this constructor when creating an instance for a brand new
+    * database (as opposed to an existing database, in which we use the
+    * Streamable-required default constructor, below).
+    * @param fodb The FOStoreDatabase instance.
+    * @exception FOStoreFatalInternalException Thrown when there is an attempt
+    * to create a second DBInfo within a store.
+    */
+    DBInfo(FOStoreDatabase fodb) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("DBInfo: new for " + fodb); // NOI18N
+        }
+        this.fodb = fodb;
+        // Initialize nextUIDs for the reserved CLIDs.
+        int size = nextCLID.getId();
+        for (int i = 0; i < size; i++) {
+            // FIRST_CLASS_UID number of uid's are reserved per-CLID.
+            nextUIDs.add(i, new Long(FIRST_CLASS_UID));
+        }
+    }
+
+    void store() throws FOStoreDatabaseException {
+        fodb.put(dbInfoOID, this);
+    }
+
+    static DBInfo get(FOStoreDatabase db) throws FOStoreDatabaseException {
+        DBInfo rc = (DBInfo)db.getIfExists(dbInfoOID);
+        if (null == rc) {
+            rc = new DBInfo(db);
+            rc.fodb = db;
+            rc.store();
+        }
+        rc.fodb = db;
+        if (logger.isDebugEnabled()) {
+            logger.debug("DBInfo.get: " + rc); // NOI18N
+        }
+        return rc;
+    }
+
+    //
+    // The intent of the next 2 methods is to provide an OID which can be
+    // used to store information about the class represented by the CLID.
+    // ActivateClassHandler uses newClassOID to create an OID for storing
+    // class metadata, GetClassHandler uses getDBClassOID to get that OID.
+    //
+    
+    /**
+    * Provide a new OID to represent a class.  Use this when activating a
+    * class.
+    * @return An OID for a class just now known to this store.
+    */
+    OID newClassOID() {
+        // FIRST_CLASS_UID number of uid's are reserved per-CLID.
+        nextUIDs.add(nextCLID.getId(), new Long(FIRST_CLASS_UID));
+
+        OID rc = OID.create(nextCLID, DBCLASS_UID);
+
+        nextCLID = nextCLID.next();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug(
+                "newClassOID: returning; nextCLID now=" + nextCLID); // NOI18N
+        }
+
+        return rc;
+    }
+
+    /**
+    * Provides the OID which represents the given CLID's class.
+    * @param clid The CLID for which the corresponding OID is needed.
+    * @return The OID of the CLID.
+    */
+    static OID getDBClassOID(CLID clid) {
+        return OID.create(clid, DBCLASS_UID);
+    }
+
+    /**
+    * Provides the OID which at which is stored the ArrayList of the CLIDs of
+    * of subclasses of the class corresponding to the CLID.
+    * @param clid The CLID for which the corresponding OID is needed.
+    * @return The OID of the ArrayList of CLIDs of the given CLID's
+    * subclasses.
+    */
+    static OID getSubclassSetOID(CLID clid) {
+        return OID.create(clid, SUBCLASS_UID);
+    }
+
+    /**
+    * Provides the OID which represents extent of instances of objects all of
+    * which have the given CLID.
+    * @param clid CLID of extent to return.
+    * @return OID of the extent of instances of CLID's class.
+    */
+    static OID getExtentOID(CLID clid) {
+        return OID.create(clid, EXTENT_UID);
+    }
+
+    /**
+    * @return Iterator of DBClass objects
+    */
+    Iterator getDBClasses() {
+        if (logger.isDebugEnabled()) {
+            logger.debug(
+                "DBInfo.getDBClasses: first=" + CLID.firstCLID + // NOI18N
+                ", next=" + nextCLID); // NOI18N
+        }
+        return new DBClassIterator(CLID.firstCLID, nextCLID);
+    }
+
+    class DBClassIterator implements Iterator {
+        private int current;
+        private final int finish;
+        
+        DBClassIterator(CLID start, CLID finish) {
+            this.current = start.getId();
+            this.finish = finish.getId();
+        }
+        
+        public boolean hasNext() {
+            return current < finish;
+        }
+        
+        public Object next() {
+            Object rc = null;
+            try {
+                rc = fodb.get(getDBClassOID(CLID.create(current++, false)));
+            } catch (FOStoreDatabaseException ex) {
+            }
+            return rc;
+        }
+
+        public void remove() { }
+    }
+
+    //
+    // Dirty extent handling
+    //
+
+    /**
+     * Marks the given extent as dirty, so that it can later be stored.
+     */
+    boolean makeExtentDirty(DBExtent e) {
+        return dirtyExtents.add(e);
+    }
+
+    /**
+     * Stores all extents that have been marked dirty since the last time this
+     * method was invoked.
+     */
+    void storeDirtyExtents() throws FOStoreDatabaseException {
+        for (Iterator i = dirtyExtents.iterator(); i.hasNext();) {
+            DBExtent dbExtent = (DBExtent)i.next();
+            if (logger.isDebugEnabled()) {
+                logger.debug("FOSCI.commit:" + dbExtent); // NOI18N
+            }
+            dbExtent.store(fodb);
+        }
+        clearDirtyExtents();
+    }
+
+    /**
+     * Causes this DBInfo to forget about the dirty state of all extents
+     * marked as dirty since the last time storeDirtyExtents was invoked.
+     */    
+    void clearDirtyExtents() {
+        dirtyExtents.clear();
+    }
+
+    /**
+    * @return Iterator of DBExtent objects
+    */
+    Iterator getExtents() {
+        if (logger.isDebugEnabled()) {
+            logger.debug(
+                "DBInfo.getExtents: first=" + CLID.firstCLID + // NOI18N
+                ", next=" + nextCLID); // NOI18N
+        }
+        return new ExtentIterator(CLID.firstCLID, nextCLID);
+    }
+
+    class ExtentIterator implements Iterator {
+        private int current;
+        private final int finish;
+        
+        ExtentIterator(CLID start, CLID finish) {
+            this.current = start.getId();
+            this.finish = finish.getId();
+        }
+        
+        public boolean hasNext() {
+            return current < finish;
+        }
+        
+        public Object next() {
+            Object rc = null;
+            try {
+                rc = fodb.get(getExtentOID(CLID.create(current++, false)));
+            } catch (FOStoreDatabaseException ex) {
+            }
+            return rc;
+        }
+
+        public void remove() { }
+    }
+        
+    /**
+    * Provide a new OID for the given CLID.  Use this when creating an
+    * instance in the store.  The OID will have its CLID part as per the
+    * given CLID, and its UID part one greater than the last-created
+    * newInstanceOID.
+    * @param clid CLID for which a new OID is needed.
+    * @return An OID for the CLID.
+    * @exception FOStoreFatalInternalException thrown if the CLID is invalid.
+    */
+    OID newInstanceOID(CLID clid) {
+        OID rc = null;
+        int clidIndex = clid.getId();
+
+        synchronized(nextUIDs) {
+            if (nextUIDs.size() > clidIndex) {
+
+                // Get the next-uid value, increment by one, store the new
+                // next-uid.  Make an OID to return.
+                Long UID = (Long)nextUIDs.get(clidIndex);
+                long uid = UID.longValue();
+                if (uid == OID.MAX_UID) {
+                    throw new FOStoreFatalInternalException(
+                        this.getClass(), "newInstance", // NOI18N
+                        msg.msg("ERR_OutOfUIDs", // NOI18N
+                                new Long(OID.MAX_UID)));
+                }
+                uid++;
+                UID = new Long(uid);
+                nextUIDs.set(clidIndex, UID);
+                
+                rc = OID.create(clid, uid);
+            } else {
+                throw new FOStoreFatalInternalException(
+                    this.getClass(), "newInstance", // NOI18N
+                    msg.msg("ERR_NoUIDsForCLID", clid)); // NOI18N
+            }
+        }
+        return rc;
+    }
+
+    /** Returns a human-readable description of this DBInfo.  If system
+     * property "dbinfo.shortname" is true, then the description includes the
+     * name of the database (e.g. 'foo'), otherwise it includes the complete
+     * pathname of the database (e.g. '/bleem/foo').
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("DBInfo '"); // NOI18N
+        String name = fodb.getName();
+        // Default is to provide full pathname of database; for testing the
+        // short name is more appropriate.
+        if (Boolean.getBoolean("dbinfo.shortname")) { // NOI18N
+            int pos = name.lastIndexOf(File.separatorChar);
+            if (pos > 0) {
+                name = name.substring(pos + 1);
+            }
+        }
+        sb.append(name).append("'\n");  // NOI18N
+            
+        sb.append("Next ").append(nextCLID.toString()).append("\n"); // NOI18N
+
+        for (Iterator i = getExtents(); i.hasNext();) {
+            DBExtent e = (DBExtent)i.next();
+            CLID clid = e.getClassCLID();
+            Long uid = (Long)nextUIDs.get(clid.getId());
+
+            sb.append(
+                "    class ").append(e.toString()).append(", "); // NOI18N
+            sb.append(
+                "next UID: ").append(uid.toString()).append(".\n"); // NOI18N
+        }
+
+        return sb.toString();
+    }
+
+    //
+    // Implement Streamable
+    //
+    
+    public DBInfo() {
+        this(null);
+    }
+    
+    public void write(OutputStream os) throws StorageException {
+        DataOutputStream dos = new DataOutputStream(os);
+
+        try {
+            nextCLID.write(dos);
+
+            int size = nextUIDs.size();
+            dos.writeInt(size);
+            for (int i = 0; i < size; i++) {
+                Long clid = (Long)nextUIDs.get(i);
+                dos.writeLong(clid.longValue());
+            }
+        } catch (IOException ex) {
+            throw new StorageIOException(ex);
+        }
+    }
+
+    public void read(InputStream is) throws StorageException {
+        DataInputStream dis = new DataInputStream(is);
+        try {
+            nextCLID = CLID.read(dis);
+            
+            int size = dis.readInt();
+            nextUIDs = new ArrayList(size);
+            for (int i = 0; i < size; i++) {
+                nextUIDs.add(i, new Long(dis.readLong()));
+            }
+        } catch (IOException ex) {
+            throw new StorageIOException(ex);
+        }
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteHandler.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteHandler.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteHandler.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteHandler.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,103 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* Processes requests to delete objects from the datastore.
+*
+* @author Dave Bristor
+*/
+class DeleteHandler extends RequestHandler {
+
+    /** I18N Support */
+    private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+    private DeleteHandler(Reply reply, int length,
+                          FOStoreServerConnection con) {
+        super(reply, length, con);
+    }
+
+    public static HandlerFactory factory =
+        new HandlerFactory() {
+            public RequestHandler getHandler(Reply reply, int length,
+                                             FOStoreServerConnection con) {
+                return new DeleteHandler(reply, length, con);
+            }};
+
+
+    RequestFinisher handleRequest()
+        throws IOException, FOStoreDatabaseException {
+
+        if (logger.isDebugEnabled()) logger.debug("DeleteHandler.hR"); //NOI18N
+
+        DataInput in = con.getInputFromClient();
+        OID oid = OID.read(in);
+        boolean optimistic = in.readBoolean();
+
+        FOStoreDatabase fodb = con.getDatabase();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("DeleteHandler.hR: deleting " + oid + // NOI18N
+                           ", optimistic=" + optimistic); // NOI18N
+        }
+
+        if (logger.isTraceEnabled()) {
+            Block block = (Block)fodb.get(oid);
+            block.dump();
+        }
+
+        // Remove instance from database and from its Extent
+        boolean found = fodb.remove(oid);
+
+        if (found) {
+            DBInfo dbInfo = fodb.getDBInfo();
+            OID extentOID = dbInfo.getExtentOID(oid.getCLID());
+            DBExtent dbExtent = (DBExtent)fodb.get(extentOID);
+            dbExtent.remove(oid);
+            con.addExtent(dbExtent);
+            reply.setStatus(Status.OK);
+        } else {
+            // Instance to be deleted not in database.  If Tx is optimistic,
+            // it's a consistency failure; if datastore it's a bug.
+            if (optimistic) {
+                // XXX when delete verify is added, write the oid there also
+                oid.write(reply);
+                reply.setStatus(
+                    Status.OPTIMISTIC,
+                    msg.msg("EXC_DeleteVerifyFailed", oid)); // NOI18N
+            } else {
+
+                // Should not happen: datastore tx and instance not in store
+                if (logger.isDebugEnabled()) {
+                    logger.debug(
+                        "DeleteHandler.hR: " + oid + " not in db"); // NOI18N
+                }
+                reply.setStatus(
+                    Status.FATAL,
+                    msg.msg("ERR_DatastoreFailed", oid)); // NOI18N
+            }
+        }
+
+        return null;
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteRequest.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteRequest.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteRequest.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DeleteRequest.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,87 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Transaction;
+import javax.jdo.JDOHelper;
+
+import org.apache.jdo.state.StateManagerInternal;
+
+
+/**
+ * Represents a requests to remove a persistent object in the store.
+ *
+ * @author Dave Bristor
+ */
+//
+// This is client-side code.  It does not need to live in the server.
+//
+class DeleteRequest extends AbstractRequest {
+    /** OID of the instance being deleted. */
+    private final OID oid;
+
+    /** Optimistic/datastore state of current transaction. */
+    private final boolean optimistic;
+
+    DeleteRequest(StateManagerInternal sm, Message m, FOStorePMF pmf) {
+        super(sm, m, pmf);
+        this.oid = (OID)sm.getInternalObjectId();
+        PersistenceManager pm = sm.getPersistenceManager(); 
+        Transaction tx = pm.currentTransaction();
+        this.optimistic = tx.getOptimistic();
+    }
+
+    protected void doRequestBody() throws IOException {
+        //
+        // The format of this request is (aside from the request header):
+        //
+        // oid: OID
+        // optimistic: boolean
+        // numFields: int
+        // fieldValue: Object...
+        //
+
+        // XXX Need in optimistic Tx, verify w/ dirtyFields? ; see 
StoreManger#delete
+        if (logger.isDebugEnabled()) {
+            logger.debug("DeleteRequest.dRB: " + oid); // NOI18N
+        }
+        oid.write(out);
+        out.writeBoolean(optimistic);
+    }
+
+    //
+    // Methods from Request
+    //
+
+    /**
+     * @see Request#handleReply
+     */
+    public void handleReply(Status status, DataInput in, int length)
+        throws IOException {
+
+        //
+        // The format of this reply is
+        //
+        //  empty, that's right, no data needed.
+        //
+        if (logger.isDebugEnabled()) logger.debug("DeleteRequest.hR"); // 
NOI18N
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DoubleTranscriber.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DoubleTranscriber.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DoubleTranscriber.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DoubleTranscriber.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+* Transcribes double values.
+*
+* @author Dave Bristor
+*/
+class DoubleTranscriber extends FOStoreTranscriber {
+    private static DoubleTranscriber instance = new DoubleTranscriber();
+
+    private DoubleTranscriber() {}
+
+    static DoubleTranscriber getInstance() {
+        return instance;
+    }
+    
+    void storeDouble(double value, DataOutput out) throws IOException {
+        out.writeDouble(value);
+    }
+
+    double fetchDouble(DataInput in) throws IOException {
+        return in.readDouble();
+    }
+
+    void skip(DataInput in) throws IOException { 
+        in.readDouble(); 
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DummyTranscriber.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DummyTranscriber.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DummyTranscriber.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DummyTranscriber.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,42 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+* This Transcriber is used to skip managed non-persistent fields.
+* Any attempt to use it for fetching or storing a field will
+* result in FOStoreAbstractMethodException.
+*
+* @author Marina Vatkina
+*/
+class DummyTranscriber extends FOStoreTranscriber {
+    private static DummyTranscriber instance = new DummyTranscriber();
+
+    private DummyTranscriber() {}
+
+    static DummyTranscriber getInstance() {
+        return instance;
+    }
+    
+    void skip(DataInput in) throws IOException {}
+
+}
+

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpHandler.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpHandler.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpHandler.java 
(added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpHandler.java 
Fri Mar 18 17:02:29 2005
@@ -0,0 +1,261 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* Process dump requests. A dump request provides information about the
+* store. Currently, two options are supported:
+* <ul>
+* <li>dbInfo: Provide information about all classes stored in the store.</li>
+* <li>ClassMetadata: Provide the stored metadata information for the class
+* <code>className</code>.</li>
+* </ul>
+*
+* @see org.apache.jdo.impl.fostore.DumpOption
+* @author Markus Fuchs
+*/
+// This is server-side code.  It does not need to live in the client.
+class DumpHandler extends RequestHandler {
+
+    /** Maps <code>DumpOptions</code> to
+     * <code>DumpOptionSubHandlers</code>. The option table must match
+     * the <code>optionTable</code> in <code>Dumper</code>.
+     * <p>
+     * Because the <code>DumpOptionSubHandler</code> are bound to 
+     * the state of the enclosing <code>DumpHander</code> instance, the
+     * <code>optionTable</code> has to be non-static. */
+    private static HashMap optionTable = new HashMap();
+
+    /** List of results. A SubRequest might report more than one result. */
+    private final ArrayList results = new ArrayList();
+
+    /** Return status. */
+    private Status status;
+
+    /** I18N support. */
+    private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+    /** Initializes the <code>optionTable</code>.
+     * The option table must match the <code>optionTable</code> in
+     * <code>Dumper</code>.
+     * @see Dumper
+     */
+    // Note that there is no entry for DumpOption.CLASS_INSTANCES: that option
+    // is handled entirely by the Dumper on the client side, with help of
+    // FOStoreStoreManager.getExtent.
+    private void initOptionTable() {
+        optionTable.put(DumpOption.DBINFO,
+                        new DBInfoHandler());
+        optionTable.put(DumpOption.CLASS_METADATA,
+                        new ClassMetadataHandler());
+        optionTable.put(DumpOption.CLASS_SUBCLASSES,
+                        new ClassSubclassesHandler());
+    }
+
+    private DumpHandler(Reply reply, int length,
+                         FOStoreServerConnection con) {
+
+        super(reply, length, con);
+        initOptionTable();
+    }
+    
+    public static final HandlerFactory factory =
+        new HandlerFactory() {
+                public RequestHandler getHandler(Reply reply, int length,
+                                             FOStoreServerConnection con) {
+                return new DumpHandler(reply, length, con);
+            }};
+
+    RequestFinisher handleRequest()
+        throws IOException, FOStoreDatabaseException {
+
+        FOStoreInput in = con.getInputFromClient();
+        FOStoreDatabase db = con.getDatabase();
+
+        // read arguments
+        DumpOption option = DumpOption.read(in);
+        String className = in.readUTF();
+        
+        DumpOptionSubHandler h = 
+            (DumpOptionSubHandler) optionTable.get(option);
+        if (null == h) {
+            reply.setStatus(Status.FATAL,msg.msg("ERR_NoSubHandler", option)); 
// NOI18N
+        } else {
+            h.run(db, className);
+
+            int size = results.size();
+            reply.writeInt(size);
+            if (size > 0) {
+                for (int i = 0; i < size; i++) {
+                    Object o = results.get(i);
+                    if (null != o) {
+                        reply.writeUTF(o.toString());
+                    }
+                }
+            }
+            reply.setStatus(status);
+        }
+
+        return null;
+    }
+
+    /**
+     * Abstract class for dumping database information. The server creates
+     * instances of subclasses and then invoke <code>run</code>. Subclasses
+     * implement <code>run</code> method to do the real work.
+     */
+    abstract class DumpOptionSubHandler {
+
+        /** Must be implemented to dump particular kind of info.
+         */
+        protected abstract void run(FOStoreDatabase db, String className)
+            throws IOException, FOStoreDatabaseException;
+    }
+
+    /**
+     * OptionHandler that dumps DBInfo.
+     */
+    class DBInfoHandler extends DumpOptionSubHandler {
+      protected void run(FOStoreDatabase db, String className) 
+          throws IOException, FOStoreDatabaseException {
+
+          results.add(db.getDBInfo());
+          status = Status.OK;
+        }
+    }
+
+    /**
+     * Abstract OptionHandler that assists in dumping information about
+     * classes.
+     */
+    abstract class ClassHandler extends DumpOptionSubHandler {
+        protected void run(FOStoreDatabase db, String className) 
+            throws IOException, FOStoreDatabaseException {
+
+            if (null == className) {
+                reply.setStatus(
+                    Status.ERROR,
+                    msg.msg("MSG_MissingParameter", className)); //NOI18N
+            } else {
+                _run(db, className);
+            }
+        }
+
+        DBClass[] getDBClasses(FOStoreDatabase db, String className)
+            throws IOException, FOStoreDatabaseException {
+
+            DBClass rc[] = null;
+
+            // look for class info in store
+            DBInfo dbInfo = db.getDBInfo();
+            ArrayList found = new ArrayList();
+            for (Iterator i = dbInfo.getDBClasses(); i.hasNext();) {
+                DBClass dbClass = (DBClass)i.next();
+                if (className.equals(dbClass.getName())) {
+                    found.add(dbClass);
+                }
+            }
+            int size = found.size();
+            if (size > 0) {
+                rc = new DBClass[size];
+                for (int i = 0; i < size; i++) {
+                    rc[i] = (DBClass)found.get(i);
+                }
+            }
+            return rc;
+        }
+
+        /** Subclasses must implement, to dump their particular kind of info.
+        */
+        abstract void _run(FOStoreDatabase db, String className) 
+            throws IOException, FOStoreDatabaseException;
+    }
+
+
+    /**
+     * OptionHandler that dumps metadata about a class.
+     */
+    class ClassMetadataHandler extends ClassHandler {
+        protected void _run(FOStoreDatabase db, String className) 
+            throws IOException, FOStoreDatabaseException {
+
+            DBClass dbClasses[] = getDBClasses(db, className);
+            for (int i = 0; i < dbClasses.length; i++) {
+                results.add(dbClasses[i]);
+            }
+            status = Status.OK;
+        }
+    }
+
+    /**
+    * OptionHandler that dumps information about the subclasses of a class.
+    */
+    class ClassSubclassesHandler extends ClassHandler {
+        protected void _run(FOStoreDatabase db, String className)
+            throws IOException, FOStoreDatabaseException {
+
+            // Sort results in String order.
+            TreeSet sorted = new TreeSet();
+
+            DBClass dbClasses[] = getDBClasses(db, className);
+            if (null == dbClasses || 0 == dbClasses.length){
+                results.add(
+                    msg.msg("MSG_DbClassNotFound", className)); // NOI18N
+            } else {
+                // For each DBClass known by className, get all of its
+                // subclasses.
+                for (int i = 0; i < dbClasses.length; i++) {
+                    String result = null;
+                    CLID clid = dbClasses[i].getCLID();
+                    OID ssOID = DBInfo.getSubclassSetOID(clid);
+                    SubclassSet sl = (SubclassSet)db.getIfExists(ssOID);
+                    if (null == sl) {
+                        result = msg.msg("MSG_NoSubclasses", className); // 
NOI18N
+                    } else {
+                        result = msg.msg("MSG_Subclasses", className); // 
NOI18N
+                        // Get results into the TreeSet
+                        for (Iterator j = sl.iterator(); j.hasNext();) {
+                            CLID subCLID = (CLID)j.next();
+                            OID subDBClassOID = DBInfo.getDBClassOID(subCLID);
+                            DBClass subDBClass =
+                                (DBClass)db.get(subDBClassOID);
+                            sorted.add("\n\t" + subDBClass.getName()); // 
NOI18N
+                        }
+
+                        // Put sorted subclasses from TreeSet to string
+                        for (Iterator k = sorted.iterator(); k.hasNext();) {
+                            result += (String)k.next();
+                        }
+                    }
+                    results.add(result);
+                }
+            }
+            status = Status.OK;
+        }
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpOption.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpOption.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpOption.java 
(added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpOption.java 
Fri Mar 18 17:02:29 2005
@@ -0,0 +1,134 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.jdo.JDOUserException;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/** Diagnostic code to identify a dump request to the store. Currently,
+* there are the following options supported: 
+* <ul>
+* <li>DBINFO: Provide information about all classes in the store.</li>
+* <li>CLASS_METADATA: Provide metadata information about a special class.</li>
+* <li>CLASS_INSTANCES: List all instances of a special class.</li>
+* </ul>
+*
+* @author Markus Fuchs
+*/
+class DumpOption {
+    /** Value of this DumpOption. */
+    private final int value;
+
+    /** String name of this option. */
+    private final String name;
+
+    /** Map from name to DumpOption. */
+    private static final HashMap options = new HashMap();
+
+    /** Provide information about all classes in the store. */
+    static final DumpOption DBINFO =
+        new DumpOption(1, "dbInfo"); // NOI18N
+
+    /** Provide metadata information about a particular class.*/
+    static final DumpOption CLASS_METADATA =
+        new DumpOption(2, "classMetadata"); // NOI18N
+
+    /** List all instances of a particular class. */
+    static final DumpOption CLASS_INSTANCES =
+    new DumpOption(3, "classInstances"); // NOI18N
+
+    /** List all subclasses of a particular class. */
+    static final DumpOption CLASS_SUBCLASSES =
+    new DumpOption(4, "classSubclasses"); // NOI18N
+
+    /** I18N support. */
+    private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+    /**
+     * Create a DumpOption with the given value and name.
+     */
+    private DumpOption(int value, String name) {
+        this.value = value;
+        this.name = name;
+        options.put(name, this);
+    }
+
+    /** Provide a DumpOption given a name. */
+    static DumpOption forName(String name) {
+        DumpOption rc = (DumpOption)options.get(name);
+        if (null == rc) {
+            throw new JDOUserException(
+                msg.msg("EXC_BadValue", name)); // NOI18N
+        }
+        return rc;
+    }
+
+    //
+    // I/O support
+    // 
+
+    /**
+     * Write this DumpOption's value.
+     */
+    void write(DataOutput out) throws IOException {
+        out.writeUTF(name);
+    }
+
+    /**
+     * Return the instance of a DumpOption that corresponds to the value read
+     * from the DataInput.
+     * @throws IOException if there is an IOException reading the value.
+     * <em>or</em> if the value read does not correspond to a DumpOption.
+     */
+    static DumpOption read(DataInput in) throws IOException {
+        String optionName = in.readUTF();
+        DumpOption rc = forName(optionName);
+        if (null == rc) {
+            throw new IOException(
+                msg.msg("EXC_BadValue", optionName)); // NOI18N
+        }
+        return rc;
+    }
+
+    //
+    // Override java.lang.Object methods
+    //
+    
+    public String toString() {
+        return name;
+    }
+    
+    public boolean equals(Object o) {
+        boolean rc = false;
+        if ((null != o) && (o instanceof DumpOption)) {
+            rc = (value == ((DumpOption)o).value);
+        }
+        return rc;
+    }
+
+    public int hashCode() {
+        // Same as for java.lang.Integer
+        return value;
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpRequest.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpRequest.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpRequest.java 
(added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/DumpRequest.java 
Fri Mar 18 17:02:29 2005
@@ -0,0 +1,109 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.jdo.Extent;
+import javax.jdo.JDOHelper;
+import javax.jdo.JDOUserException;
+import javax.jdo.PersistenceManager;
+
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.state.StateManagerInternal;
+
+
+/**
+ * Represents a request to dump information from the store.
+ *
+ * @author Markus Fuchs
+ */
+//
+// This is client-side code.  It does not need to live in the server.
+//
+class DumpRequest extends AbstractRequest {
+    /** The DumpOption.
+     */
+    private final DumpOption option;
+
+    /** The name of the class queried by this request.
+     */
+    private final String className;
+
+    /** Returned dump information.
+     */
+    private String dump;
+
+    DumpRequest(DumpOption option, String className, Message m,
+                     FOStorePMF pmf) {
+
+        super(m, pmf);
+        this.option = option;
+        this.className = className;
+    }
+
+    protected void doRequestBody() throws IOException {
+        //
+        // The format of this request is:
+        //
+        // int: option code
+        // String: className
+        //
+
+        option.write(out);
+        out.writeUTF((null != className) ? className : ""); // NOI18N
+        if (logger.isDebugEnabled()) {
+            logger.debug("DR.dRB: " + option // NOI18N
+                           + " class=" + className); // NOI18N
+        }
+    }
+
+     public void handleReply(Status status, DataInput in, int length) throws 
IOException {
+         //
+         // The format of the reply is:
+         // int: number of objects (<= one)
+         // String: information dump
+         //
+         // The status might be Status.WARN, in which case either
+         // * The class to be queried wasn't found.
+         // * The className parameter was null.
+
+         int count = in.readInt();
+         if (logger.isDebugEnabled()) {
+             logger.debug("DR.hR/0: count=" + count); // NOI18N
+         }
+
+         StringBuffer results = new StringBuffer();
+         for (int i = 0; i < count; i++) {
+             results.append(in.readUTF());
+         }
+         dump = results.toString();
+         
+         if (logger.isDebugEnabled()) {
+             logger.debug("DR.hR/1: dump=" + dump); // NOI18N
+         }
+    }
+
+    String getDump() {
+        return dump;
+    }
+}

Added: incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Dumper.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Dumper.java?view=auto&rev=158176
==============================================================================
--- incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Dumper.java 
(added)
+++ incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/Dumper.java 
Fri Mar 18 17:02:29 2005
@@ -0,0 +1,280 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import javax.jdo.Extent;
+import javax.jdo.JDOUserException;
+import javax.jdo.PersistenceManager;
+
+import org.apache.jdo.impl.pm.PersistenceManagerWrapper;
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* Provides information such as metadata, extents, objects about the store.
+* <pre>
+* FOStore dumper program usage:
+*     -DdumpOption=OPTION -DclassNames=CLASSNAMES
+* OPTION parameter can be one of the following:
+*     dbInfo: prints general information about the store.
+*     classMetadata: prints the metadata for the classes CLASSNAMES.
+*     classInstances: prints all instances of the classes CLASSNAMES.
+*     classSubclasses: prints all information about the subclasses 
+*     of the classes CLASSNAMES.
+* </pre>
+* This class is <code>public</code> because it has a <code>main</code> entry
+* point for running as a standalone program.
+*
+* @author Markus Fuchs
+* @author Dave Bristor
+*/
+public class Dumper {
+
+    /** Maps <code>DumpOptions</code> to
+     * <code>DumpOptionSubRequests</code>. The option table must match
+     * the <code>optionTable</code> in <code>DumpHandler</code>.
+     * <p>
+     * Because there is no non-static state to be shared between
+     * <code>Dumper</code> and the <code>DumpOptionSubRequest</code>s, 
+     * the <code>optionTable</code> can be initilialzed only once.
+     * @see org.apache.jdo.impl.fostore.DumpOption
+     */
+    private static final HashMap optionTable = new HashMap();
+
+    private static FOStorePMF pmf;
+
+    /** Class names to dump informations about. */
+    private static String classNames;
+
+    /** I18N support. */
+    private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+    /**
+     * Initializes the <code>optionTable</code>.
+     * The option table must match the <code>optionTable</code> in
+     * <code>DumpHandler</code>.
+     * @see org.apache.jdo.impl.fostore.DumpHandler
+     */
+    static {
+        optionTable.put(DumpOption.DBINFO,
+                        new DBInfoRequest());
+        optionTable.put(DumpOption.CLASS_METADATA,
+                        new ClassMetadataRequest());
+        optionTable.put(DumpOption.CLASS_INSTANCES,
+                        new ClassInstancesRequest());
+        optionTable.put(DumpOption.CLASS_SUBCLASSES,
+                        new ClassSubclassesRequest());
+    }
+
+    /**
+     * Given a command line argument that specifies what information
+     * to dump, gets that information from the database and prints it
+     * on standard output.
+     * @param args the command line arguments
+     */
+    public static void main(String args[]) {
+
+        String optionName = System.getProperty("dumpOption"); // NOI18N
+        if (null == optionName) {
+            exit(msg.msg("MSG_MissingDumpOption")); // NOI18N
+        }
+        classNames = System.getProperty("classNames"); // NOI18N
+
+        try {
+            DumpOption option = DumpOption.forName(optionName);
+            
+            DumpOptionSubRequest r = 
+                (DumpOptionSubRequest)optionTable.get(option);
+            r.run();
+        } catch (Exception ex) {
+            exit(msg.msg("MSG_DumperException", ex)); // NOI18N
+        }
+    }
+
+    /**
+     * Abstract class for dumping database information. Clients create
+     * instances of subclasses and then invoke <code>run</code>. Subclasses
+     * implement <code>dump</code> method to do the real work.
+     */
+    static abstract class DumpOptionSubRequest {
+        protected PersistenceManager pm;
+        protected FOStoreStoreManager srm;
+        protected StringTokenizer st;
+
+        /** Called by clients to cause information to be dumped.
+         */
+        void run() {
+            try {
+                setupPMF();
+                pm = pmf.getPersistenceManager();
+                srm = (FOStoreStoreManager)pmf.getStoreManager(pm);
+                dump();
+            } catch (Exception ex) {
+                exit(msg.msg("MSG_DumperException", ex)); // NOI18N
+            }
+        }
+
+        /** Subclasses must implement, to dump their particular kind of info.
+         */
+        protected abstract void dump();
+    }
+
+    /**
+     * DumpRequest that can dump DBInfo.
+     */
+    static class DBInfoRequest extends DumpOptionSubRequest {
+        protected void dump() {
+            println(srm.dump(DumpOption.DBINFO, "")); // NOI18N
+        }
+    }
+
+    /**
+     * Abstract DumpRequest that assists in dumping
+     * information about classes.
+     */
+    static abstract class ClassRequest extends DumpOptionSubRequest {
+        protected void dump() {
+            StringTokenizer st = 
+                new StringTokenizer(classNames, ","); // NOI18N
+            while (st.hasMoreElements()) {
+                subDump((String)st.nextElement());
+            }
+        }
+
+        /** Subclasses must implement, to dump their particular kind
+         * of info.
+         */
+        protected abstract void subDump(String className);
+    }
+
+    /**
+     * DumpRequest that dumps metadata about a class.
+     */
+    static class ClassMetadataRequest extends ClassRequest {
+        protected void subDump(String className) {
+            println(srm.dump(DumpOption.CLASS_METADATA, className));
+        }
+    }
+
+    /**
+     * DumpRequest that dumps information about the instances
+     * of a class.
+     */
+    static class ClassInstancesRequest extends ClassRequest {
+        protected void subDump(String className) {
+            int objCount = 0;
+            Class cls = null;
+            try {
+                cls = Class.forName(className);
+            } catch (ClassNotFoundException ex) {
+                throw new JDOUserException(
+                  msg.msg("EXC_InstantiateClass", className)); // NOI18N
+            }
+
+            println("\n" + msg.msg("MSG_ExtentName", className)); // NOI18N
+            Extent e = pm.getExtent(cls, false);
+            for (Iterator i = e.iterator(); i.hasNext();) {
+                Object pc = i.next();
+                println("" + pc); // NOI18N
+                objCount++;
+            }
+            println(msg.msg("MSG_ExtentCount", className, // NOI18N 
+                            new Integer(objCount)));
+        }
+    }
+
+    /**
+     * DumpRequest that dumps information about the subclasses
+     * of a class.
+     */
+    static class ClassSubclassesRequest extends ClassRequest {
+        protected void subDump(String className) {
+            int objCount = 0;
+            Class cls = null;
+            try {
+                cls = Class.forName(className);
+            } catch (ClassNotFoundException ex) {
+                throw new JDOUserException(
+                  msg.msg("EXC_InstantiateClass", className)); // NOI18N
+            }
+
+            println(srm.dump(DumpOption.CLASS_SUBCLASSES, className));
+        }
+    }
+
+    /** Print an error message and exit.
+     */
+    private static void exit(String message) {
+        println(message);
+        usage();
+        System.exit(1);
+    }
+
+    /** Print the usage message on standard output.
+     */    
+    private static void usage() {
+        println(msg.msg("MSG_Usage")); // NOI18N
+    }
+        
+    /**
+     * Configures a PMF with some basic properties, and creates the
+     * corresponding database.
+     */
+    private static void setupPMF() throws Exception {
+        pmf = new FOStorePMF();
+        pmf.setConnectionCreate(false);
+
+        pmf.setConnectionUserName(System.getProperty("user", // NOI18N
+                                                     "fred")); // NOI18N
+        pmf.setConnectionPassword(System.getProperty("password", // NOI18N
+                                                     "wombat")); // NOI18N
+
+        // Create url in string form.
+        String path = ""; // NOI18N
+
+        String dir = System.getProperty("dir"); // NOI18N
+        if (null == dir) {
+            dir = System.getProperty("user.dir"); // NOI18N
+        }
+
+        String name = System.getProperty("name"); // NOI18N
+        if (null == name) {
+            name = "FOStoreTestDB"; // NOI18N
+        }
+
+        path += dir + File.separator;
+        path += name;
+        
+        path = "fostore:" + path; // NOI18N
+
+        pmf.setConnectionURL(path);
+    }
+
+    /** Print a message on the standard output.
+     * @param s the message to print.
+     */    
+    private static void println(String s) {
+        System.out.println(s);
+    }
+
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreAbstractMethodException.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreAbstractMethodException.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreAbstractMethodException.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreAbstractMethodException.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,31 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import javax.jdo.JDOFatalInternalException;
+
+/**
+ * This exception means that a subclass didn't override a method that it should
+ * have.  When thrown, it means there is an implementation bug.
+ *
+ * @author Dave Bristor
+ */
+class FOStoreAbstractMethodException extends JDOFatalInternalException {
+    FOStoreAbstractMethodException(String msg) {
+        super(msg); // NOI18N
+    }
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreBtreeStorage.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreBtreeStorage.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreBtreeStorage.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreBtreeStorage.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,142 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.util.HashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.netbeans.mdr.persistence.MOFID;
+import org.netbeans.mdr.persistence.ObjectResolver;
+import org.netbeans.mdr.persistence.StorageException;
+import org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeFactory;
+import org.netbeans.mdr.persistence.btreeimpl.btreestorage.BtreeStorage;
+
+/**
+ * FOStore specific BtreeStorage subclass. This class manages MOFIDs for a
+ * FOStore datastore. A MOFID consists of two parts: a storageId of type
+ * String and a serial number of type long. When storing on disk the
+ * storageId is converted into a number and stored as 16-bit value. Only 48
+ * bits of the serial number get represented on disk. FOStore uses the
+ * serial number to encode the uid part of an OID and the storageId for the
+ * class id of an OID. The btree class MOFIDInfo converts a MOFID into a
+ * byte array of 8 bytes that is stored on disk. The two high order bytes
+ * represent the storageId. Class MOFIDInfo calls method storageIdToNumber
+ * to convert a String storageId into a number. The remaining 6 bytes
+ * represent the serial number.  
+ *
+ * @author Michael Bouschen
+ * @since 1.1
+ * @version 1.1
+ */
+public class FOStoreBtreeStorage extends BtreeStorage {
+    
+    /** 
+     * Dummy ObjectResolver instance required by BtreeStorage create and 
+     * open methods.
+     */
+    private static final ObjectResolver resolver = new Resolver();
+
+    /** Prefix for the storageId generated from an class id. */
+    private static final String CLID_PREFIX = "FOSTORE_CLID";
+
+    /** Length of class id prefix. */
+    private static final int CLID_PREFIX_LENGTH = 12;
+
+    /** Logger */
+    static final Log logger = LogFactory.getFactory().getInstance(
+        "org.apache.jdo.impl.fostore"); // NOI18N
+
+    /**
+     * Creates a new FOStoreBtreeStorage instance. The constructor creates
+     * or opens a storage based on the specified argument <code>isNew</code>.
+     * @param name the name of the storage.
+     * @param isNew true if the database is being created
+     */
+    public FOStoreBtreeStorage(String name, boolean isNew) 
+        throws StorageException {
+        super(name);
+        if (isNew) {
+            create(true, resolver);
+        } 
+        else {
+            open(false, resolver);
+        }
+    }
+    
+    /**
+     * Returns Creates a MOFID based on the class id and uid taken from a
+     * FOStore OID. The storageId of the returned MOFID represents the
+     * class id and the serial number represents the uid.
+     * @param clid the class id 
+     * @param uid the unique id
+     * @return MOFID representing class id and uid taken from  FOStore OID.
+     */
+    public MOFID createMOFID(int clid, long uid) {
+        // Add FIRST_EXTERNAL_ID to avoid clashes with 
+        // internal btree serial numbers
+        long serialNumber = uid + BtreeFactory.FIRST_EXTERNAL_ID;
+        // The prefix CLID_PREFIX check whether the storageId denotes a
+        // fostore class id. Add FIRST_EXTERNAL_CODE to avoid clashes with  
+        // internal btree storageId codes
+        String storageId = 
+            CLID_PREFIX + (clid + BtreeFactory.FIRST_EXTERNAL_CODE);
+        return new MOFID(serialNumber, storageId);
+    }
+    
+    /** 
+     * Converts a storageId to an int. If the specified storageId starts
+     * with CLID_PREFIX, then the storageId represents a class id. In this
+     * case use the class id as the numeric reresentation. 
+     * @param storageId the storageId as String
+     * @return the numeric representation of the storageId 
+     */
+    public int storageIdToNumber(String storageId) throws StorageException {
+        if (storageId.startsWith(CLID_PREFIX))
+            return Integer.parseInt(storageId.substring(CLID_PREFIX_LENGTH));
+        else 
+            return super.storageIdToNumber(storageId);
+    }
+    
+    /**
+     * Creates a storage id from an int. It returns the FOStore specific
+     * String representation for a storageId representing a class id.
+     * @param number the numberic representation of the storageId 
+     * @return the storageId as String
+     */
+    public String numberToStorageId(int number) throws StorageException {
+        if (number >= BtreeFactory.FIRST_EXTERNAL_CODE)
+            return CLID_PREFIX + number;
+        else
+            return super.numberToStorageId(number);
+    }
+
+    /** Dummy implementation. */
+    static class Resolver implements ObjectResolver {
+        
+        /** */
+        public Object resolve(String storageID, Object key) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("FOStoreBtreeStorage: called Resolver.resolve(" +
+                             storageID + ", " + key + ")");
+            }
+            return new Object();
+        }
+    }
+}
+

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnection.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnection.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnection.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnection.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,82 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Represents the connection as seen by the client.  This contains two types
+ * of interface: that used by the ConnectionFactory, and that used by the
+ * Message.  It provides a means for managing the data sent and received
+ * from the store, as well as for being managed in a pool.
+ *
+ * @author Dave Bristor
+ */
+interface FOStoreClientConnection extends FOStoreConnection {
+
+    /** Connect to the data source.
+     */
+    public void connect() throws IOException;
+    
+    /**
+    * Provides DataInput from which the client can read replies from
+    * the server.
+    * @return DataInput from which the client can read replies.
+    */
+    public DataInput getInputFromServer() throws IOException;
+
+    /**
+     * Indicates that the client has finished writing.  The data is sent to the
+     * server and processed there.
+     */
+    public void sendToStore(byte[] buffer, int start, int length) throws 
IOException;
+
+    /**
+     * Put this connection back into the connection pool managed by the 
+     * ConnectionFactory.
+     */
+    public void close() throws IOException;
+    
+    /** Set the connection id used to create this connection.  This is used
+     * to determine which connection pool is used.
+     */
+    public void setConnectionId (FOStoreConnectionId connectionId);
+    
+    /** Get the connection id used to create this connection.  Connections
+     * are pooled based on this connection id.
+     */
+    public FOStoreConnectionId getConnectionId();
+    
+    /** Set the connection id used to create this connection.  This is used
+     * to determine which connection pool is used.
+     */
+    public void setConnectionFactory (FOStoreConnectionFactory 
connectionFactory);
+    
+    /** Get the connection Factory used to create this connection.  Connections
+     * are pooled based on this connection Factory.
+     */
+    public FOStoreConnectionFactory getConnectionFactory();
+    
+    /** Close the database associated with this connection.  In the remote 
case,
+     * close the socket.
+     */
+    public void closeDatabase() throws IOException, FOStoreDatabaseException ;
+    
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnectionImpl.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnectionImpl.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnectionImpl.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreClientConnectionImpl.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+/*
+ * FOStoreClientConnectionImpl.java
+ *
+ * Created on June 7, 2001, 3:17 PM
+ */
+
+package org.apache.jdo.impl.fostore;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.OutputStream;
+
+import java.net.URLConnection;
+import java.net.URL;
+import java.net.Socket;
+
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implementation of the client side of a FOStore connection.
+ *
+ * @author  Craig Russell
+ * @version 1.0
+ */
+abstract class FOStoreClientConnectionImpl extends URLConnection implements 
FOStoreClientConnection {
+
+    /** Message to handle connection-to-connection messages (login).
+     */
+    Message message = new Message();
+    
+    FOStoreConnectionFactory connectionFactory;
+    
+    FOStoreConnectionId connectionId;
+    
+    /** Flag set while logging in.  This flag, when set, causes close() to
+     * retain the connection instead of returning the connection to the pool.
+     */
+    private boolean loggingIn = true;
+
+    /** Logger */
+    static final Log logger = LogFactory.getFactory().getInstance(
+        "org.apache.jdo.impl.fostore"); // NOI18N
+    
+    /** Creates new FOStoreClientConnectionImpl */
+    public FOStoreClientConnectionImpl(URL url) {
+        super (url);
+        if (logger.isDebugEnabled()) logger.debug("FOCCI<init>" +  // NOI18N
+            " Host: " + url.getHost() + // NOI18N
+            " Port: " + url.getPort() + // NOI18N
+            " Path: " + url.getPath()); // NOI18N
+    }
+
+    /**
+     * Return this connection to the connection pool.
+     */
+    public void close() throws IOException {
+        if (!loggingIn) {
+            if (logger.isDebugEnabled()) {
+                logger.debug ("FOCCI.close: closing"); // NOI18N
+            }
+            connectionFactory.closeConnection(this);
+        } else {
+            if (logger.isDebugEnabled()) {
+                logger.debug ("FOCCI.close: loggingIn; not closing"); // NOI18N
+            }
+        }
+    }
+        
+    /** Log in to the datastore.  This will be done for both local and
+     * remote connections.
+     */
+    protected void login() throws IOException {
+        String path = localizePath(url.getPath());
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("FOCCI:login " +  // NOI18N
+                           " Database: " + path + // NOI18N
+                           " User: " + connectionId.getUser() + // NOI18N
+                           " Password: " + connectionId.getPassword() + // 
NOI18N
+                           " Create: " + connectionId.getCreate()); // NOI18N
+        }
+        LoginRequest logreq =
+            new LoginRequest(
+                message, connectionFactory.getPMF(),
+                path, connectionId.getUser(), connectionId.getPassword(),
+                connectionId.getCreate());
+        logreq.doRequest();
+        // false => NOT ok to close (this) connection
+        message.processInStore(this, false);
+        loggingIn = false;
+    }
+        
+    public void setConnectionFactory(FOStoreConnectionFactory cf) {
+        this.connectionFactory = cf;
+    }
+    
+    /** Get the connection Factory used to create this connection.  Connections
+     * are pooled based on this connection Factory.
+     */
+    public FOStoreConnectionFactory getConnectionFactory() {
+        return connectionFactory;
+    }
+    
+    /** Set the connection id used to create this connection.  This is used
+     * to determine which connection pool is used.
+     */
+    public void setConnectionId (FOStoreConnectionId id) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("FOCCI.setConnectionId(): " + // NOI18N
+            " URL: " + id.getUrl() + // NOI18N
+            " User: " + id.getUser() + // NOI18N
+            " Password: " + id.getPassword() + // NOI18N 
+            " Create: " + id.getCreate()); // NOI18N
+        }
+        this.connectionId = id;
+    }
+    
+    /** Get the connection id used to create this connection.  The id
+     * encapsulates URL, user, and password.  Connections
+     * are pooled based on this connection id.
+     */
+    public FOStoreConnectionId getConnectionId() {
+        return connectionId;
+    }
+    
+    /** 
+     * @return The path, modified as required for the kind of connection.
+     */
+    abstract protected String localizePath(String path);
+}

Added: 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreConnection.java
URL: 
http://svn.apache.org/viewcvs/incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreConnection.java?view=auto&rev=158176
==============================================================================
--- 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreConnection.java
 (added)
+++ 
incubator/jdo/trunk/ri11/src/java/org/apache/jdo/impl/fostore/FOStoreConnection.java
 Fri Mar 18 17:02:29 2005
@@ -0,0 +1,25 @@
+/*
+ * 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 org.apache.jdo.impl.fostore;
+
+/**
+* Tagging interface at root of all kinds of FOStore connections.
+*
+* @author Dave Bristor
+*/
+interface FOStoreConnection {
+}


Reply via email to