You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by mb...@apache.org on 2005/05/22 20:40:21 UTC
svn commit: r171355 [7/31] - in /incubator/jdo/trunk/fostore20: ./ src/
src/conf/ src/java/ src/java/org/ src/java/org/apache/
src/java/org/apache/jdo/ src/java/org/apache/jdo/impl/
src/java/org/apache/jdo/impl/fostore/ test/ test/conf/ 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/
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreStoreManager.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreStoreManager.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreStoreManager.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreStoreManager.java Sun May 22 11:40:13 2005
@@ -0,0 +1,720 @@
+/*
+ * 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.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.jdo.Extent;
+import javax.jdo.JDOException;
+import javax.jdo.JDODataStoreException;
+import javax.jdo.JDOFatalInternalException;
+import javax.jdo.JDOUserException;
+import javax.jdo.JDOFatalUserException;
+import javax.jdo.Transaction;
+import javax.jdo.spi.JDOImplHelper;
+import javax.jdo.spi.PersistenceCapable;
+import javax.jdo.spi.StateManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.impl.model.java.runtime.RuntimeJavaModelFactory;
+import org.apache.jdo.query.BasicQueryResult;
+import org.apache.jdo.query.QueryResult;
+import org.apache.jdo.query.QueryResultHelper;
+import org.apache.jdo.model.jdo.JDOClass;
+import org.apache.jdo.model.jdo.JDOIdentityType;
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.state.StateManagerInternal;
+import org.apache.jdo.store.Connector;
+import org.apache.jdo.store.StoreManagerImpl;
+import org.apache.jdo.util.I18NHelper;
+
+//
+// Note the exception handling herein; it is intentional: if we catch a
+// subclass of JDOException, rethrow it as it is "expected" by calling code,
+// but if it is not, then create a subclass of JDOException (as are all
+// FOStore exceptions) and throw that. In other words, the intent is that
+// only JDOException subclasses be thrown by this class.
+//
+
+/**
+* StoreManager represents the datastore to the rest of the JDO components.
+* It provides the means to write and read instances, to get the extent of
+* classes, and to get the object id for a persistence capable object.
+*
+* @author Dave Bristor
+*/
+class FOStoreStoreManager extends StoreManagerImpl {
+ private final FOStorePMF pmf;
+ private final FOStoreConnector connector;
+ private final RequestFactory rf;
+
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(
+ I18N.NAME, FOStoreStoreManager.class.getClassLoader());
+
+ /** Logger */
+ static final Log logger = LogFactory.getFactory().getInstance(
+ "org.apache.jdo.impl.fostore"); // NOI18N
+
+ /** JDOImplHelper instance. */
+ private static final JDOImplHelper jdoImplHelper =
+ (JDOImplHelper) AccessController.doPrivileged (
+ new PrivilegedAction () {
+ public Object run () {
+ try {
+ return JDOImplHelper.getInstance();
+ }
+ catch (SecurityException e) {
+ throw new JDOFatalUserException (msg.msg(
+ "ERR_Security", e.getMessage()), e); // NOI18N
+ }
+ }
+ }
+ );
+
+ /** RuntimeJavaModelFactory. */
+ private static final RuntimeJavaModelFactory javaModelFactory =
+ (RuntimeJavaModelFactory) AccessController.doPrivileged(
+ new PrivilegedAction () {
+ public Object run () {
+ return RuntimeJavaModelFactory.getInstance();
+ }
+ }
+ );
+
+ FOStoreStoreManager(FOStorePMF pmf) {
+ this.pmf = pmf;
+ this.connector = new FOStoreConnector(pmf);
+ this.rf = pmf.getRequestFactory();
+ }
+
+ //
+ // Implement org.apache.jdo.store.StoreManager
+ //
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#getConnector
+ */
+ public Connector getConnector() {
+ return connector;
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#getConnector(String userid,
+ * String password)
+ */
+ public Connector getConnector(String userid, String password) {
+ throw new JDOUserException("Not yet implemented"); // NOI18N
+ }
+
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#insert(BitSet, BitSet,
+ * StateManagerInternal)
+ */
+ public synchronized int insert(
+ BitSet loadedFields, BitSet dirtyFields, StateManagerInternal sm) {
+
+ Message message = connector.getMessage();
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.insert"); // NOI18N
+ }
+
+ InsertRequest request = rf.getInsertRequest(sm, message, pmf);
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "insert", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "insert", ex); // NOI18N
+ }
+ dirtyFields.xor(dirtyFields); // Clear all bits.
+ return StateManagerInternal.FLUSHED_COMPLETE;
+ }
+
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#update(BitSet, BitSet,
+ * StateManagerInternal)
+ */
+ public synchronized int update(
+ BitSet loadedFields, BitSet dirtyFields, StateManagerInternal sm) {
+
+ Message message = connector.getMessage();
+ try {
+ UpdateRequest request =
+ rf.getUpdateRequest(sm, message, pmf,
+ loadedFields, dirtyFields, optimistic);
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "update", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "update", ex); // NOI18N
+ }
+ dirtyFields.xor(dirtyFields); // Clear all bits.
+ return StateManagerInternal.FLUSHED_COMPLETE;
+ }
+
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#verifyFields(BitSet,
+ * BitSet, StateManagerInternal)
+ */
+ public synchronized int verifyFields(
+ BitSet ignoredFields, BitSet fieldsToVerify, StateManagerInternal sm) {
+
+ if ( ! verify(sm, true, fieldsToVerify)) {
+ throw new JDODataStoreException(
+ msg.msg("EXC_VerifyFields")); // NOI18N
+ }
+ fieldsToVerify.xor(fieldsToVerify); // Clear all bits.
+ return StateManagerInternal.FLUSHED_COMPLETE;
+ }
+
+ // RESOLVE: Marina, do we need this? @see org.apache.jdo.store.StoreManager#verifyExistence.
+ /**
+ * @see org.apache.jdo.store.StoreManager#verifyExistence
+ */
+// public boolean verifyExistence(StateManagerInternal sm) {
+// return verify(sm, false, null, null);
+// }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#delete(BitSet, BitSet,
+ * StateManagerInternal)
+ */
+ public synchronized int delete(
+ BitSet loadedFields, BitSet dirtyFields, StateManagerInternal sm) {
+
+ Message message = connector.getMessage();
+ try {
+ DeleteRequest request = rf.getDeleteRequest(sm, message, pmf);
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "delete", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "delete", ex); // NOI18N
+ }
+ dirtyFields.xor(dirtyFields);
+ return StateManagerInternal.FLUSHED_COMPLETE;
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#fetch
+ */
+ public synchronized void fetch(StateManagerInternal sm, int fieldNums[]) {
+
+ Message message = connector.getMessage();
+ try {
+ FetchRequest request = rf.getFetchRequest(sm, message, pmf);
+ request.doRequest();
+ connector.flush();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "fetch", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "fetch", ex); // NOI18N
+ }
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#getExtent
+ */
+ public synchronized Extent getExtent(Class pcClass, boolean subclasses,
+ PersistenceManagerInternal pm) {
+
+ FOStoreModel model = pmf.getModel();
+ Message message = connector.getMessage();
+
+ // If the instance's class has PC superclasses, we must make sure
+ // they are activated too.
+ activateClasses(pcClass, message);
+
+ return new FOStoreExtent(pcClass, subclasses, pm, rf, connector);
+ }
+
+ /**
+ * Creates a new object id for the given sm. Delegates implementation to
+ * #createInternalObjectId(StateManagerInternal sm,Class cls,
+ * PersistenceManagerInternal pm)
+ * @see org.apache.jdo.store.StoreManager#createObjectId
+ */
+ public synchronized Object createObjectId(StateManagerInternal sm,
+ PersistenceManagerInternal pm) {
+ PersistenceCapable obj = sm.getObject();
+ Class cls = obj.getClass();
+ OID rc = createInternalObjectId(sm, obj, null, cls, pm);
+ return rc;
+ }
+
+ /**
+ * Creates a new object id for the given class. Binds metadata for the sm
+ * (i.e., ensures that there is a CLID for instances of the sm's object's
+ * class). Creates a request in the message that will provide a datastore
+ * oid for the provisional oid which is returned, but does not interact
+ * with the store.
+ * @see org.apache.jdo.store.StoreManager#createObjectId
+ */
+ public synchronized OID createInternalObjectId(StateManagerInternal sm,
+ PersistenceCapable pc, Object oid,
+ Class cls, PersistenceManagerInternal pm) {
+ FOStoreModel model = pmf.getModel();
+ Message message = connector.getMessage();
+
+ // If the instance's class has PC superclasses, we must make sure
+ // they are activated too.
+ JDOClass jdoClass = model.getJDOClass(cls);
+
+ // Now we can bind class type to the correct OID instance.
+ OID rc = model.bind(cls, jdoClass.getIdentityType(), pc, oid, pm, pmf);
+
+ activateClasses(cls, message);
+
+ // If the instance's CLID is provisional, we must activate its class.
+ CLID clid = rc.getCLID();
+ if (clid.isProvisional() && ! message.containsCLID(clid)) {
+ activateClass(cls, message);
+ message.addCLID(clid);
+ }
+
+ try {
+ CreateOIDRequest request =
+ rf.getCreateOIDRequest(sm, message, pmf, rc, pm);
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "createObjectid", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ /**
+ * Provides a datastore object id.
+ * If objectId is not provisional, return it. Otherwise, see if we have a
+ * corresponding datastore objectId and return that if so. If neither of
+ * those works out, flush the current message which (we hope) will have a
+ * corresponding CreateObjectIdRequest in it. Then look as before for a
+ * corresponding datastore objectId in our mapping and return that. If we
+ * still don't have a correspondance, throw an exception.
+ * @see org.apache.jdo.store.StoreManager#getExternalObjectId(Object oid,
+ * PersistenceCapable pc)
+ */
+ public synchronized Object getExternalObjectId(Object objectId,
+ PersistenceCapable pc) {
+ Object rc = null;
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.getEOID given " + objectId); // NOI18N
+ }
+ OID oid = (OID)objectId;
+ if (oid.isProvisional()) {
+ if (oid.isDataStoreIdentity()) {
+ oid = pmf.getRealOIDFromProvisional(oid);
+
+ if (null == oid) {
+
+ // Given objectId is provisional, and we have no mapping.
+ // Flush so that the CreateObjectId requests that are in
+ // the current message get written to the store, which
+ // should cause us to get a datastore oid for the given
+ // provisional oid.
+ preFlush();
+ oid = pmf.getRealOIDFromProvisional((OID)objectId);
+ if (null == oid) {
+ throw new JDOUserException(
+ msg.msg("EXC_UnboundOID"), objectId); // NOI18N
+ }
+ }
+ } else {
+ // Do flush only:
+ preFlush();
+ }
+ }
+ // Always return a copy
+ rc = oid.getExternalObjectId(pc);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.getEOID returning " + rc); // NOI18N
+ }
+
+ return rc;
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#copyKeyFieldsFromObjectId
+ */
+ public void copyKeyFieldsFromObjectId(StateManagerInternal sm,
+ Class pcClass) {
+ OID oid = (OID)sm.getInternalObjectId();
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.copyKeyFieldsFromObjectId: " + oid); // NOI18N
+ }
+ PersistenceManagerInternal pm = sm.getPersistenceManager();
+ FOStoreModel model = pmf.getModel();
+ JDOClass jdoClass = model.getJDOClass(pcClass);
+ oid.copyKeyFieldsToPC(sm, pmf, pcClass,
+ jdoClass.getPrimaryKeyFieldNumbers());
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#hasActualPCClass
+ */
+ public boolean hasActualPCClass(Object objectId) {
+ boolean rc = false;
+ if (objectId instanceof OID) {
+ rc = ((OID)objectId).isDataStoreIdentity();
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.hasActualPCClass: " + rc); // NOI18N
+ }
+ return rc;
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#getInternalObjectId
+ */
+ public synchronized Object getInternalObjectId(Object objectId,
+ PersistenceManagerInternal pm) {
+ OID rc = null;
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.getInternalObjectId: " + objectId); // NOI18N
+ }
+ if (objectId instanceof OID) {
+ rc = ((OID)objectId).copy();
+ } else {
+ Class cls = getPCClassForOid(objectId, pm);
+ rc = createInternalObjectId(null, null, objectId, cls, pm);
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.getInternalObjectId: got=" + rc); // NOI18N
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * @see org.apache.jdo.store.StoreManager#getPCClassForOid
+ */
+ public synchronized Class getPCClassForOid(Object objectId,
+ PersistenceManagerInternal pm) {
+ Class rc = null;
+ Message message = connector.getMessage();
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.getPCClassForOid: " +
+ objectId.getClass().getName() + objectId); // NOI18N
+ }
+ if (!(objectId instanceof OID)) {
+ Class cls = objectId.getClass();
+ rc = pm.loadPCClassForObjectIdClass(cls);
+ } else {
+ OID oid = (OID)objectId;
+ CLID clid = oid.getCLID();
+
+ FOStoreModel model = pmf.getModel();
+ rc = model.getClass(clid);
+
+ if (null == rc) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOSRM.getPCClassForOid: asking store for CLID: " +
+ clid); // NOI18N
+ }
+ // The clid is not known in this JVM, but it might be known
+ // in the store. Try to get it.
+ GetClassRequest request =
+ rf.getGetClassRequest(clid, message, pmf, pm);
+ try {
+ request.doRequest();
+ connector.flush();
+ rc = request.getClassForCLID();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "getPCClassForOid", ex); // NOI18N
+ }
+ }
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.getPCClassForOid: got " + rc); // NOI18N
+ }
+ } catch (ClassCastException ex) {
+ throw new JDOUserException(
+ msg.msg("EXC_NotOID"), ex, objectId); // NOI18N
+ } catch (ClassNotFoundException ex) {
+ throw new JDOUserException(
+ msg.msg("EXC_NotOID"), ex, objectId); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "getPCClassForOid", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ /**
+ * This method returns an object id instance corresponding to the Class
+ * and String arguments. The String argument might have been the
+ * result of executing toString on an object id instance.
+ * @param pcClass the Class of the persistence-capable instance
+ * @param str the String form of the object id
+ * @return an instance of the object identity class
+ */
+ public Object newObjectIdInstance (Class pcClass, String str) {
+ Object rc = null;
+ FOStoreModel model = pmf.getModel();
+ JDOClass jdoClass = model.getJDOClass(pcClass);
+ switch (jdoClass.getIdentityType()) {
+ case JDOIdentityType.APPLICATION:
+ //No need to create an AID here - it will not be used.
+ rc = jdoImplHelper.newObjectIdInstance(pcClass, str);
+ break;
+ case JDOIdentityType.DATASTORE:
+ rc = new OID(str);
+ break;
+ default:
+ break;
+ }
+ return rc;
+ }
+
+ /**
+ * Returns a QueryResult instance which is then returned as the result of
+ * Query.execute(...). This method allows support for datastore specific
+ * query execution strategies, since each StoreManager can have its own
+ * implementation of the QueryResult interface.
+ * For now fostore uses the non optimized BasicQueryResult as QueryResult
+ * implemenatation.
+ * @param qrh the helper providing the query tree, the candidates
+ * and the actual parameters.
+ * @return a datastore specific query result instance
+ */
+ public QueryResult newQueryResult(QueryResultHelper qrh) {
+ return new BasicQueryResult(qrh);
+ }
+
+ //
+ // Used within FOStore
+ //
+
+ /**
+ * Activates this class and all supeclasses.
+ */
+ private void activateClasses(Class cls, Message message) {
+ FOStoreModel model = pmf.getModel();
+ // If the instance's class has PC superclasses, we must make sure
+ // they are activated too.
+ JDOClass jdoClass = model.getJDOClass(cls);
+ JDOClass jdoSuper = jdoClass.getPersistenceCapableSuperclass();
+ if (null != jdoSuper) {
+ ArrayList javaSupers = new ArrayList();
+ while (null != jdoSuper) {
+ Class javaSuper = javaModelFactory.
+ getJavaClass(jdoSuper.getJavaType());
+ javaSupers.add(javaSuper);
+ jdoSuper = jdoSuper.getPersistenceCapableSuperclass();
+ }
+
+ // Activate the superclasses in order from Object on down, so
+ // that the store can recognize subclasses.
+ int size = javaSupers.size();
+ for (int i = size - 1; i >= 0; i--) {
+ Class javaSuper = (Class)javaSupers.get(i);
+ CLID clidSuper = model.getCLID(javaSuper);
+ if (clidSuper.isProvisional() &&
+ ! message.containsCLID(clidSuper)) {
+ activateClass(javaSuper, message);
+ message.addCLID(clidSuper);
+ }
+ }
+ }
+
+ }
+ /**
+ * Writes a request to activate the given state manager's class
+ */
+ private void activateClass(Class cls, Message message) {
+ ActivateClassRequest request =
+ rf.getActivateClassRequest(cls, message, pmf);
+ try {
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "activateClass", ex); // NOI18N
+ }
+ }
+
+ /**
+ * Dumps information about the store. The provided information
+ * depends on the <code>option</code> parameter. Currently,
+ * there are the following options supported:
+ * <ul>
+ * <li>DBInfo: Provide information about all classes stored in the
+ * database.</li>
+ * <li>MetaData: Provide metadata information about the class
+ * <code>name</code>.</li>
+ * </ul>
+ * @param option Dump option, specifies the kind of information.
+ * @param name Optional fully qualified classname.
+ * @see org.apache.jdo.impl.fostore.DumpOption
+ */
+ public String dump(DumpOption option, String name) {
+ Message message = connector.getMessage();
+ try {
+ DumpRequest request =
+ rf.getDumpRequest(option, name, message, pmf);
+ request.doRequest();
+ connector.flush();
+ return request.getDump();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "dump", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new FOStoreFatalInternalException(
+ getClass(), "dump", ex); // NOI18N
+ }
+ }
+
+ /**
+ * Get instances for oids
+ * @param oids List of oids
+ * @param start Starting index within <code>oids</code> of oids whose
+ * instances are to be returned.
+ * @param numInstances Number of instances to return.
+ * @param pm PersistenceManagerInternal on whose behalf the instances are
+ * being obtained.
+ * @param cls Candidate Class for which instances are being obtained.
+ * @return ArrayList of instances corresponding to
+ * <code>numInstances</code> of oids in the <code>oids</code> parameter,
+ * starting at <code>start</code>.
+ */
+ synchronized ArrayList getInstances(
+ ArrayList oids, int start, int numInstances,
+ PersistenceManagerInternal pm, Class cls) {
+
+ ArrayList rc = null;
+ Message message = connector.getMessage();
+ try {
+ GetInstancesRequest request =
+ rf.getGetInstancesRequest(oids, start, numInstances,
+ message, pm, cls);
+ request.doRequest();
+ connector.flush();
+ rc = request.getInstances();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "getInstances", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "getInstances", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ //
+ // Implementation detail
+ //
+
+ /**
+ * Verifies existence or values of a state manager's object in the
+ * database.
+ * @param sm The state manager whose object is to be verified.
+ * @param verifyFields If true, verify values of object, otherwise verify
+ * only existence (and ignore remaining parameters).
+ * @param fieldsToVerify Set of fields to be verified against those in the
+ * database.
+ * @return true if verify was successful (either by existence of value
+ * matching as per verifyFields).
+ */
+ private boolean verify(StateManagerInternal sm,
+ boolean verifyFields, BitSet fieldsToVerify) {
+
+ boolean rc = false;
+ Message message = connector.getMessage();
+ try {
+ VerifyRequest request =
+ rf.getVerifyRequest(sm, message, pmf,
+ verifyFields, fieldsToVerify);
+ request.doRequest();
+ connector.flush();
+ rc = request.getVerified();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "verify", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "verify", ex); // NOI18N
+ }
+ return rc; //success
+ }
+
+ /**
+ * Write a CommitRequest and flush the connector, to cause all
+ * CreateOid and ActivateClass requests to be committed in the
+ * database *before* any inserts, updates, or deletes.
+ */
+ protected void preFlush() {
+ Message message = connector.getMessage();
+ CommitRequest request = rf.getCommitRequest(message, pmf);
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOSRM.preFlush"); // NOI18N
+ }
+ try {
+ request.setOkToReleaseDatabase(false);
+ request.doRequest();
+ connector.flush();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "flush", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "flush", ex); // NOI18N
+ }
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriber.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriber.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriber.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriber.java Sun May 22 11:40:13 2005
@@ -0,0 +1,193 @@
+/*
+ * 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 org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.store.Transcriber;
+
+
+//
+// A note on Strings and Objects
+//
+// The JDO spec calls out special treatment for primitives and Strings,
+// lumping everything else into the category "Object". For example,
+// StateManager has providedStringField(). So, one would think this singling
+// out of String as a "primitive Object" would continue here.
+//
+// We have not done so. The reason is Collections. Primitives are never
+// elements of Collections, only Objects. Strings are Objects. To treat
+// them as primitives would require special treatment in each of the
+// collection transcribers. Rather than do that, we treat Strings as
+// Objects. Eventually, Strings get the same treatment as other immutable
+// types such as Integer; see ImmutableStringTranscriber.
+//
+
+/**
+* FOStoreTranscriber contains methods to transcribe each primitive type,
+* but they all throw AbstractMethodError. Subclasses do the actual
+* work, implementing methods for one and only one type of data.
+*
+* @author Dave Bristor
+*/
+abstract class FOStoreTranscriber implements Transcriber {
+ // See ObjectTranscriber's description of getInstance() method.
+ static final ObjectTranscriber objectTranscriber =
+ new ObjectTranscriber();
+
+ //
+ // Transcriber methods. All are quasi-abstract: they are intended to be
+ // overridden.
+ //
+
+ void storeBoolean(boolean value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeBoolean"); // NOI18N
+ }
+
+ boolean fetchBoolean(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchBoolean"); // NOI18N
+ }
+
+
+ void storeChar(char value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeChar"); // NOI18N
+ }
+
+ char fetchChar(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchChar"); // NOI18N
+ }
+
+
+ void storeByte(byte value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeByte"); // NOI18N
+ }
+
+ byte fetchByte(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchByte"); // NOI18N
+ }
+
+
+ void storeShort(short value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeShort"); // NOI18N
+ }
+
+ short fetchShort(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchShort"); // NOI18N
+ }
+
+
+ void storeInt(int value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeInt"); // NOI18N
+ }
+
+ int fetchInt(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchInt"); // NOI18N
+ }
+
+
+ void storeLong(long value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeLong"); // NOI18N
+ }
+
+ long fetchLong(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchLong"); // NOI18N
+ }
+
+
+ void storeFloat(float value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeFloat"); // NOI18N
+ }
+
+ float fetchFloat(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchFloat"); // NOI18N
+ }
+
+
+ void storeDouble(double value, DataOutput out) throws IOException {
+ throw new FOStoreAbstractMethodException(getClass().getName() +
+ ".storeDouble"); // NOI18N
+ }
+
+ double fetchDouble(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchDouble"); // NOI18N
+ }
+
+ void skip(DataInput in) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".skip"); // NOI18N
+ }
+
+
+ //
+ // Note that the signatures and visibilty of the Object-related
+ // transcribing methods differ from the above.
+ //
+ // The publicly visible storeObject requires a PersistenceManagerInternal
+ // parameter, so that we can get its StoreManager and an OIDs
+ // corresponding to a Java objects.
+ //
+ // The signature of fetchObject takes Object and int parameters so that
+ // we can support SCO's, which must be created with an owner and field
+ // number. It takes a PM so that it can create an object from an OID.
+ //
+
+ int[] storeObject(Object value, FOStoreOutput out,
+ PersistenceManagerInternal pm) throws IOException {
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeObject"); // NOI18N
+ }
+
+ protected int[] storeObject(Object value, FOStoreOutput out)
+ throws IOException {
+
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".storeObject"); // NOI18N
+ }
+
+ Object fetchObject(DataInput in, Object owner, int fieldNum,
+ PersistenceManagerInternal pm)
+ throws IOException, Exception {
+
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchObject"); // NOI18N
+ }
+
+ protected Object fetchObject(DataInput in, Object owner, int fieldNum)
+ throws IOException, Exception {
+
+ throw new FOStoreAbstractMethodException(
+ getClass().getName() + ".fetchObject"); // NOI18N
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriberFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriberFactory.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriberFactory.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreTranscriberFactory.java Sun May 22 11:40:13 2005
@@ -0,0 +1,90 @@
+/*
+ * 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.JDOException;
+
+import org.apache.jdo.store.Transcriber;
+import org.apache.jdo.store.TranscriberFactory;
+
+
+/**
+* Provides Transcriber instances for FOStore. Note that only one instance of
+* any kind of transcriber is ever created.
+*
+* @author Dave Bristor
+*/
+class FOStoreTranscriberFactory implements TranscriberFactory {
+ // Singleton
+ private static FOStoreTranscriberFactory instance;
+
+ private static HashMap transcribers = new HashMap(10);
+
+ private FOStoreTranscriberFactory() {
+ transcribers.put(boolean.class,
+ new Transcriber[] { BooleanTranscriber.getInstance()});
+ transcribers.put(char.class,
+ new Transcriber[] { CharTranscriber.getInstance()});
+ transcribers.put(byte.class,
+ new Transcriber[] { ByteTranscriber.getInstance()});
+ transcribers.put(short.class,
+ new Transcriber[] { ShortTranscriber.getInstance()});
+ transcribers.put(int.class,
+ new Transcriber[] { IntTranscriber.getInstance()});
+ transcribers.put(long.class,
+ new Transcriber[] { LongTranscriber.getInstance()});
+ transcribers.put(float.class,
+ new Transcriber[] { FloatTranscriber.getInstance()});
+ transcribers.put(double.class,
+ new Transcriber[] { DoubleTranscriber.getInstance()});
+ transcribers.put(Object.class,
+ new Transcriber[] { ObjectTranscriber.getInstance()});
+ }
+
+ static FOStoreTranscriberFactory getInstance() {
+ if (null == instance) {
+ instance = new FOStoreTranscriberFactory();
+ }
+ return instance;
+ }
+
+ /**
+ * Provides a Transcriber for the given class. The result is an array, as
+ * defined by the interface, but the return here always contains only one
+ * Transcriber.
+ * @param cls Class for which a Transcriber is needed.
+ * @return An array of transcribers; array will contain only one
+ * Transcriber.
+ */
+ public Transcriber[] getTranscriber(Class cls) {
+ Transcriber rc[] = null;
+ if (cls != null) {
+ rc = (Transcriber[])transcribers.get(cls);
+ if (null == rc) { // cls not of a primitive
+ rc = (Transcriber[])transcribers.get(Object.class);
+ }
+ }
+ return rc;
+ }
+}
+
+
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreURLStreamHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreURLStreamHandler.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreURLStreamHandler.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreURLStreamHandler.java Sun May 22 11:40:13 2005
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/*
+ * FOStoreURLStreamHandler.java
+ *
+ * Created on June 7, 2001, 7:11 PM
+ */
+
+package org.apache.jdo.impl.fostore;
+
+import java.net.URLStreamHandler;
+import java.net.URLConnection;
+import java.io.IOException;
+
+/**
+ * Creates connections to databases.
+ * @author Craig Russell
+ * @version 1.0
+ */
+class FOStoreURLStreamHandler extends URLStreamHandler {
+
+ static FOStoreURLStreamHandler sh = new FOStoreURLStreamHandler();
+
+ static FOStoreURLStreamHandler getInstance() {
+ return sh;
+ }
+
+ /** Creates new FOStoreURLStreamHandler */
+ public FOStoreURLStreamHandler() {
+ }
+
+ protected URLConnection openConnection(java.net.URL url)
+ throws IOException {
+ if (url.getHost().length() == 0) {
+ // local connection
+ return new FOStoreLocalConnection(url);
+ } else {
+ // remote connection
+ return new FOStoreRemoteConnection(url);
+ }
+ }
+
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreUnsupportedException.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreUnsupportedException.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreUnsupportedException.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreUnsupportedException.java Sun May 22 11:40:13 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.
+ */
+
+package org.apache.jdo.impl.fostore;
+
+import javax.jdo.JDOFatalException;
+
+/**
+* This exception means that a FOStore doesn't have support for what is being
+* requested. This differs from JDOUnsupportedException, which indicates that
+* an optional feature has not been implemented. This is used, for example, to
+* indicate that storing of a particular type (e.g. an array of non-PC objects)
+* is not supported.
+*
+* @author Dave Bristor
+*/
+class FOStoreUnsupportedException extends JDOFatalException {
+ FOStoreUnsupportedException(String msg) {
+ super(msg);
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchHandler.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchHandler.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchHandler.java Sun May 22 11:40:13 2005
@@ -0,0 +1,143 @@
+/*
+ * 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.Iterator;
+
+import javax.jdo.JDOUserException;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* Process fetch requests.
+*
+* @author Dave Bristor
+*/
+//
+// This is server-side code. It does not need to live in the client.
+//
+class FetchHandler extends RequestHandler {
+
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+ private FetchHandler(Reply reply, int length,
+ FOStoreServerConnection con) {
+
+ super(reply, length, con);
+ }
+
+ public static final HandlerFactory factory =
+ new HandlerFactory() {
+ public RequestHandler getHandler(Reply reply, int length,
+ FOStoreServerConnection con) {
+ return new FetchHandler(reply, length, con);
+ }};
+
+ RequestFinisher handleRequest()
+ throws IOException, FOStoreDatabaseException {
+
+ // XXX TBD Handle numFields and fieldNums. For now, we're expecting
+ // only an OID, and we return all field values.
+
+ DataInput in = con.getInputFromClient();
+ boolean knownclass = in.readBoolean();
+ OID oid = OID.read(in);
+ CLID clid = oid.getCLID();
+
+ FOStoreDatabase fodb = con.getDatabase();
+ Block block = null;
+ try {
+ block = (Block)fodb.getIfExists(oid);
+ if (null == block) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FR.reply: nonexistent: " + oid); // NOI18N
+ }
+
+ if (knownclass == false) {
+ long uid = oid.getUID();
+ OID tempOid = null;
+ if (clid.isProvisional()) {
+ // Retry with the known class id.
+ if (logger.isDebugEnabled()) {
+ logger.debug("FH.hR: replace provisional clid..."); // NOI18N
+ }
+ clid = fodb.getRealCLIDFromProvisional(clid);
+ tempOid = OID.create(clid, uid);
+ block = (Block)fodb.getIfExists(tempOid);
+ }
+ if (null == block) {
+ // Still not found. Now test subclasses.
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("FH.hR: test subclassess..."); // NOI18N
+ }
+
+ OID ssOID = DBInfo.getSubclassSetOID(clid);
+ SubclassSet ss = (SubclassSet)fodb.getIfExists(ssOID);
+ if (logger.isDebugEnabled()) {
+ logger.debug("FH.hR: subclassOID: " + ssOID); // NOI18N
+ }
+ if (null != ss) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FH.hR: SubclassSet exists for : " + clid); // NOI18N
+ }
+ for (Iterator i = ss.iterator(); i.hasNext();) {
+ CLID subCLID = (CLID)i.next();
+ tempOid = OID.create(subCLID, uid);
+ if (logger.isDebugEnabled()) {
+ logger.debug("FH.hR: looking for : " + tempOid); // NOI18N
+ }
+ block = (Block)fodb.getIfExists(tempOid);
+ if (block != null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FH.hR: exists: " + tempOid); // NOI18N
+ }
+
+ clid = subCLID;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (null == block) {
+ reply.setStatus(
+ Status.WARN,
+ msg.msg("EXC_DoesNotExist", oid.toString())); // NOI18N
+ } else {
+ if (logger.isTraceEnabled()) {
+ logger.trace("FR.reply data:"); // NOI18N
+ block.dump();
+ }
+ reply.write(block.getData());
+ reply.writeCLID(clid);
+ reply.setStatus(Status.OK);
+ }
+ } catch (FOStoreDatabaseException ex) {
+ reply.setStatus(Status.ERROR, ex);
+ }
+
+ return null;
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchRequest.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchRequest.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchRequest.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FetchRequest.java Sun May 22 11:40:13 2005
@@ -0,0 +1,137 @@
+/*
+ * 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.JDOUserException;
+import javax.jdo.JDOObjectNotFoundException;
+
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.state.StateManagerInternal;
+
+
+/**
+ * Represents a request to read the values of one or more fields for a
+ * persistent object from the store.
+ *
+ *
+ * @author Dave Bristor
+ */
+//
+// This is client-side code. It does not need to live in the server.
+//
+class FetchRequest extends AbstractRequest implements FieldRequest {
+ private final OID oid;
+ private final Object owner;
+ private final PersistenceManagerInternal pm;
+
+ FetchRequest(StateManagerInternal sm, Message m, FOStorePMF pmf) {
+ super(sm, m, pmf);
+
+ this.oid = (OID)sm.getInternalObjectId();
+ this.owner = sm; // Owner will be set to StateManagerInternal
+ this.pm = (PersistenceManagerInternal)sm.getPersistenceManager();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("FetchRequest: " + oid); // NOI18N
+ }
+ }
+
+ //
+ // Methods from AbstractRequest
+ //
+
+ protected void doRequestBody() throws IOException {
+ //
+ // The format of this request is (aside from the request header):
+ //
+ // oid: OID
+ // numFields: int
+ // fieldNum: int...
+ //
+
+ out.writeBoolean(pm.getStoreManager().hasActualPCClass(oid));
+ oid.write(out);
+
+ // XXX TBD Make use of the fieldNums (right now we fetch all
+ // fields). This will entail writing more output as per above.
+ }
+
+
+ //
+ // Methods from Request
+ //
+
+ public void handleReply(Status status, DataInput in, int length)
+ throws IOException {
+
+ //
+ // The format of this reply is
+ //
+ // className: String
+ // fieldsLength: int
+ // fieldValue: Object...
+ // numPairs: int
+ // CLID, classname pairs...
+ //
+ // The value types are as per the metadata, and are provided in the
+ // same order as that in which they were requested.
+ //
+
+ byte data[] = new byte[length];
+ if (logger.isDebugEnabled()) {
+ logger.debug("FR.hR: reading " + length + " bytes"); // NOI18N
+ }
+ in.readFully(data);
+
+ if (status.equals(Status.WARN)) {
+ String message = in.readUTF();
+ throw new JDOObjectNotFoundException(message);
+ }
+
+ ClassLoader loader = sm.getPCClass().getClassLoader();
+
+ FieldFetcher ff =
+ new FieldFetcher(new FOStoreInput(data, 0, length),
+ pmf.getModel(),
+ pm,
+ loader);
+ ff.fetch(sm, oid);
+ }
+
+
+ //
+ // Implement FieldRequest
+ //
+
+ /**
+ * Determines which fields (at least) will be read from the store. We say
+ * 'at least' because while we guarantee that the specified fields will be
+ * read, other fields may be read; this is implementation dependent.
+ * @param fieldNums Numbers of the fields which are to be read from the
+ * store.
+ */
+ public void setFieldNums(int fieldNums[]) { }
+
+ /**
+ * Adds to the set of fields that are to be manipulated.
+ * @param fieldNum Number of the field to be manipulated.
+ */
+ public void addFieldNum(int fieldNum) { }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldFetcher.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldFetcher.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldFetcher.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldFetcher.java Sun May 22 11:40:13 2005
@@ -0,0 +1,474 @@
+/*
+ * 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.JDOFatalUserException;
+import javax.jdo.JDOUserException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.model.jdo.JDOClass;
+import org.apache.jdo.model.jdo.JDOField;
+import org.apache.jdo.model.jdo.PersistenceModifier;
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.state.StateManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+* Extend AbstractFieldManager overriding only fetchABCField methods
+*
+* @author Dave Bristor
+*/
+class FieldFetcher extends AbstractFieldManager {
+ /** Read values from here. */
+ private final FOStoreInput fin;
+
+ /** PM on whose behalf we read */
+ private final PersistenceManagerInternal pm;
+
+ private final FOStoreModel model;
+
+ /** ClassLoader to use for loading the class of the instance. */
+ private final ClassLoader candidateLoader;
+
+ /** Class of instance being fetched. */
+ private Class cls;
+
+ //
+ // One of the follwing 2 fields, sm and oid, will be set at an entry to
+ // this object.
+ //
+
+ // StateManger for which we're reading data.
+ private StateManagerInternal sm = null;
+
+ // OID for which we're reading data.
+ private OID oid = null;
+
+ // OID provided for the request.
+ private OID oldOID = null;
+
+ // Last read field number
+ private int currNum = 0;
+
+ // Flag that enables actual field skip.
+ // If set to false only currNum is ignored.
+ private boolean skip = true;
+
+ /** 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
+
+ FieldFetcher(FOStoreInput fin,
+ FOStoreModel model,
+ PersistenceManagerInternal pm,
+ ClassLoader candidateLoader) {
+
+ this.fin = fin;
+ this.model = model;
+ this.pm = pm;
+ this.candidateLoader = candidateLoader;
+ this.skip = true;
+ }
+
+ /** Called by AID when PK fields are written sequentially
+ * independent of their actual field numbers.
+ */
+ FieldFetcher(FOStoreInput fin,
+ FOStoreModel model,
+ PersistenceManagerInternal pm,
+ ClassLoader candidateLoader,
+ boolean skip) {
+
+ this.fin = fin;
+ this.model = model;
+ this.pm = pm;
+ this.candidateLoader = candidateLoader;
+ this.skip = skip;
+ }
+
+ //
+ // Entry points
+ //
+
+ /**
+ * Invoke this if you have a StateManagerInternal for the object that
+ * you're fetching. For example, see FetchRequest.handleReply().
+ */
+ void fetch(StateManagerInternal sm, OID oid) throws IOException {
+ this.sm = sm;
+ this.oldOID = oid;
+ fetch();
+ }
+
+ /**
+ * Invoke this if you have an OID for the object that you're fetching.
+ * For example, see GetExtentRequest.handleReply().
+ */
+ StateManagerInternal fetch(OID oid) throws IOException {
+ this.oid = oid;
+ fetch();
+ return sm;
+ }
+
+
+ /**
+ * Fetches data from input, resulting in an PersistenceCapable object
+ * with state from the datastore. The format of the data is as per that
+ * described in InsertRequest.
+ */
+ private void fetch() throws IOException {
+ String className = fin.readUTF();
+ FOStoreSchemaUID fsuid = FOStoreSchemaUID.read(fin);
+ if (logger.isDebugEnabled()) {
+ logger.debug("FF.fetch/1: className=" + className + // NOI18N
+ ", fsuid=" + fsuid + ", oid=" + oid); // NOI18N
+ }
+
+ // Class of the instance that we are loading.
+ Class instanceClass = null;
+
+ // JDOClass corresponding to instanceClass.
+ JDOClass jdoClass = null;
+
+ // ClassLoader of the instance we are loading.
+ ClassLoader loader = null;
+
+ try {
+ instanceClass = pm.loadClass(className, candidateLoader);
+ jdoClass = model.getJDOClass(instanceClass);
+
+ FOStoreSchemaUID instanceClassFsuid =
+ FOStoreSchemaUID.lookup(instanceClass, model);
+ if ( ! instanceClassFsuid.equals(fsuid)) {
+ throw new JDOUserException(
+ msg.msg("EXC_FsuidMismatch", className)); // NOI18N
+ }
+ loader = instanceClass.getClassLoader();
+
+ // If we have an oid, we might not yet have the classname/CLID
+ // mapping. Make it so.
+ if (null != oid) {
+ CLID clid = oid.getCLID();
+ if (model.getClass(clid) == null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FF.fetch/1a: putting for " + // NOI18N
+ instanceClass.getName() + ", " + clid); // NOI18N
+ }
+ model.put(instanceClass, clid);
+ }
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new JDOUserException(
+ msg.msg("EXC_CannotLoadInstanceClass", className)); // NOI18N
+ }
+
+ // We need read the CLID/classname pairs *before* reading the data
+ // which contains fields using those CLID's, so that we can establish
+ // a mapping that the FieldFetcher (and StateManager) will use to
+ // create instances of those classes.
+ synchronized(fin) {
+ int fieldsLength = fin.readInt();
+ int fieldsPos = fin.getPos(); // Save for later
+ fin.advance(fieldsLength);
+
+ //
+ // Read the CLID/classname pairs, and make sure that we have
+ // both loaded the class and mapped the class to the CLID
+ //
+
+ int size = fin.readInt(); // number of CLID/classname pairs
+ for (int i = 0; i < size; i++) {
+ CLID clid = CLID.read(fin);
+ String fieldClassName = fin.readUTF();
+ FOStoreSchemaUID flduid = FOStoreSchemaUID.read(fin);
+
+ Class fieldClass = model.getClass(clid);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("FF.fetch/2: fieldClassName=" + // NOI18N
+ fieldClassName +
+ ", fieldClass=" + fieldClass + // NOI18N
+ ", " + clid + // NOI18N
+ ", flduid=" + flduid); // NOI18N
+ }
+
+ if (fieldClass != null) {
+ // The class is already loaded, just do a sanity check.
+ if (!fieldClassName.equals(fieldClass.getName())) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "handleReply", // NOI18N
+ msg.msg("ERR_ClassMismatch", // NOI18N
+ className,
+ fieldClassName,
+ fieldClass.getName()));
+ }
+ } else {
+ try {
+ fieldClass = pm.loadClass(fieldClassName, loader);
+
+ // If the FOStoreSchemaUID for fieldClass doesn't
+ // match flduid, then we've got a structural mismatch
+ // between the class in the database and the class in
+ // the current JVM.
+ if (!
+ flduid.equals(FOStoreSchemaUID.lookup(fieldClass, model))) {
+ throw new JDOUserException(
+ msg.msg(
+ "EXC_FsuidMismatch", fieldClassName)); // NOI18N
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FF.fetch/3: putting for " + // NOI18N
+ fieldClass.getName() +
+ ", " + jdoClass + // NOI18N
+ ", " + clid); // NOI18N
+ }
+ model.put(fieldClass, clid);
+ } catch (ClassNotFoundException ex) {
+ throw new JDOUserException(
+ msg.msg("EXC_CannotLoadFieldClass", // NOI18N
+ className, fieldClassName));
+ }
+ }
+ }
+
+ // sm will be null if we were invoked via the "fetch(oid)" entry
+ // point. In that case, pm.getStateManager(oid) is only safe
+ // once we have gone through the above CLID/classname mapping.
+ if (null == sm) {
+ sm = pm.getStateManager(oid, instanceClass);
+ sm.setPCClass(instanceClass); // this will be a no-op if sm is replaced above.
+ } else {
+ // It may be the case when StateManager did not know the
+ // actual type of the instance Class (application identity)
+ // Read the actual CLID from the stream.
+ CLID newCLID = CLID.read(fin);
+ if (oldOID != null && !oldOID.isDataStoreIdentity()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FF.fetch: check OID=" + oldOID + " for SM=" + sm); // NOI18N
+ }
+ long uid = oldOID.getUID();
+ CLID clid = oldOID.getCLID();
+ if (!newCLID.equals(clid)) {
+ FOStorePMF pmf = (FOStorePMF)pm.getPersistenceManagerFactory();
+ oldOID.replaceProvisionalOIDWithReal(OID.create(newCLID, uid), null, null);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FF.fetch: new OID=" + oldOID + ", SM=" + sm); // NOI18N
+ }
+ }
+ }
+ sm.setPCClass(instanceClass); // this will be a no-op if sm is replaced above.
+ }
+
+ // Save this end-of-data position for later use
+ int endPos = fin.getPos();
+
+ // Set the stream's position for reading data values, and get
+ // them.
+ fin.setPos(fieldsPos);
+
+ // XXX We should be using the field numbers as given to FetchRequest.
+ int fields[] = jdoClass.getPersistentFieldNumbers();
+ int numFields = fields.length;
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FF.fetch/4: numFields=" + numFields); // NOI18N
+ }
+ currNum = 0;
+ cls = sm.getPCClass();
+ sm.replace(fields, this);
+
+ fin.setPos(endPos);
+ }
+ }
+
+ void setPCClass(Class pcClass) {
+ cls = pcClass;
+ }
+
+ public boolean fetchBooleanField(int fieldNum) {
+ boolean rc = false;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchBoolean(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchBooleanField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public char fetchCharField(int fieldNum) {
+ char rc = ' ';
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchChar(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchCharField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public byte fetchByteField(int fieldNum) {
+ byte rc = 0;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchByte(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchByteField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public short fetchShortField(int fieldNum) {
+ short rc = 0;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchShort(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchShortField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public int fetchIntField(int fieldNum) {
+ int rc = 0;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchInt(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchIntField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public long fetchLongField(int fieldNum) {
+ long rc = 0L;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchLong(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchLongField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public float fetchFloatField(int fieldNum) {
+ float rc = 0.0F;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchFloat(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchFloatField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public double fetchDoubleField(int fieldNum) {
+ double rc = 0.0;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchDouble(fin);
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "fetchDoubleField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public String fetchStringField(int fieldNum) {
+ String rc = ""; // NOI18N
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ // Need to pass all correct parameters as this can be
+ // a nested request and we don't want to override important
+ // info with null's.
+ rc = (String)t.fetchObject(fin, sm, fieldNum, pm);
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ this.getClass(), "fetchStringField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ public Object fetchObjectField(int fieldNum) {
+ Object rc = null;
+
+ skipFields(fieldNum);
+ FOStoreTranscriber t = model.getTranscriber(cls, fieldNum);
+ try {
+ rc = t.fetchObject(fin, sm, fieldNum, pm);
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ this.getClass(), "fetchObjectField", ex); // NOI18N
+ }
+ return rc;
+ }
+
+ private void skipFields(int fieldNum) {
+ if (skip) {
+ while(currNum < fieldNum) {
+ FOStoreTranscriber t = model.getTranscriber(cls, currNum);
+ try {
+ t.skip(fin);
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ this.getClass(), "skipFields", ex); // NOI18N
+ }
+ currNum++;
+ }
+ currNum++; // for the next time.
+ } // do nothing otherwise.
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldRequest.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldRequest.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldRequest.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FieldRequest.java Sun May 22 11:40:13 2005
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * Represents a request to manipulate (read or update) the fields of an
+ * object.
+ *
+ * @author Dave Bristor
+ */
+interface FieldRequest extends Request {
+ /**
+ * Indicates which fields are to be manipulated in the object.
+ * @param fieldNums The set of field numbers indicating the fields that
+ * are to be manipulated.
+ */
+ public void setFieldNums(int fieldNums[]);
+
+ /**
+ * Adds to the set of fields that are to be manipulated.
+ * @param fieldNum Number of the field to be manipulated.
+ */
+ public void addFieldNum(int fieldNum);
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FloatTranscriber.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FloatTranscriber.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FloatTranscriber.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FloatTranscriber.java Sun May 22 11:40:13 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 float values.
+*
+* @author Dave Bristor
+*/
+class FloatTranscriber extends FOStoreTranscriber {
+ private static FloatTranscriber instance = new FloatTranscriber();
+
+ private FloatTranscriber() {}
+
+ static FloatTranscriber getInstance() {
+ return instance;
+ }
+
+ void storeFloat(float value, DataOutput out) throws IOException {
+ out.writeFloat(value);
+ }
+
+ float fetchFloat(DataInput in) throws IOException {
+ return in.readFloat();
+ }
+
+ void skip(DataInput in) throws IOException {
+ in.readFloat();
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassHandler.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassHandler.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassHandler.java Sun May 22 11:40:13 2005
@@ -0,0 +1,95 @@
+/*
+ * 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 javax.jdo.JDOUserException;
+
+import org.apache.jdo.util.I18NHelper;
+
+/**
+* Process GetClass requests.
+*
+* @author Dave Bristor
+*/
+// This is server-side code. It does not need to live in the client.
+class GetClassHandler extends RequestHandler {
+
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+ private GetClassHandler(Reply reply, int length,
+ FOStoreServerConnection con) {
+
+ super(reply, length, con);
+ }
+
+ public static final HandlerFactory factory =
+ new HandlerFactory() {
+ public RequestHandler getHandler(Reply reply, int length,
+ FOStoreServerConnection con) {
+ return new GetClassHandler(reply, length, con);
+ }};
+
+ RequestFinisher handleRequest()
+ throws IOException, FOStoreDatabaseException {
+
+ DataInput in = con.getInputFromClient();
+ FOStoreDatabase db = con.getDatabase();
+ CLID clid = CLID.read(in);
+
+ OID oid = db.getDBInfo().getDBClassOID(clid);
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "GetClassHandler.hR/0: " + clid + // NOI18N
+ " " + Tester.toHex(clid.getId(), 8) + ", " + oid + // NOI18N
+ " " + Tester.toHex(oid.oid, 16)); // NOI18N
+ }
+
+ FOStoreDatabase fodb = con.getDatabase();
+ try {
+ DBClass dbClass = (DBClass)fodb.getIfExists(oid);
+ if (null == dbClass) {
+ reply.setStatus(
+ Status.ERROR,
+ msg.msg("EXC_DoesNotExist", oid.toString())); // NOI18N
+ } else {
+ String className = dbClass.getName();
+ reply.writeUTF(className);
+ reply.setStatus(Status.OK);
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "GetClassHandler.hR/1: " + className); // NOI18N
+ }
+ }
+
+ } catch (ClassCastException ex) {
+ reply.setStatus(Status.ERROR, ex);
+ }
+
+ return null;
+ }
+}
+
+
+
+
+
+
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassRequest.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassRequest.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassRequest.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/GetClassRequest.java Sun May 22 11:40:13 2005
@@ -0,0 +1,93 @@
+/*
+ * 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.JDOUserException;
+
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+ * Represents a request to get the java.lang.Class corresponding to a CLID.
+ *
+ * @author Dave Bristor
+ */
+//
+// This is client-side code. It does not need to live in the server.
+//
+class GetClassRequest extends AbstractRequest {
+ /** The CLID of the class sought by this request. */
+ private final CLID clid;
+
+ /** PersistenceManagerInternal used to load the class. */
+ private final PersistenceManagerInternal pm;
+
+ /** The Class sought by this request. */
+ private Class classForCLID;
+
+ GetClassRequest(CLID clid, Message m,
+ FOStorePMF pmf, PersistenceManagerInternal pm) {
+ super(m, pmf);
+ this.clid = clid;
+ this.classForCLID = null;
+ this.pm = pm;
+ }
+
+ protected void doRequestBody() throws IOException {
+ clid.write(out);
+ if (logger.isDebugEnabled()) {
+ logger.debug("GetClassRequest.dRB: " + clid); // NOI18N
+ }
+ }
+
+ public void handleReply(Status status, DataInput in, int length)
+ throws IOException {
+
+ String className = in.readUTF();
+ if (logger.isDebugEnabled()) {
+ logger.debug("GetClassRequest.hR: className=" + className // NOI18N
+ + " status=" + status); // NOI18N
+ }
+ // className is valid if not empty and request succeeded.
+ if (null != className
+ && className.length() > 0
+ && Status.OK.equals(status)) {
+
+ try {
+ classForCLID = pm.loadClass(className, null);
+ // Bind in the metadata
+ FOStoreModel model = pmf.getModel();
+ model.put(classForCLID, clid);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("GetClassRequest.hR: classForCLID=" + classForCLID); // NOI18N
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new JDOUserException(
+ msg.msg("EXC_NoClassForCLID", clid, ex)); // NOI18N
+ }
+ }
+ }
+
+ Class getClassForCLID() {
+ return classForCLID;
+ }
+}