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 [5/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/FOStoreConnector.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreConnector.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreConnector.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreConnector.java Sun May 22 11:40:13 2005
@@ -0,0 +1,277 @@
+/*
+ * 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.IOException;
+
+import javax.jdo.JDOException;
+import javax.jdo.JDODataStoreException;
+import javax.jdo.JDOFatalInternalException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.store.Connector;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+* FOStoreConnector represents a connection to the FOStoreDatabase.
+*
+* @author Dave Bristor
+*/
+class FOStoreConnector implements Connector {
+ /** @see org.apache.jdo.store.Connector#setRollbackOnly */
+ private boolean rollbackOnly = false;
+
+ /** 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
+
+ /**
+ * Message in which this Connector buffers requests for the store.
+ */
+ private final Message message;
+
+ /**
+ * Datasource to which this Connector writes its Message.
+ */
+ private final FOStorePMF pmf;
+
+ /**
+ * Connection for interacting with store.
+ */
+ FOStoreClientConnection connection = null;
+
+ /**
+ * True if we can release this connection after flushing. By default we
+ * can; affected by transactions beginning and ending and their types.
+ */
+ private boolean okToReleaseConnection = true;
+
+ /** True if flush is in progress. */
+ private boolean busy = false;
+
+ FOStoreConnector(FOStorePMF pmf) {
+ this.pmf = pmf;
+ this.message = new Message(this);
+ }
+
+ //
+ // Implement Connector
+ //
+
+ /**
+ * @see org.apache.jdo.store.Connector#begin
+ */
+ public void begin(boolean optimistic) {
+ assertNotRollbackOnly();
+
+ // If transaction is optimistic, then we can release the connection as
+ // soon as data is flushed. If it's datastore, then we can't release
+ // the connection until after commit/rollback.
+ this.okToReleaseConnection = optimistic;
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOConnector.begin: okToReleaseConnection=" + // NOI18N
+ okToReleaseConnection);
+ }
+
+ try {
+ RequestFactory rf = pmf.getRequestFactory();
+ BeginTxRequest request =
+ rf.getBeginTxRequest(message, pmf, 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
+ }
+ }
+
+ /**
+ * @see org.apache.jdo.store.Connector#beforeCompletion
+ */
+ public void beforeCompletion() {
+ assertNotRollbackOnly();
+
+ // Nothing to do.
+ }
+
+ /**
+ * Get a connection, process the message by using that connection to
+ * interact with the database, read back the reply, release the
+ connection.
+ * @see org.apache.jdo.store.Connector#flush
+ */
+ public void flush() {
+ assertNotRollbackOnly();
+ assertNotBusy("flush"); // NOI18N
+ busy = true;
+
+ try {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOConnector.flush: " + // NOI18N
+ "okToReleaseConnection=" + okToReleaseConnection + // NOI18N
+ ", connection=" + connection); // NOI18N
+ }
+
+ if (message.hasRequests()) {
+ if (logger.isTraceEnabled()) message.dump();
+
+ if (connection == null) {
+ FOStoreConnectionFactory cf =
+ (FOStoreConnectionFactory)pmf.getConnectionFactory();
+ connection = (FOStoreClientConnection)cf.getConnection();
+ }
+
+ // Now send the message and process it in the store
+ try {
+ message.processInStore(connection, okToReleaseConnection);
+ } finally {
+ if (okToReleaseConnection) {
+ connection = null;
+ }
+ }
+ }
+ } finally {
+ busy = false;
+ }
+ }
+
+ /**
+ * Add a CommitRequest to the connector's message, and send it to the
+ * store. Then close the connection.
+ * @see org.apache.jdo.store.Connector#commit
+ */
+ public synchronized void commit() {
+ assertNotRollbackOnly();
+ assertNotBusy("commit"); // NOI18N
+
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOConnector.commit"); // NOI18N
+ }
+
+ RequestFactory rf = pmf.getRequestFactory();
+ CommitRequest request = rf.getCommitRequest(message, pmf);
+
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "commit", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "commit", ex); // NOI18N
+ } finally {
+ // Now that we've commited, we can release the connection.
+ okToReleaseConnection = true;
+ flush();
+ }
+ }
+
+ /**
+ * If rollbackOnly is set, then the store has already done a
+ * rollback, so we don't do one now (but neither do we throw an
+ * exception, as do other methds).
+ * @see org.apache.jdo.store.Connector#rollback
+ * @see org.apache.jdo.impl.fostore.ReplyHandler#processReplies
+ */
+ public synchronized void rollback() {
+ assertNotBusy("rollback"); // NOI18N
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOConnector.rollback, RBO=" + rollbackOnly); // NOI18N
+ }
+
+ if (! rollbackOnly) {
+ try {
+ RequestFactory rf = pmf.getRequestFactory();
+ RollbackRequest request = rf.getRollbackRequest(message, pmf);
+
+ request.doRequest();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ this.getClass(), "rollback", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "rollback", ex); // NOI18N
+ } finally {
+ // Now that we've rolled back, we can release the connection.
+ okToReleaseConnection = true;
+ flush();
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.jdo.store.Connector#setRollbackOnly
+ */
+ public void setRollbackOnly() {
+ rollbackOnly = true;
+ }
+
+ /**
+ * @see org.apache.jdo.store.Connector#getRollbackOnly
+ */
+ public boolean getRollbackOnly() {
+ return rollbackOnly;
+ }
+
+ //
+ // Implementation
+ //
+
+ /**
+ * Provides the Message which this this connector uses to send data to the
+ * store.
+ */
+ Message getMessage() {
+ assertNotRollbackOnly();
+ assertNotBusy("getMessage"); // NOI18N
+
+ return message;
+ }
+
+ private void assertNotRollbackOnly() {
+ if (rollbackOnly) {
+ throw new JDODataStoreException(
+ msg.msg("EXC_RollbackOnly")); // NOI18N
+ }
+ }
+
+ private void assertNotBusy(String methodName) {
+ if (busy) {
+ throw new FOStoreFatalInternalException(
+ getClass(), methodName,
+ msg.msg("EXC_Busy")); // NOI18N
+ }
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabase.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabase.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabase.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabase.java Sun May 22 11:40:13 2005
@@ -0,0 +1,574 @@
+/*
+ * 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.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.File;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.util.Set;
+import java.util.HashMap;
+
+import javax.jdo.JDOFatalUserException;
+import javax.jdo.JDOFatalException;
+import javax.jdo.JDOFatalDataStoreException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.util.I18NHelper;
+import org.apache.jdo.util.Pool;
+import org.netbeans.mdr.persistence.Storage;
+import org.netbeans.mdr.persistence.SinglevaluedIndex;
+import org.netbeans.mdr.persistence.StorageBadRequestException;
+import org.netbeans.mdr.persistence.StorageException;
+import org.netbeans.mdr.persistence.Streamable;
+
+/**
+* File/Object Store Database, using an underlying Btree implementation.
+*
+* @author Dave Bristor
+*/
+class FOStoreDatabase {
+
+ /** We manage a map of pools of databases by database name.
+ */
+ private static final HashMap databaseMap = new HashMap();
+
+ private static final int poolSize = 1;
+
+ // We delegate all calls to this storage. Not final, because for
+ // rollback's sake we have to close and then make a new storage.
+ private FOStoreBtreeStorage storage;
+
+ // Map from provisional IDs to real, datastore-created, durable IDs.
+ //
+ // XXX TBD Remote: Provisional CLID's are per client (PMF).
+ // That is because each client will independently generate its
+ // own set of provisional ID's. One way to manage this might be for
+ // each client to send a "hello" message when it first connects, with
+ // something like it's IP address and process id. Future communications
+ // from that same client will contain that same info. A "goodbye" message
+ // would be nice, too, so that the store can remove any tables that will
+ // not ever be used again.
+ private final HashMap provisionalCLIDs = new HashMap();
+
+ // Same as above, but for OIDs.
+ private final HashMap provisionalOIDs = new HashMap();
+
+ /** Count the number of connections open on this database. When the last
+ * connection closes, then really close the database.
+ */
+ private int openConnections = 0;
+
+ private DBInfo dbInfo = null;
+ /** Pool for this database.
+ */
+ private Pool pool = null;
+
+ /** 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
+
+ /** Find an open database of the given name. If it is not already open,
+ * open it and put it into the pool.
+ */
+ public synchronized static FOStoreDatabase getDatabase (String dbname,
+ boolean create)
+ throws InterruptedException, FOStoreDatabaseException {
+ Pool pool = (Pool) databaseMap.get(dbname);
+ FOStoreDatabase db = null;
+ if (pool == null) {
+ try {
+ db = new FOStoreDatabase (dbname, create);
+ } catch (FOStoreDatabaseException fode) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FODB:getDatabase exception for new database " + // NOI18N
+ dbname + " create: " + create); // NOI18N
+ }
+ throw (fode);
+ }
+ pool = new Pool (poolSize);
+ databaseMap.put (dbname, pool);
+ pool.put (db);
+ db.setPool(pool);
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("FODB:getDatabase found pool for database " + dbname); // NOI18N
+ }
+ db = (FOStoreDatabase) pool.get();
+ return db;
+ }
+
+ /** Release the database for other connections to use.
+ */
+ public synchronized static void releaseDatabase (FOStoreDatabase db)
+ throws InterruptedException {
+
+ db.pool.put (db);
+ }
+
+ /**
+ * Create an FODatabase and create/open the files.
+ * @param name name of database, which is used to name the files
+ * @param isNew true if the database is being created
+ */
+ FOStoreDatabase(String name, boolean isNew)
+ throws FOStoreDatabaseException {
+ // first verify that the directory exists
+ // if not, there is no way to continue
+ // Note, the filename might include a mixture of \ and / as
+ // path separator, make them all / for the lookup
+ int slashIndex = name.replace('\\', '/').lastIndexOf('/');
+ if (slashIndex != -1) { // at least one / in pathname
+ String dirName = name.substring(0, slashIndex);
+ File dir = new File(dirName); // NOI18N
+ if (!existsFile(dir)) {
+ throw new JDOFatalDataStoreException (
+ msg.msg("ERR_DirectoryDoesNotExist", name)); // NOI18N
+ }
+ }
+ // XXX the DBInfo is not a singleton; change this code
+ // and DBInfo to support multiple Databases in one VM.
+ if (isNew) {
+ // We must remove a database if one does exist. This means delete
+ // both the .btd and .btx files.
+ String extensions[] = {"btd", "btx"}; // NOI18N
+ boolean found = false;
+ for (int i = 0; i < extensions.length; i++) {
+ File f = new File(name + "." + extensions[i]); // NOI18N
+ if (existsFile(f)) {
+ if (! found) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FODB: Deleting existing database " +
+ name); // NOI18N
+ }
+ found = true;
+ }
+ deleteFile(f);
+ }
+ }
+ storage = createBtreeStorage(name, true);
+ dbInfo = new DBInfo(this);
+ dbInfo.store();
+ commitChanges();
+ if (logger.isDebugEnabled()) {
+ logger.debug("FODB: Created database " + name); // NOI18N
+ }
+ } else {
+ storage = createBtreeStorage(name, false);
+ dbInfo = DBInfo.get(this);
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FODB: Opened existing database " + name); // NOI18N
+ }
+ }
+ }
+
+ /** Verify that this user is authorized to use this database.
+ */
+ public void verifyUserPassword (String user, long timestamp, byte[] secret) {
+ // XXX look up Authentication objects and verify this user is authorized.
+ addConnection();
+ }
+
+ /** Get the DBInfo for this database.
+ */
+ public DBInfo getDBInfo() {
+ return dbInfo;
+ }
+
+ /** Associates the specified value with the specified key in this index.
+ * @return true if there was an item in this index that was associated
+ * with the key prior to this call
+ * @param key
+ * @param value
+ * @throws FOStoreDatabaseException
+ */
+ public boolean put(OID key, Object value) throws FOStoreDatabaseException {
+ try {
+ Object keyValue = key.keyValue(storage);
+// Uncomment the next lines to simulate a fatal error during login.
+// if (null != keyValue)
+// throw new NullPointerException("fodb: NPE on purpose"); // YYY
+ return storage.getPrimaryIndex().put(keyValue, value);
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ /** Replaces the original value associated with the specified key in this
+ * index with new value. If no value was associated with this key prior
+ * to this call StorageBadRequestException is thrown.
+ * @param key
+ * @param value
+ * @throws FOStoreDatabaseException
+ */
+ public void replace(OID key, Object value)
+ throws FOStoreDatabaseException {
+
+ try {
+ Object keyValue = key.keyValue(storage);
+ storage.getPrimaryIndex().replace(keyValue, value);
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ /** Returns the value to which this index maps the specified key.
+ * StorageBadRequestException is thrown if there is no value for the key.
+ * @return value associated with specified key
+ * @param key
+ * @throws FOStoreDatabaseException
+ */
+ public Object get(OID key)
+ throws FOStoreDatabaseException {
+
+ try {
+ Object keyValue = key.keyValue(storage);
+ return storage.getPrimaryIndex().get(keyValue);
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ /** Returns the value to which this index maps the specified key
+ * or null if there is no value for this key.
+ * @return value associated with specified key or null
+ * @param key
+ * @throws FOStoreDatabaseException
+ */
+ public Object getIfExists (OID key) throws FOStoreDatabaseException {
+ try {
+ Object keyValue = key.keyValue(storage);
+ return storage.getPrimaryIndex().getIfExists(keyValue);
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ /** Returns the unique name of the index in the Storage.
+ * @return The name of this index.
+ */
+ public String getName() {
+ return storage.getName();
+ }
+
+ /** Returns a set view of the keys contained in this index.
+ * Returned set is read only and may not be modified.
+ * @return keys contained in this index
+ * @throws FOStoreDatabaseException
+ */
+ public Set keySet() throws FOStoreDatabaseException {
+ try {
+ return storage.getPrimaryIndex().keySet();
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ /** Adds the specified value to values associated in this index with the
+ * specified key. If the index puts limit on number of values associated
+ * with one key and adding value would break this limit, it thorows
+ * StorageBadRequestException.
+ * @param key
+ * @param value
+ * @throws FOStoreDatabaseException
+ */
+ public void add(OID key, Object value) throws FOStoreDatabaseException {
+ try {
+ Object keyValue = key.keyValue(storage);
+ storage.getPrimaryIndex().add(keyValue, value);
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ /** Removes all values assosiated in the index with specified key.
+ * @return true if this index changed as a result of this call
+ * @param key
+ * @throws FOStoreDatabaseException
+ */
+ public boolean remove (OID key) throws FOStoreDatabaseException {
+ try {
+ Object keyValue = key.keyValue(storage);
+ return storage.getPrimaryIndex().remove(keyValue);
+ } catch (StorageException ex) {
+ throw new FOStoreDatabaseException(ex);
+ }
+ }
+
+ public void commitChanges() throws FOStoreDatabaseException {
+ if (logger.isDebugEnabled()) logger.debug("FODB.commitChanges"); // NOI18N
+
+ // Need to have privileges to perform this operation.
+ final FOStoreBtreeStorage storage1 = storage;
+ try {
+ AccessController.doPrivileged (
+ new PrivilegedExceptionAction () {
+ public Object run () throws StorageException {
+ storage1.commitChanges();
+ return null;
+ }
+ }
+ );
+ } catch (PrivilegedActionException ex) {
+ throw new FOStoreDatabaseException(
+ (StorageException)ex.getException());
+ }
+
+ }
+
+ /** Increment the openConnections to allow proper close when the last
+ * connection closes the database.
+ */
+ public synchronized void addConnection() {
+ openConnections++;
+ }
+
+ /** Decrement the open connections counter and close the database when
+ * it reaches zero.
+ */
+ public synchronized void close() throws FOStoreDatabaseException {
+ if (--openConnections > 0) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FODB.close: " + getName() + // NOI18N
+ " count still " + openConnections); // NOI18N
+ }
+ try {
+ releaseDatabase(this);
+ } catch (InterruptedException ex) {
+ // ignore
+ }
+ return;
+ }
+ // count has reached zero. Now really close the database.
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FODB.close: count reached zero." + getName()); // NOI18N
+ }
+
+ closeBtreeStorage(storage);
+ databaseMap.remove(getName());
+ pool = null;
+ }
+
+ public static synchronized void closeDatabase (String dbname)
+ throws FOStoreDatabaseException, InterruptedException {
+
+ Pool pool = (Pool) databaseMap.get(dbname);
+ if (pool == null) {
+ throw new JDOFatalDataStoreException (
+ msg.msg("ERR_CloseDatabase", dbname)); // NOI18N
+ }
+ FOStoreDatabase fodb = (FOStoreDatabase) pool.get();
+ fodb.close();
+ }
+
+ public void rollbackChanges() throws FOStoreDatabaseException {
+ if (logger.isDebugEnabled()) logger.debug("FODB.rollbackChanges"); // NOI18N
+
+ // The btree doesn't *really* rollback. But closing it and
+ // getting a new one works fine.
+ final String name = storage.getName();
+ closeBtreeStorage(storage);
+
+ storage = createBtreeStorage(name, false);
+ dbInfo = DBInfo.get(this);
+ }
+
+ static Block createBlock(FOStoreInput in, int length) {
+ return new Block(in, length);
+ }
+
+ /**
+ * Establishes a mapping in this database from provisional to real
+ * CLIDs. The mapping lasts as long as the server is running, that is, it
+ * is not durable.
+ * @param pCLID A provisional CLID.
+ * @param rCLID The non-provisional, datastore CLID corresponding to
+ * provCLID.
+ * @exception JDOFatalException Thrown if the given CLID is not provisional.
+ */
+ // If you change this code, please see also method of same name in FOStorePMF.
+ public synchronized void mapProvisionalCLIDToReal(
+ CLID pCLID, CLID rCLID) {
+
+ if (! pCLID.isProvisional()) {
+ throw new JDOFatalException(msg.msg("ERR_CLIDNotProv", pCLID)); // NOI18N
+ }
+ if (null == provisionalCLIDs.get(pCLID)) {
+ provisionalCLIDs.put(pCLID, rCLID);
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FODB.mapProvCLIDToReal: " + pCLID + " -> " + rCLID); // NOI18N
+ }
+ }
+
+ /**
+ * Provides a datastore CLID corresponding to the given provisional CLID.
+ * @param provCLID A provisional CLID for which there
+ * @return A non-provisional, datastore CLID corresponding to provCLID, or
+ * null if the given provCLID is not mapped to a datastore CLID.
+ * @exception JDOFatalException Thrown if the given CLID is not provisional.
+ */
+ // If you change this code, see method of same name in FOStorePMF.
+ public CLID getRealCLIDFromProvisional(CLID provCLID) {
+ if (! provCLID.isProvisional()) {
+ throw new JDOFatalException(msg.msg("ERR_CLIDNotProv", provCLID)); // NOI18N
+ }
+ return (CLID)provisionalCLIDs.get(provCLID);
+ }
+
+ /**
+ * Establishes a mapping in this database from provisional to real
+ * OIDs. The mapping lasts as long as the server is running, that is, it
+ * is not durable.
+ * @param pOID A provisional OID.
+ * @param rOID The non-provisional, datastore OID corresponding to
+ * pOID.
+ * @exception JDOFatalException Thrown if the given OID is not provisional.
+ */
+ // If you change this code, please see also method of same name in FOStorePMF.
+ synchronized void mapProvisionalOIDToReal(
+ OID pOID, OID rOID) {
+
+ if (! pOID.isProvisional()) {
+ throw new JDOFatalException(msg.msg("ERR_OIDNotProv", pOID)); // NOI18N
+ }
+ if (null == provisionalOIDs.get(pOID)) {
+ provisionalOIDs.put(pOID, rOID);
+ }
+ }
+
+ /**
+ * Provides a datastore OID corresponding to the given provisional OID.
+ * @param pOID A provisional OID for which there
+ * @return A non-provisional, datastore OID corresponding to pOID or null
+ * if the given pOID is not mapped to a datastore OID.
+ * @exception JDOFatalException Thrown if the given OID is not provisional.
+ */
+ // If you change this code, see method of same name in FOStorePMF.
+ OID getRealOIDFromProvisional(OID pOID) {
+ if (! pOID.isProvisional()) {
+ throw new JDOFatalException(msg.msg("ERR_OIDNotProv", pOID)); // NOI18N
+ }
+ return (OID)provisionalOIDs.get(pOID);
+ }
+
+ private void setPool (Pool pool) {
+ this.pool = pool;
+ }
+
+ /**
+ * Helper method to create a BtreeStorage. This method excutes the
+ * storage operation in a doPrivileged block and handles possible
+ * exceptions.
+ * @param name name of database, which is used to name the files
+ * @param isNew true if the database is being created
+ * @return new database
+ * @exception FOStoreDatabaseException wraps a StorageException thrown
+ * by the create call.
+ * @exception JDOFatalUserException wraps a possible SecurityException.
+ */
+ private FOStoreBtreeStorage createBtreeStorage(final String name,
+ final boolean isNew)
+ throws FOStoreDatabaseException, JDOFatalUserException
+ {
+ try {
+ return (FOStoreBtreeStorage) AccessController.doPrivileged (
+ new PrivilegedExceptionAction () {
+ public Object run () throws StorageException {
+ return new FOStoreBtreeStorage(name, isNew);
+ }
+ });
+ } catch (SecurityException ex) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_SecurityExceptionOnCreateBtreeStorage"), ex); //NOI18N
+ } catch (PrivilegedActionException ex) {
+ throw new FOStoreDatabaseException(
+ (StorageException)ex.getException());
+ }
+ }
+
+ /**
+ * Helper method to close a BtreeStorage.
+ * @param storage the database to be closed
+ * @exception FOStoreDatabaseException wraps a StorageException thrown
+ * by the close call.
+ */
+ private void closeBtreeStorage(final FOStoreBtreeStorage storage)
+ throws FOStoreDatabaseException
+ {
+ try {
+ AccessController.doPrivileged (
+ new PrivilegedExceptionAction () {
+ public Object run () throws StorageException {
+ storage.shutDown();
+ storage.close();
+ return null;
+ }
+ });
+ } catch (SecurityException ex) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_SecurityExceptionOnCloseBtreeStorage"), ex); //NOI18N
+ } catch (PrivilegedActionException ex) {
+ throw new FOStoreDatabaseException(
+ (StorageException)ex.getException());
+ }
+ }
+
+ /**
+ * Helper method to check whether a file exists. This method delegates
+ * to File.exists and handles possible SecurityExceptions.
+ * @param file the file to be checked
+ * @return <code>true</code> if the specified file exists.
+ */
+ private boolean existsFile(File file) {
+ try {
+ return file.exists();
+ } catch (SecurityException ex) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_CannotReadFile", file.getName()), ex); //NOI18N
+ }
+ }
+
+ /**
+ * Helper method to delete a file. This method delegates to File.delete
+ * and handles possible SecurityExceptions.
+ * @param file the file to be deleted
+ */
+ private void deleteFile(File file) {
+ try {
+ file.delete();
+ } catch (SecurityException ex) {
+ throw new JDOFatalUserException(msg.msg(
+ "EXC_CannotDeleteFile", file.getName()), ex); //NOI18N
+ }
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabaseException.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabaseException.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabaseException.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreDatabaseException.java Sun May 22 11:40:13 2005
@@ -0,0 +1,56 @@
+/*
+ * 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 org.netbeans.mdr.persistence.StorageException;
+
+/**
+* This provides an insulation layer between BtreeDatabase and FOStore.
+*
+* @author Dave Bristor
+*/
+class FOStoreDatabaseException extends StorageException {
+ private final StorageException ex;
+
+ FOStoreDatabaseException(StorageException ex) {
+ this.ex = ex;
+ }
+
+ public String getLocalizedMessage() {
+ return ex.getLocalizedMessage();
+ }
+
+ public String getMessage() {
+ return ex.getMessage();
+ }
+
+ public void printStackTrace() {
+ ex.printStackTrace();
+ }
+
+ public void printStackTrace(java.io.PrintStream s) {
+ ex.printStackTrace(s);
+ }
+
+ public void printStackTrace(java.io.PrintWriter s) {
+ ex.printStackTrace(s);
+ }
+
+ public String toString() {
+ return ex.toString();
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreExtent.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreExtent.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreExtent.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreExtent.java Sun May 22 11:40:13 2005
@@ -0,0 +1,304 @@
+/*
+ * 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.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.jdo.Extent;
+import javax.jdo.JDOHelper;
+import javax.jdo.JDOException;
+import javax.jdo.JDOUserException;
+import javax.jdo.PersistenceManager;
+import javax.jdo.Transaction;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.state.StateManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+ * Represents a request to get the extent of a class and possibly its
+ * subclasses.
+ *
+ * @author Dave Bristor
+ */
+//
+// This is client-side code. It does not need to live in the server.
+//
+/**
+ * This is an in-memory extent.
+ */
+class FOStoreExtent implements Extent {
+private final FOStoreConnector connector;
+private final RequestFactory rf;
+
+ /** Iterators requested by user. */
+ private final HashSet iterators = new HashSet();
+
+ /** Class specified by user. */
+ private final Class cls;
+
+ /** If true, extent includes subclasses of user's class. */
+ private final boolean subclasses;
+
+ /** Persistence manager on which getExtent was invoked by user. */
+ private final PersistenceManagerInternal pm;
+
+ /** 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
+
+ FOStoreExtent(Class cls, boolean subclasses,
+ PersistenceManagerInternal pm,
+ RequestFactory rf,
+ FOStoreConnector connector) {
+
+ this.cls = cls;
+ this.subclasses = subclasses;
+ this.pm = pm;
+ this.rf = rf;
+ this.connector = connector;
+ }
+
+ //
+ // Implement Extent
+ //
+
+ /**
+ * @see javax.jdo.Extent#iterator
+ */
+ public Iterator iterator() {
+ pm.assertReadAllowed();
+ Iterator rc = new FOStoreExtentIterator(this);
+ iterators.add(rc);
+ return rc;
+ }
+
+ /**
+ * @see javax.jdo.Extent#hasSubclasses
+ */
+ public boolean hasSubclasses() {
+ return subclasses;
+ }
+
+ /**
+ * @see javax.jdo.Extent#getCandidateClass
+ */
+ public Class getCandidateClass() {
+ return cls;
+ }
+
+ /**
+ * @see javax.jdo.Extent#getPersistenceManager
+ */
+ public PersistenceManager getPersistenceManager() {
+ return pm.getCurrentWrapper();
+ }
+
+ /**
+ * @see javax.jdo.Extent#closeAll
+ */
+ public void closeAll() {
+ for (Iterator i = iterators.iterator(); i.hasNext();) {
+ Iterator extentIterator = (Iterator)i.next();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Extent.closeAll: removing " + extentIterator); // NOI18N
+ }
+ i.remove(); // remove first because close also removes it
+ close(extentIterator);
+ }
+ }
+
+ /**
+ * @see javax.jdo.Extent#close
+ */
+ public void close(Iterator it) {
+ if (it instanceof FOStoreExtentIterator) {
+ FOStoreExtentIterator fit = (FOStoreExtentIterator)it;
+ fit.close();
+ if (iterators.contains(fit)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Extent.close: removing " + fit); // NOI18N
+ }
+ // this will be true only if not executing closeAll.
+ iterators.remove(fit);
+ }
+ }
+ }
+
+ /**
+ * Iterates over the elements in a FOStoreExtent.
+ */
+ class FOStoreExtentIterator implements Iterator {
+ /** Instances that have been retrieved from store. */
+ // We have our own copy and do not use those from the enclosing
+ // FOStoreExtent, because we use a GetInstancesRequest to re-fill
+ // the ArrayList if needed.
+ private ArrayList instances;
+ private ArrayList oids;
+ private int maxInstances;
+
+ /** Index into instances. */
+ private int instanceIndex = 0;
+
+ /** Index into oids. */
+ private int oidsIndex = 0;
+
+ /** Index into extent as a whole.*/
+ private int index = 0;
+
+ /** Size of extent (number of instances + number of oids). */
+ private final int size;
+
+ /** If false, then can get next object, otherwise
+ * next() always throws NoSuchElementException and
+ * hasNext() always returns false. */
+ private boolean closed = false;
+
+ private Object nextObject = null;
+
+ FOStoreExtentIterator(FOStoreExtent extent) {
+ try {
+ Message message = connector.getMessage();
+ GetExtentRequest request =
+ rf.getGetExtentRequest(extent, cls, subclasses, message, pm);
+ request.doRequest();
+ connector.flush();
+ instances = request.getInstances();
+ oids = request.getOIDs();
+ maxInstances = request.getMaxInstances();
+ } catch (IOException ex) {
+ throw new FOStoreFatalIOException(
+ getClass(), "init", ex); // NOI18N
+ } catch (JDOException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "init", ex); // NOI18N
+ }
+
+ Collection insertedInstances = pm.getInsertedInstances();
+ for (Iterator it = insertedInstances.iterator(); it.hasNext();) {
+ Object o = it.next();
+ Class clz = o.getClass();
+ if (cls.equals(clz) || (subclasses && cls.isAssignableFrom(clz))) {
+ instances.add(o);
+ }
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOStoreExtentIterator.<init>: cls=" + cls.getName() + // NOI18N
+ ", numInstances=" + instances.size()); // NOI18N
+ }
+
+ this.size = instances.size() + oids.size();
+ if (size == 0) {
+ close();
+ }
+ }
+
+ /**
+ * @see java.util.Iterator#hasNext
+ */
+ public boolean hasNext() {
+ // This code advances to the next not deleted
+ // instance, or until the iterator is closed.
+ // Iterator is closed in getNext() if there
+ // are no more instances available. nextObject
+ // is null at the beginning and after close().
+ while (! closed && (nextObject == null ||
+ JDOHelper.isDeleted(nextObject))) {
+ getNext();
+ }
+ return (nextObject != null);
+ }
+
+ /**
+ * @see java.util.Iterator#next
+ */
+ public Object next() {
+ if (nextObject == null && !hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ Object rc = nextObject;
+ nextObject = null;
+ return rc;
+ }
+
+ /** Get the next instance. Close the iterator if there are
+ * no more instances available.
+ */
+ private void getNext() {
+ if (index < size) {
+ if (instanceIndex >= instances.size()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOStoreExtentIterator.next get new instances"); // NOI18N
+ }
+ FOStoreStoreManager srm =
+ (FOStoreStoreManager)pm.getStoreManager();
+ instances = srm.getInstances(
+ oids, oidsIndex, maxInstances, pm, cls);
+ oidsIndex += instances.size();
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOStoreExtent.next got " + // NOI18N
+ instances.size() + " instances"); // NOI18N
+ }
+ instanceIndex = 0;
+ }
+ nextObject = instances.get(instanceIndex);
+ instanceIndex++;
+ index++;
+
+ } else {
+ close();
+ }
+ }
+
+ /**
+ * Always throws UnsupportedOperationException.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException(
+ msg.msg("EXC_RemoveNotSupported")); // NOI18N
+ }
+
+ /**
+ * Disallow getting further objects from this iterator.
+ */
+ void close() {
+ closed = true;
+ instances = null;
+ index = size;
+ nextObject = null;
+ }
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalIOException.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalIOException.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalIOException.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalIOException.java Sun May 22 11:40:13 2005
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+/**
+* This is an exception which _should_ never be thrown, as it indicates an
+* error in I/O traffic between client and server. It most likely indicates a
+* bug in the implementation.
+*
+* @author Dave Bristor
+*/
+public class FOStoreFatalIOException extends FOStoreFatalInternalException {
+ /**
+ * @param clz Class in which the exception is thrown.
+ * @param methodName Name of the method from which the exception is
+ * thrown.
+ */
+ FOStoreFatalIOException(Class clz, String methodName, Exception nested) {
+ super(clz, methodName, nested);
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalInternalException.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalInternalException.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalInternalException.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreFatalInternalException.java Sun May 22 11:40:13 2005
@@ -0,0 +1,61 @@
+/*
+ * 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 is an exception which _should_ never be thrown, as it indicates an
+* error in the implementation, such as a bug that has been found.
+*
+* @author Dave Bristor
+*/
+public class FOStoreFatalInternalException extends JDOFatalInternalException {
+ /**
+ * @param clz Class in which the exception is thrown.
+ * @param methodName Name of the method from which the exception is
+ * thrown.
+ * @param msg The exception message.
+ */
+ FOStoreFatalInternalException(Class clz, String methodName, String msg) {
+ super(clz.getName() + "." + methodName + ": " + msg); // NOI18N
+ }
+
+ /**
+ * @param clz Class in which the exception is thrown.
+ * @param methodName Name of the method from which the exception is
+ * thrown.
+ */
+ FOStoreFatalInternalException(Class clz, String methodName,
+ Exception nested) {
+ super(clz.getName() + "." + methodName, // NOI18N
+ new Exception[] {nested}); // NOI18N
+ }
+
+ /**
+ * @param clz Class in which the exception is thrown.
+ * @param methodName Name of the method from which the exception is
+ * thrown.
+ * @param msg The exception message.
+ */
+ FOStoreFatalInternalException(Class clz, String methodName, String msg,
+ Exception nested) {
+
+ super(clz.getName() + "." + methodName + ": " + msg, // NOI18N
+ new Exception[] {nested}); // NOI18N
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreInput.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreInput.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreInput.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreInput.java Sun May 22 11:40:13 2005
@@ -0,0 +1,135 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* Extend ByteArrayInputStream so that we can get ahold of the byte array
+* and current position, and can change the current position.
+*
+* @author Dave Bristor
+*/
+class FOStoreInput extends ByteArrayInputStream implements DataInput {
+ private final DataInputStream dis;
+
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+ FOStoreInput(byte data[], int off, int len) {
+ super(data, off, len);
+ dis = new DataInputStream(this);
+ }
+
+ byte[] getBuf() {
+ return buf;
+ }
+
+ int getPos() {
+ return pos;
+ }
+
+ void setPos(int pos) {
+ if (pos < 0 || pos > buf.length) {
+ throw new FOStoreFatalInternalException(
+ this.getClass(), "setPos", // NOI18N
+ msg.msg("ERR_InvalidSeekPos", // NOI18N
+ new Integer(pos), new Integer(buf.length)));
+ }
+ this.pos = pos;
+ }
+
+ // Advance pos by len, but don't break invariant required by
+ // ByteArrayInputStream (see ByteArrayInputStrea.pos's javadoc).
+ void advance(int len) {
+ if (pos + len <= count) {
+ pos += len;
+ } else {
+ pos = count;
+ }
+ }
+
+ //
+ // Implement DataInput
+ //
+
+ public boolean readBoolean() throws IOException {
+ return dis.readBoolean();
+ }
+
+ public byte readByte() throws IOException {
+ return dis.readByte();
+ }
+
+ public char readChar() throws IOException {
+ return dis.readChar();
+ }
+
+ public double readDouble() throws IOException {
+ return dis.readDouble();
+ }
+
+ public float readFloat() throws IOException {
+ return dis.readFloat();
+ }
+
+ public void readFully(byte[] b) throws IOException {
+ dis.readFully(b);
+ }
+
+ public void readFully(byte[] b, int off, int len) throws IOException {
+ dis.readFully(b, off, len);
+ }
+
+ public int readInt() throws IOException {
+ return dis.readInt();
+ }
+
+ public String readLine() throws IOException {
+ return dis.readLine();
+ }
+
+ public long readLong() throws IOException {
+ return dis.readLong();
+ }
+
+ public short readShort() throws IOException {
+ return dis.readShort();
+ }
+
+ public int readUnsignedByte() throws IOException {
+ return dis.readUnsignedByte();
+ }
+
+ public int readUnsignedShort() throws IOException {
+ return dis.readUnsignedShort();
+ }
+
+ public String readUTF() throws IOException {
+ return dis.readUTF();
+ }
+
+ public int skipBytes(int n) throws IOException {
+ return dis.skipBytes(n);
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLocalConnection.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLocalConnection.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLocalConnection.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLocalConnection.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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.jdo.JDOUserException;
+
+/**
+* Implements the client and server/store connections for the case in which
+* the client and store are running in the same address space.
+*
+* @author Dave Bristor
+*/
+class FOStoreLocalConnection extends FOStoreClientConnectionImpl {
+
+ /** The server that implements the requests
+ */
+ private FOStoreServerConnection server = new FOStoreServerConnectionImpl();
+
+ /**
+ * Provides a connection to the database, using the URL support in
+ * the superclass.
+ */
+ FOStoreLocalConnection(URL url) {
+ super(url);
+ }
+
+ /**
+ * @see FOStoreClientConnection#getInputFromServer
+ */
+ public DataInput getInputFromServer() throws IOException {
+ return server.getOutputFromServer();
+ }
+
+ /** Write bytes to the store. The data is used to construct a FOStoreInput
+ * for the server to use; then the server is called to process the requests.
+ */
+ public void sendToStore(byte[] buffer, int offset, int length) throws IOException {
+ if (logger.isDebugEnabled()) logger.debug("FOLC.wTS: " + // NOI18N
+ (length - offset));
+ server.setClientInput (new FOStoreInput (buffer, offset, length));
+ server.processRequests();
+ }
+
+ /** This connects to the data store, and verifies the user name and password..
+ */
+ public void connect() throws IOException {
+ login();
+ }
+
+ /** Close the database associated with this connection. This closes the local
+ * server, which causes the remote database to be closed.
+ */
+ public void closeDatabase() throws FOStoreDatabaseException {
+ server.closeDatabase();
+ }
+
+ /**
+ * @return The <code>path</code> as given.
+ */
+ protected String localizePath(String path) {
+ return path;
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLoginException.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLoginException.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLoginException.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreLoginException.java Sun May 22 11:40:13 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 javax.jdo.JDOFatalUserException;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* This is an exception which _should_ never be thrown, as it indicates an
+* error in the implementation, such as a bug that has been found.
+*
+* @author Dave Bristor
+*/
+public class FOStoreLoginException extends JDOFatalUserException {
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+ /**
+ * @param nested Exception which caused failure
+ * thrown.
+ */
+ FOStoreLoginException(String dbname, String user, Exception nested) {
+ super(msg.msg("EXC_LoginFailed", dbname, user), nested); // NOI18N
+ }
+}
+
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreModel.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreModel.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreModel.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreModel.java Sun May 22 11:40:13 2005
@@ -0,0 +1,271 @@
+/*
+ * 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 java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.jdo.JDOFatalInternalException;
+
+import javax.jdo.spi.PersistenceCapable;
+
+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.model.ModelException;
+import org.apache.jdo.model.jdo.JDOClass;
+import org.apache.jdo.model.jdo.JDOField;
+import org.apache.jdo.model.jdo.JDOIdentityType;
+import org.apache.jdo.model.jdo.JDOModel;
+import org.apache.jdo.pm.PersistenceManagerFactoryInternal;
+import org.apache.jdo.pm.PersistenceManagerInternal;
+import org.apache.jdo.util.I18NHelper;
+
+/**
+* Provides model information required by fostore: mapping between CLID's and
+* the java.lang.Class's.
+*
+* @author Dave Bristor
+*/
+class FOStoreModel {
+ // Maps from java.lang.Class to CLID.
+ private HashMap clids = new HashMap();
+
+ /** Maps from provisional CLID's to java.lang.Class's. See updateCLID
+ * and getClass.
+ */
+ private HashMap provisionalCLIDs = new HashMap();
+
+ /** Map from jdoClass to an array of FOStoreTranscribers. */
+ private final HashMap transcribers = new HashMap();
+
+ /** Convenience; so that we don't have to getInstance() all the time. */
+ // XXX We may want to rethink how transcribers are accessed.
+ private final FOStoreTranscriberFactory transcriberFactory =
+ FOStoreTranscriberFactory.getInstance();
+
+ /** RuntimeJavaModelFactory. */
+ private static final RuntimeJavaModelFactory javaModelFactory =
+ (RuntimeJavaModelFactory) AccessController.doPrivileged(
+ new PrivilegedAction () {
+ public Object run () {
+ return RuntimeJavaModelFactory.getInstance();
+ }
+ }
+ );
+
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(
+ I18N.NAME, FOStoreModel.class.getClassLoader());
+
+ /** Logger */
+ static final Log logger = LogFactory.getFactory().getInstance(
+ "org.apache.jdo.impl.fostore"); // NOI18N
+
+ /** Constructor */
+ FOStoreModel() { }
+
+ /**
+ * Provides the class id for the given class.
+ * @param cls The class for which the corresponding class id is needed.
+ * @return CLID for the given class, or null if there is no metadata for
+ * that class.
+ */
+ CLID getCLID(Class cls) {
+ // First check if cls has a well-known CLID. If not, get metadata for
+ // cls and get the CLID for that. If still no CLID, create one and map
+ // it in the clids table.
+ CLID rc = CLID.getKnownCLID(cls);
+ if (null == rc) {
+ synchronized(clids) {
+ rc = (CLID)clids.get(cls);
+ if (null == rc) {
+ rc = CLID.createProvisional();
+ clids.put(cls, rc);
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "FOM.getCLID (new): " + cls + " -> " + rc); // NOI18N
+ }
+ }
+ }
+ }
+ return rc;
+ }
+
+ /**
+ * Add a mapping from ClassMetaData to CLID.
+ */
+ synchronized void put(Class cls, CLID clid) {
+ clids.put(cls, clid);
+ }
+
+ /**
+ * Causes the given class mapped to an OID.
+ * @param cls Class to be mapped.
+ * @param type JDOIdentityType as an int.
+ * @param pc PersistenceCapable instance to copy fields from if available.
+ * @param oid Object Id instance to copy fields from if available.
+ * @param pm PersistenceManagerInternal that requested the operation.
+ * @param pmf FOStorePMF that requested the operation.
+ * @return ObjectId corresponding to given class.
+ */
+ OID bind(Class cls, int type, PersistenceCapable pc,
+ Object oid, PersistenceManagerInternal pm, FOStorePMF pmf) {
+ OID rc = null;
+ switch (type) {
+ case JDOIdentityType.APPLICATION:
+ rc = AID.create(cls, pc, oid, pm, pmf);
+ break;
+ case JDOIdentityType.DATASTORE:
+ CLID clid = getCLID(cls);
+ rc = OID.create(clid);
+ break;
+ default:
+ break;
+ }
+ return rc;
+ }
+
+ /**
+ * Changes the class id by which this metadata is known.
+ * @param pCLID The class id by which the class was previously known.
+ * @param rCLID The class id by which the class should be known from now
+ * on in this JVM.
+ */
+ void updateCLID(CLID pCLID, CLID rCLID) {
+ Map.Entry entry = getEntry(pCLID);
+ if (null != entry) {
+ entry.setValue(rCLID);
+ if (null == provisionalCLIDs.get(pCLID)) {
+ Class cls = (Class)entry.getKey();
+ provisionalCLIDs.put(pCLID, cls);
+ }
+ }
+ }
+
+ /**
+ * Return the class corresponding to the given CLID.
+ * @param clid The CLID for which a class is wanted.
+ * @return The java.lang.Class corresponding to the given CLID, or null if
+ * none is found.
+ */
+ Class getClass(CLID clid) {
+ Class rc = null;
+ Map.Entry entry = getEntry(clid);
+ if (null != entry) {
+ rc = (Class)entry.getKey();
+ }
+
+ // It is possible we did not find a mapping. This can be the case if,
+ // for example, 2 objects are created, and one is stored but not the
+ // other. The act of storing one will update the clids table via
+ // updateCLID. So we have to look in this other table.
+ if (null == rc && clid.isProvisional()) {
+ rc = (Class)provisionalCLIDs.get(clid);
+ }
+ return rc;
+ }
+
+
+ // Provide the entry which represents the Class - CLID mapping. While
+ // this may seem time-wise expensive, we don't expect there to be all
+ // *that* many classes (O(100)) per JVM.
+ synchronized Map.Entry getEntry(CLID clid) {
+ Map.Entry rc = null;
+ Set entries = (Set)clids.entrySet();
+ for (Iterator i = entries.iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry)i.next();
+ CLID aCLID = (CLID)entry.getValue();
+ if (clid.equals(aCLID)) {
+ rc = entry;
+ break;
+ }
+ }
+ return rc;
+ }
+
+ //
+ // Provide access to the JDOModel
+ //
+
+ /** @param c Class whose corresponding JDOClass is needed.
+ * @return The JDOClass for the given class.
+ */
+ JDOClass getJDOClass(Class c) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("FOM.getJDOClass for " + c.getName()); // NOI18N
+ }
+ return javaModelFactory.getJavaType(c).getJDOClass();
+ }
+
+ /** Provides a transcriber for the field in the given JDOClass indicated
+ * by fieldNum.
+ * @param c JDOClass for which a transcriber is needed.
+ * @param fieldNum The absolute fieldNumber in the class modeled by
+ * jdoClass that is to be transcribed.
+ * @return a FOStoreTranscriber appropriate for the type of field in the
+ * class modeled by field fieldNum in the class corresponding to
+ * jdoClass.
+ */
+ FOStoreTranscriber getTranscriber(Class c, int fieldNum) {
+ FOStoreTranscriber t[] =
+ (FOStoreTranscriber[])transcribers.get(c);
+ if (null == t) {
+ // Create transcribers for jdoClass
+ JDOClass jdoClass = getJDOClass(c);
+ // Use managed fields here to preserve correct fieldNum's.
+ JDOField fields[] = jdoClass.getManagedFields();
+ int length = fields.length;
+ t = new FOStoreTranscriber[length];
+
+ for (int i = 0; i < length; i++) {
+ if (fields[i].isPersistent()) {
+ t[i] = (FOStoreTranscriber)transcriberFactory.getTranscriber(
+ javaModelFactory.getJavaClass(fields[i].getType()))[0];
+ } else {
+ t[i] = DummyTranscriber.getInstance();
+ }
+ }
+ transcribers.put(c, t);
+ }
+ return t[fieldNum];
+ }
+
+ //
+ // Debug support
+ //
+
+ void print(Object o) {
+ print (o.getClass());
+ }
+
+ void print(Class c) {
+ JDOModel m = null;
+ try {
+ ClassLoader cl = c.getClassLoader();
+ m = javaModelFactory.getJavaModel(cl).getJDOModel();
+ org.apache.jdo.impl.model.jdo.util.PrintSupport.printJDOModel(m);
+ } catch (Exception ex) {
+ System.out.println("Cannot print model"); // NOI18N
+ }
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreOutput.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreOutput.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreOutput.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStoreOutput.java Sun May 22 11:40:13 2005
@@ -0,0 +1,244 @@
+/*
+ * 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.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.apache.jdo.util.I18NHelper;
+
+
+/**
+* Extend ByteArrayOutputStream so that we can get ahold of the byte array
+* and current position, and can make sure we have enough space to write an
+* object. We also allow getting and changing the current position. Also,
+* implement DataOutput so that we can write easily to this output.
+*
+* @author Dave Bristor
+*/
+class FOStoreOutput implements DataOutput {
+ // Once closed, no more writing allowed.
+ private boolean closed = false;
+
+ private final LocalByteArrayOutputStream stream;
+ private final DataOutputStream dos;
+
+ /** I18N support. */
+ private static final I18NHelper msg = I18NHelper.getInstance(I18N.NAME);
+
+ FOStoreOutput() {
+ stream = new LocalByteArrayOutputStream();
+ dos = new DataOutputStream(stream);
+ }
+
+ /** Close the stream. The stream can no longer be written.
+ */
+ public void close() {
+ closed = true;
+ }
+
+ /** Reset the stream. Discard the current contents, and reset the count
+ * to 0 and the current position to 0. The current buffer is retained.
+ */
+ public void reset() {
+ stream.reset();
+ }
+
+ // In a simpler world, FOStoreOutput would extend ByteArrayOutputStream
+ // and implement DataOutput. However. The creators of the early Java
+ // classes wisely noted that, in ByteArrayOutputStream, the write methods
+ // could not throw IOException, after all, there's no I/O happening. Of
+ // course, with DataOutput, you never know what's behind the scenes, so
+ // it's write methods *do* throw IOException. Since we need the
+ // functionality of both, and these are in conflice, we cannot both
+ // extend ByteArrayOutputStream *and* implement DataOutput. So we
+ // implement DataOutput and delegate to this extension.
+ //
+ class LocalByteArrayOutputStream extends ByteArrayOutputStream {
+ LocalByteArrayOutputStream() {
+ super();
+ }
+
+ byte[] getBuf() {
+ return buf;
+ }
+
+ int getCurrentPosition() {
+ return count;
+ }
+
+ void seek(int pos) {
+ if (pos < 0 || pos > buf.length) {
+ throw new FOStoreFatalInternalException(
+ this.getClass(), "seek", // NOI18N
+ msg.msg("ERR_InvalidSeekPos", // NOI18N
+ new Integer(pos), new Integer(buf.length)));
+ }
+ this.count = pos;
+ }
+ }
+
+ /**
+ * Provides no-copy access to the buffer.
+ * @return The byte array representing this stream. <em>Not a copy.</em>
+ */
+ byte[] getBuf() {
+ return stream.getBuf();
+ }
+
+ //
+ // A common need of RequestHandlers is to write a nonsense number, which
+ // is later filled in with a count or length (etc.) appropriate to the
+ // reply's acutal data. These help do that. Use them instead of
+ // getPos/setPos, if/when you can.
+ //
+ // This is easy to do by hand, but I've burned myself too many times
+ // by being imprecise when doing it that way!
+ //
+
+ /**
+ * Write a nonsense int value at the current position, and return that
+ * position for later use with endStash
+ * @return Position in this output for later use in writing a 'real'
+ * value.
+ * @see #endStash
+ */
+ int beginStash() throws IOException {
+ int rc = getPos();
+ writeInt(0xbadbad10);
+ return rc;
+ }
+
+ /**
+ * Write the given value at the given position, and reset the position to
+ * what it was before the write occurred.
+ * @param value Value to be written
+ * @param pos Position in this output at which value is to be written
+ * @see #beginStash
+ */
+ void endStash(int value, int pos) throws IOException {
+ int savedPos = getPos();
+ setPos(pos);
+ writeInt(value);
+ setPos(savedPos);
+ }
+
+ /**
+ * Provides the stream's current writing position.
+ * @return The current writing position of the stream.
+ */
+ int getPos() {
+ return stream.getCurrentPosition();
+ }
+
+ /**
+ * Allows for setting the current writing position.
+ * @param pos Position at which future write operations will take
+ * place.
+ */
+ void setPos(int pos) throws IOException {
+ stream.seek(pos);
+ }
+
+ //
+ // Implement DataOutput by forwarding onto our private DataOutputStream
+ //
+
+ public void write(byte[] b) throws IOException {
+ assertNotClosed();
+ dos.write(b);
+ }
+
+ public void write(int b) throws IOException {
+ assertNotClosed();
+ dos.write(b);
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ assertNotClosed();
+ dos.write(b, off, len);
+ }
+
+ public void writeBoolean(boolean v) throws IOException {
+ assertNotClosed();
+ dos.writeBoolean(v);
+ }
+
+ public void writeByte(int v) throws IOException {
+ assertNotClosed();
+ dos.writeByte(v);
+ }
+
+ public void writeBytes(String s) throws IOException {
+ assertNotClosed();
+ dos.writeBytes(s);
+ }
+
+ public void writeChar(int v) throws IOException {
+ assertNotClosed();
+ dos.writeChar(v);
+ }
+
+ public void writeChars(String s) throws IOException {
+ assertNotClosed();
+ dos.writeChars(s);
+ }
+
+ public void writeDouble(double v) throws IOException {
+ assertNotClosed();
+ dos.writeDouble(v);
+ }
+
+ public void writeFloat(float v) throws IOException {
+ assertNotClosed();
+ dos.writeFloat(v);
+ }
+
+ public void writeInt(int v) throws IOException {
+ assertNotClosed();
+ dos.writeInt(v);
+ }
+
+ public void writeLong(long v) throws IOException {
+ assertNotClosed();
+ dos.writeLong(v);
+ }
+
+ public void writeShort(int v) throws IOException {
+ assertNotClosed();
+ dos.writeShort(v);
+ }
+
+ public void writeUTF(String str) throws IOException {
+ assertNotClosed();
+ dos.writeUTF(str);
+ }
+
+ //
+ // Private implementation methods
+ //
+
+ private void assertNotClosed() {
+ if (closed) {
+ throw new FOStoreFatalInternalException(
+ getClass(), "assertNotClosed", // NOI18N
+ msg.msg("ERR_Closed")); // NOI18N
+ }
+ }
+}
Added: incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStorePM.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStorePM.java?rev=171355&view=auto
==============================================================================
--- incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStorePM.java (added)
+++ incubator/jdo/trunk/fostore20/src/java/org/apache/jdo/impl/fostore/FOStorePM.java Sun May 22 11:40:13 2005
@@ -0,0 +1,160 @@
+/*
+ * 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.Collection;
+
+import javax.jdo.Extent;
+import javax.jdo.JDOUserException;
+import javax.jdo.Query;
+
+import org.apache.jdo.jdoql.JDOQLQueryFactory;
+
+import org.apache.jdo.impl.pm.PersistenceManagerImpl;
+
+/**
+ * Subclass of {@link #PersistenceManagerImpl} implementing
+ * abstract methods <code>newQuery</code>.
+ *
+ * @author Michael Watzek
+ */
+public class FOStorePM extends PersistenceManagerImpl
+{
+ /** The JDOQLQueryFactory. */
+ private JDOQLQueryFactory jdoqlQueryFactory;
+
+ /**
+ * Constructs new instance of PersistenceManagerImpl for this
+ * PersistenceManagerFactoryInternal and particular combination of
+ * username and password.
+ * @param pmf calling PersistenceManagerFactory as
+ * PersistenceManagerFactoryInternal
+ * @param username user name used for accessing Connector or null if none
+ * is provided.
+ * @param password user password used for accessing Connector or null if
+ * none is provided.
+ */
+ FOStorePM(FOStorePMF pmf, String username, String password)
+ {
+ super(pmf, username, password);
+ this.jdoqlQueryFactory = pmf.getJDOQLQueryFactory();
+ }
+
+ /** Create a new Query with no elements.
+ * @return a new Query instance with no elements.
+ */
+ public Query newQuery()
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this);
+ }
+
+ /** Create a new Query using elements from another Query. The other Query
+ * must have been created by the same JDO implementation. It might be active
+ * in a different PersistenceManager or might have been serialized and
+ * restored.
+ * @return the new Query
+ * @param compiled another Query from the same JDO implementation
+ */
+ public Query newQuery(Object compiled)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, compiled);
+ }
+
+ /** Create a new Query using the specified language.
+ * @param language the language of the query parameter
+ * @param query the query, which is of a form determined by the language
+ * @return the new Query
+ */
+ public Query newQuery(String language, Object query)
+ {
+ assertIsOpen();
+ if ("javax.jdo.query.JDOQL".equals(language)) //NOI18N
+ return this.jdoqlQueryFactory.newQuery(this, query);
+ throw new JDOUserException(msg.msg(
+ "EXC_UnsupportedQueryLanguage", language)); // NOI18N
+ }
+
+ /** Create a new Query specifying the Class of the results.
+ * @param cls the Class of the results
+ * @return the new Query
+ */
+ public Query newQuery(Class cls)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, cls);
+ }
+
+ /** Create a new Query with the candidate Extent; the class is taken
+ * from the Extent.
+ * @return the new Query
+ * @param cln the Extent of candidate instances */
+ public Query newQuery(Extent cln)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, cln);
+ }
+
+ /** Create a new Query with the Class of the results and candidate
+ * Collection.
+ * @param cls the Class of results
+ * @param cln the Collection of candidate instances
+ * @return the new Query
+ */
+ public Query newQuery(Class cls, Collection cln)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, cls, cln);
+ }
+
+ /** Create a new Query with the Class of the results and Filter.
+ * @param cls the Class of results
+ * @param filter the Filter for candidate instances
+ * @return the new Query
+ */
+ public Query newQuery(Class cls, String filter)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, cls, filter);
+ }
+
+ /** Create a new Query with the Class of the results, candidate Collection,
+ * and Filter.
+ * @param cls the Class of results
+ * @param cln the Collection of candidate instances
+ * @param filter the Filter for candidate instances
+ * @return the new Query
+ */
+ public Query newQuery(Class cls, Collection cln, String filter)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, cls, cln, filter);
+ }
+
+ /** Create a new Query with the candidate Extent and Filter.
+ * The class is taken from the Extent.
+ * @return the new Query
+ * @param cln the Extent of candidate instances
+ * @param filter the Filter for candidate instances */
+ public Query newQuery(Extent cln, String filter)
+ {
+ assertIsOpen();
+ return this.jdoqlQueryFactory.newQuery(this, cln, filter);
+ }
+
+}