/*
$Header: /cvsroot/xorm/xorm/src/org/xorm/InterfaceManager.java,v 1.80 2004/05/19 19:58:57 wbiggs Exp $
This file is part of XORM.
XORM is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
XORM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with XORM; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.xorm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.Iterator;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xorm.cache.DataCache;
import org.xorm.datastore.Column;
import org.xorm.datastore.Row;
import org.xorm.datastore.Table;
import org.xorm.datastore.DataFetchGroup;
import org.xorm.datastore.DatastoreDriver;
import org.xorm.datastore.DriverException;
import org.xorm.query.CodeParser;
import org.xorm.query.CodeQuery;
import org.xorm.query.DataQuery;
import org.xorm.query.Operator;
import org.xorm.query.QueryImpl;
import org.xorm.query.QueryLanguage;
import org.xorm.query.Selector;
import org.xorm.query.SimpleCondition;
import org.xorm.util.TypeConverter;
import javax.jdo.Extent;
import javax.jdo.InstanceCallbacks;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import javax.jdo.Transaction;
import javax.jdo.JDODataStoreException;
import javax.jdo.JDOFatalUserException;
import javax.jdo.spi.JDOImplHelper;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.JDOUserException;
import javax.jdo.spi.PersistenceCapable;
import net.sf.cglib.Enhancer;
import net.sf.cglib.Factory;
// TODO: make InterfaceManager have to know less about status codes of
// InterfaceInvocationHandler
/**
* Roughly equivalent to JDO PersistenceManager. Developers should
* always acquire an InterfaceManager as a
* javax.jdo.PersistenceManager. The implementation details are
* transparent to the use of the API. To use additional XORM
* features, the org.xorm.XORM static methods are provided.
*/
class InterfaceManager implements PersistenceManager, I15d {
private static Logger logger =
Logger.getLogger("org.xorm");
private static final String JDOQL_LANGUAGE = "javax.jdo.query.JDOQL";
private InterfaceManagerFactory factory;
private Object transaction;
private Object userObject;
private boolean closed;
private boolean multithreaded;
private boolean ignoreCache;
//need to hold onto this now to make transactions for the thread local case
private Options jdoOptions;
/**
* Creates a new InterfaceManager. This method is called from the
* InterfaceManagerFactory.
*/
InterfaceManager(final InterfaceManagerFactory factory, final Options jdoOptions) {
this.factory = factory;
// Depending on option
if (!factory.useThreadLocalTransactions()) {
this.transaction = new TransactionImpl(this, factory.newDatastoreDriver(), jdoOptions);
} else {
this.jdoOptions = jdoOptions;
this.transaction = new WeakHashMap();
}
}
/**
* Helper method that is called by all PersistenceManager
* interface methods.
*/
private void assertNotClosed() {
if (closed) {
throw new JDOFatalUserException(I18N.msg("E_PM_closed"));
}
}
InterfaceManagerFactory getInterfaceManagerFactory() {
return factory;
}
public PersistenceManagerFactory getPersistenceManagerFactory() {
assertNotClosed();
return factory;
}
/**
* Returns the transaction associated with this InterfaceManager.
* Merely retrieving the transaction does not change its state;
* you must call begin(), commit(), etc.
*/
public Transaction currentTransaction() {
assertNotClosed();
// Give users the option to use thread-local transactions
// with a single PersistenceManager.
Transaction txn = null;
if (transaction instanceof WeakHashMap) {
WeakHashMap threadTransactionMap = (WeakHashMap)transaction;
Thread currentThread = Thread.currentThread();
synchronized(threadTransactionMap) {
txn = (Transaction)threadTransactionMap.get(currentThread);
if(txn == null) {
txn = new TransactionImpl(this, factory.newDatastoreDriver(), jdoOptions);
threadTransactionMap.put(currentThread, txn);
}
}
} else {
txn = (Transaction) transaction;
}
return txn;
}
public Object getObjectById(Object object, boolean validate) {
assertNotClosed();
if (object instanceof ObjectId) {
ObjectId objectId = (ObjectId) object;
Class mappedClass = objectId.mappedClass;
Object id = objectId.id;
// Munge id if necessary
ClassMapping mapping = factory.getModelMapping().getClassMapping(mappedClass);
Class datastoreClass = mapping.getDatastoreIdentityType();
if (datastoreClass != null) {
id = TypeConverter.convertToType(id, datastoreClass);
}
Object out = lookup(mapping, id);
// If validate is set, transition the object from hollow:
if (validate) {
InterfaceInvocationHandler handler =
InterfaceInvocationHandler.getHandler(out);
handler.refresh(this);
}
return out;
}
throw new JDOUserException(I18N.msg("E_no_object_id"));
}
/**
* Retrieves an object from the cache or from persistent storage
* that is of the given type and has the matching object ID.
* Called from getObjectById and from RelationshipProxy.iterator()
*/
Object lookup(Class clazz, Object primaryKey) {
ClassMapping classMapping = factory.getModelMapping().getClassMapping(clazz);
if (classMapping == null) {
throw new JDOUserException(I18N.msg("E_no_class_mapping", clazz));
}
return lookup(classMapping, primaryKey);
}
// package-scope; used for performance reasons from InterfaceInvocationHandler when mapping is known
/**
* This is the primary method by which an object is acquired.
* This method may return a hollow object that has not been validated.
* Called from lookup(Class, Object) and from InterfaceInvocationHandler
* .invokeGet().
*/
Object lookup(ClassMapping classMapping, Object primaryKey) {
// 1. Look in transactional scope
TransactionImpl txn = (TransactionImpl) currentTransaction();
useNontransactionalRead(); // asserts that there is an active transaction or nontransactional read is supported
Object proxy = txn.get(classMapping.getMappedClass(), primaryKey);
if (proxy != null) return proxy;
// Try lookup in cache and datastore if non-transient
if (primaryKey instanceof TransientKey) {
return null;
}
// Return hollow object
Row row = new Row(classMapping.getTable(), primaryKey);
proxy = rowToProxy(classMapping, row);
return proxy;
}
/**
* Create a proxy instance representing a particular row in the datastore.
*/
private Object rowToProxy(ClassMapping classMapping, Row row) {
TransactionImpl txn = (TransactionImpl) currentTransaction();
Object proxy = null;
// Avoid two copies of the same object
if (txn.isActive()) {
proxy = txn.get(classMapping.getMappedClass(), row.getPrimaryKeyValue());
}
if ( proxy == null ) {
InterfaceInvocationHandler handler = new InterfaceInvocationHandler(factory, classMapping, row);
proxy = handler.newProxy();
handler.enterTransaction(txn);
}
return proxy;
}
/**
* Returns true if a nontransactional read should be performed.
* If nontransactional read is not supported, but no transaction
* is in progress, throws an exception.
*/
private boolean useNontransactionalRead() {
TransactionImpl txn = (TransactionImpl) currentTransaction();
if (!txn.isActive()) {
if (factory.getNontransactionalRead()) {
return true;
} else {
throw new UnsupportedOperationException(I18N.msg("E_no_txn"));
}
}
return false;
}
void addToCache(Row row) {
DataCache cache = factory.getCache();
if (cache != null) {
// Don't need to clone anymore...cached flag instead
//cache.add((Row) row.clone());
cache.add(row);
}
}
void addToCache(Collection rows) {
DataCache cache = factory.getCache();
if (cache != null) {
Iterator i = rows.iterator();
while (i.hasNext()) {
Row row = (Row) i.next();
// Don't need to clone anymore...cached flag instead
//cache.add((Row) row.clone());
cache.add(row);
}
}
}
Row getFromCache(Table table, Object primaryKey) {
DataCache cache = factory.getCache();
if (cache != null) {
Row row = cache.get(table, primaryKey);
return row;
} else {
return null;
}
}
void removeFromCache(Row row) {
DataCache cache = factory.getCache();
if (cache != null) {
cache.remove(row);
}
}
/**
* Retrieve a datastore row given its primary key.
* This method first checks the local cache, then calls
* DatastoreDriver.read(). If no matching row is found,
* JDOObjectNotFoundException is thrown. Called from lookup() and from
* InterfaceInvocationHandler.refresh().
*/
Row lookupRow(ClassMapping classMapping, Object primaryKey) {
Table table = classMapping.getTable();
boolean useNontrans = useNontransactionalRead();
// 1. Look in cache
Row row = getFromCache(table, primaryKey);
if (row == null) {
// 2. Look in datastore
// Get the DataFetchGroup to use.
DataFetchGroup dfg = factory.getFetchGroupManager()
.getDataFetchGroup(classMapping);
Selector selector = new Selector
(table,
new SimpleCondition(table.getPrimaryKey(),
Operator.EQUAL,
primaryKey));
selector.require(dfg);
Collection rows = selectRows(selector);
if (!rows.isEmpty()) {
row = (Row) rows.iterator().next();
} else {
throw new JDOObjectNotFoundException();
}
}
return row;
}
/**
* Refreshes particular fields of a Row from the datastore.
* This method does not affect the cache.
*/
void refreshColumns(Row row, DataFetchGroup dfg) {
Table table = row.getTable();
boolean useNontrans = useNontransactionalRead();
Collection rows = null;
try {
if (useNontrans) {
((TransactionImpl) currentTransaction()).begin(true);
}
Object primaryKey = row.getPrimaryKeyValue();
Selector selector = new Selector
(table,
new SimpleCondition(table.getPrimaryKey(),
Operator.EQUAL,
primaryKey));
selector.require(dfg);
Set extraRows = new HashSet();
rows = ((TransactionImpl) currentTransaction()).getDriver()
.select(selector, extraRows);
if (!rows.isEmpty()) {
Row newFields = (Row) rows.iterator().next();
// Determine which fields to copy
Iterator i = dfg.getColumns().iterator();
while (i.hasNext()) {
Column c = (Column) i.next();
row.setValue(c, newFields.getValue(c));
}
} else {
throw new JDODataStoreException(I18N.msg("E_row_deleted"));
}
} catch (DriverException e) {
throw new JDODataStoreException(I18N.msg("E_query_failed"), e);
} finally {
if (useNontrans) {
currentTransaction().commit();
}
}
}
/**
* Attempts to identify the primaryKey for the object.
* Returns null if the object is not PersistenceCapable.
*/
public Object getObjectId(Object object) {
assertNotClosed();
// TODO according to JDO spec, instanceof PersistenceCapable
// is not sufficient
if (!(object instanceof PersistenceCapable)) return null;
return ((PersistenceCapable) object).jdoGetObjectId();
}
/**
* Marks an object as persistent so it may be saved to the datastore.
*/
public void makePersistent(Object object) {
assertNotClosed();
if (!currentTransaction().isActive()) {
throw new JDOUserException(I18N.msg("E_no_txn"));
}
PersistenceCapable pc = (PersistenceCapable) object;
ObjectState handler = getObjectState(object);
if (handler instanceof InterfaceInvocationHandler) {
// XORM-specific case
((InterfaceInvocationHandler) handler).makePersistent(this);
} else {
PersistenceManager mgr = pc.jdoGetPersistenceManager();
if (mgr != null) {
if (mgr == this) return; // already managed
else throw new JDOUserException(I18N.msg("E_wrong_PM"));
}
// Standard JDO object, make a StateManager for it
handler.setPersistent(true);
handler.setNew(true);
// TODO THIS IS NOT FULLY IMPLEMENTED
}
}
/**
* Marks all items within a collection of objects as persistent.
*/
public void makePersistentAll(Collection collection) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
makePersistent(i.next());
}
}
/**
* Marks all items within an array of objects as persistent.
*/
public void makePersistentAll(Object[] array) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
makePersistent(array[i]);
}
}
/**
* The incoming object may be an instance of either a
* reference-enhanced JDO class or a dynamically enhanced
* cglib-generated class.
*/
ObjectState getObjectState(Object object) {
if (object instanceof Factory) {
return (ObjectState) Enhancer.getMethodInterceptor(object);
}
// TODO instanceof check not sufficient
if (object instanceof PersistenceCapable) {
// look it up in hash of managed objects
return StateManagerImpl.forPersistenceCapable((PersistenceCapable) object, this);
}
return null;
}
// TODO incomplete
public void makeTransactional(Object object) {
assertNotClosed();
ObjectState handler = getObjectState(object);
if (handler instanceof InterfaceInvocationHandler) {
((InterfaceInvocationHandler) handler).makeTransactional(this);
}
}
public void makeTransactionalAll(Collection collection) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
makeTransactional(i.next());
}
}
public void makeTransactionalAll(Object[] array) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
makeTransactional(array[i]);
}
}
// TODO incomplete
public void makeNontransactional(Object object) {
assertNotClosed();
TransactionImpl txn = (TransactionImpl) currentTransaction();
if (txn.contains(object)) {
txn.detach(object);
}
ObjectState handler = getObjectState(object);
if (handler.isPersistent()) {
handler.setStatus(handler.STATUS_PERSISTENT_NONTRANSACTIONAL);
} else {
handler.setStatus(handler.STATUS_TRANSIENT);
}
}
public void makeNontransactionalAll(Collection collection) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
makeNontransactional(i.next());
}
}
public void makeNontransactionalAll(Object[] array) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
makeNontransactional(array[i]);
}
}
// TODO incomplete
public void makeTransient(Object object) {
assertNotClosed();
TransactionImpl txn = (TransactionImpl) currentTransaction();
if (!txn.contains(object)) {
txn.attach(object);
}
ObjectState handler = getObjectState(object);
handler.setStatus(handler.STATUS_TRANSIENT);
}
public void makeTransientAll(Collection collection) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
makeTransient(i.next());
}
}
public void makeTransientAll(Object[] array) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
makeTransient(array[i]);
}
}
public void deletePersistent(Object object) {
assertNotClosed();
InterfaceInvocationHandler handler = InterfaceInvocationHandler.getHandler(object);
if (!handler.isPersistent()) {
throw new JDOUserException(I18N.msg("E_delete_nonpersistent"));
}
if (this != handler.getInterfaceManager()) {
throw new JDOUserException(I18N.msg("E_wrong_PM"));
}
TransactionImpl txn = (TransactionImpl) currentTransaction();
if (!txn.contains(object)) {
handler.enterTransaction(txn);
}
switch (handler.getStatus()) {
case ObjectState.STATUS_PERSISTENT_NEW:
if (object instanceof InstanceCallbacks) {
((InstanceCallbacks) object).jdoPreDelete();
}
handler.setStatus(handler.STATUS_PERSISTENT_NEW_DELETED);
break;
case ObjectState.STATUS_PERSISTENT_CLEAN:
case ObjectState.STATUS_HOLLOW:
case ObjectState.STATUS_PERSISTENT_NONTRANSACTIONAL:
if (object instanceof InstanceCallbacks) {
((InstanceCallbacks) object).jdoPreDelete();
}
handler.setStatus(handler.STATUS_PERSISTENT_DELETED);
break;
}
}
public void deletePersistentAll(Collection collection) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
deletePersistent(i.next());
}
}
public void deletePersistentAll(Object[] array) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
deletePersistent(array[i]);
}
}
/**
* Selects the rows from the datastore matching the selection criteria.
* If no transaction is in progress, but nontransactionalRead is enabled,
* begins and ends a datastore transaction in order to perform the
* query. Before returning the collection of rows, this method adds
* the query results and any extra rows read by the driver to the cache.
*/
Collection selectRows(Selector selector) {
boolean useNontrans = useNontransactionalRead();
Collection rows = null;
try {
if (useNontrans) {
((TransactionImpl) currentTransaction()).begin(true);
}
Set extraRows = new HashSet();
rows = ((TransactionImpl) currentTransaction()).getDriver()
.select(selector, extraRows);
// Put rows in the 2nd-level cache
Table table = selector.getTable();
addToCache(rows);
// Put extraRows in the cache too
addToCache(extraRows);
} catch (DriverException e) {
throw new JDODataStoreException(I18N.msg("E_query_failed"), e);
} finally {
if (useNontrans) {
currentTransaction().commit();
}
}
return rows;
}
/** Returns a query built using JDOQL. */
public Query newQuery(Class clazz, String filter) {
assertNotClosed();
Query q = new QueryImpl(this);
q.setClass(clazz);
q.setFilter(filter);
return q;
}
/**
* Returns a query for the specified class. Without user
* modification, when executed, returns all instances of the class.
*/
public Query newQuery(Class clazz) {
assertNotClosed();
QueryImpl query = new QueryImpl(this);
query.setClass(clazz);
return query;
}
/**
* Returns a query for the specified extent. Without user
* modification, when executed, returns all instances of the class.
* Note that XORM does not support subclasses at this time.
*/
public Query newQuery(Extent extent) {
assertNotClosed();
QueryImpl query = new QueryImpl(this);
query.setClass(extent.getCandidateClass());
return query;
}
/**
* Returns a query for the specified extent. Without user
* modification, when executed, returns all instances of the class
* that match the query filter (JDOQL expression). Note that XORM
* does not support subclasses at this time.
*/
public Query newQuery(Extent extent, String filter) {
assertNotClosed();
QueryImpl query = new QueryImpl(this);
query.setClass(extent.getCandidateClass());
query.setFilter(filter);
return query;
}
int executeSizeQuery(Selector selector) {
boolean useNontrans = useNontransactionalRead();
int count = -1;
try {
if (useNontrans) {
((TransactionImpl) currentTransaction()).begin(true);
}
count = ((TransactionImpl) currentTransaction()).getDriver()
.count(selector);
} catch (DriverException e) {
throw new JDODataStoreException(I18N.msg("E_query_failed"), e);
} finally {
if (useNontrans) {
currentTransaction().commit();
}
}
return count;
}
/**
* Retrieves the user-associated object.
*/
public Object getUserObject() {
assertNotClosed();
return userObject;
}
/**
* Allows the user to associate an arbitrary object with this
* InterfaceManager.
*/
public void setUserObject(Object userObject) {
assertNotClosed();
this.userObject = userObject;
}
/**
* Reloads the fields of the object from the datastore.
*/
public void refresh(Object object) {
assertNotClosed();
// Look up the backing row in the datastore
InterfaceInvocationHandler handler = InterfaceInvocationHandler.getHandler(object);
ClassMapping mapping = handler.getClassMapping();
Table table = mapping.getTable();
// Look in datastore
Row row = null;
DataFetchGroup dfg = new DataFetchGroup(table.getColumns());
Selector selector = new Selector
(table,
new SimpleCondition(table.getPrimaryKey(),
Operator.EQUAL,
handler.getObjectId()));
selector.require(dfg);
Collection rows = selectRows(selector);
if (!rows.isEmpty()) {
row = (Row) rows.iterator().next();
} else {
throw new JDODataStoreException(I18N.msg("E_row_deleted"));
}
handler.resetRow(row);
}
/** Calls refresh() on all objects in the array. */
public void refreshAll(Object[] array) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
refresh(array[i]);
}
}
/** Calls refresh() on all objects in the collection. */
public void refreshAll(Collection collection) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
refresh(i.next());
}
}
/** Refreshes all objects in the transaction. */
public void refreshAll() {
assertNotClosed();
((TransactionImpl) currentTransaction()).refreshAll();
}
/**
* Marks this InterfaceManager as closed. Closing an
* InterfaceManager ensures that any datastore resources being
* used will be disconnected. After a call to close(), all
* methods of the PersistenceManager interface (with the exception
* of isClosed()) will throw JDOFatalUserException. Calling close()
* while a Transaction is active will throw a JDOUserException.
*/
public synchronized void close() {
assertNotClosed();
closeImpl(true);
closed = true;
}
private void closeImpl(boolean failIfActive) {
if (transaction instanceof WeakHashMap) {
WeakHashMap threadTransactionMap = (WeakHashMap)transaction;
for (Iterator it = threadTransactionMap.values().iterator(); it.hasNext();) {
TransactionImpl txn = (TransactionImpl) it.next();
if (txn.isActive()) {
if (failIfActive) {
throw new JDOUserException(I18N.msg("E_open_txn"));
}
txn.closeImpl();
}
}
} else {
TransactionImpl txn = (TransactionImpl) transaction;
if (txn.isActive()) {
if (failIfActive) {
throw new JDOUserException(I18N.msg("E_open_txn"));
}
txn.closeImpl();
}
}
}
/**
* Returns true if this manager object has been closed.
*/
public boolean isClosed() {
return closed;
}
/**
* Returns the Extent of the given class. Subclasses are not
* supported yet.
*/
public Extent getExtent(Class clazz, boolean subclasses) {
assertNotClosed();
return new ExtentImpl(this, clazz, subclasses);
}
// -------------- UNSUPPORTED JDO SPEC OPERATIONS -------------------
/** This operation is not currently supported. */
public void evict(Object object) {
assertNotClosed();
throw new UnsupportedOperationException();
}
/** This operation is not currently supported. */
public void evictAll(Object[] array) {
assertNotClosed();
throw new UnsupportedOperationException();
}
/** This operation is not currently supported. */
public void evictAll(Collection collection) {
assertNotClosed();
throw new UnsupportedOperationException();
}
/** This operation is not currently supported. */
public void evictAll() {
assertNotClosed();
throw new UnsupportedOperationException();
}
/**
* If the class parameter is not mapped in a *.jdo file,
* returns null. Otherwise returns org.xorm.ObjectId.class.
*/
public Class getObjectIdClass(Class clazz) {
assertNotClosed();
ClassMapping classMapping = factory.getModelMapping().getClassMapping(clazz);
return (classMapping == null) ? null : ObjectId.class;
}
/**
* Indicates that this PersistenceManager will be used in a
* multithreaded context. Currently this flag is not being used.
*/
public void setMultithreaded(boolean multithreaded) {
assertNotClosed();
this.multithreaded = multithreaded;
}
/**
* Returns the value of the multithreaded flag, which XORM
* blithely ignores.
*/
public boolean getMultithreaded() {
assertNotClosed();
return multithreaded;
}
/**
* Sets the value of the ignoreCache flag. Currently this suggestion
* is given little attention.
*/
public void setIgnoreCache(boolean ignoreCache) {
assertNotClosed();
this.ignoreCache = ignoreCache;
}
/**
* Returns the value of the ignoreCache flag. Not that it will
* do you much good.
*/
public boolean getIgnoreCache() {
assertNotClosed();
return ignoreCache;
}
/**
* Creates a new query that the user must set values on
* using the Query interface.
*/
public Query newQuery() {
assertNotClosed();
return new QueryImpl(this);
}
/** Constructs a query by copying data from a previous query. */
public Query newQuery(Object compiled) {
assertNotClosed();
if (compiled instanceof QueryImpl) {
return new QueryImpl(this, (QueryImpl) compiled);
}
throw new UnsupportedOperationException();
}
/**
* Known languages are "javax.jdo.query.JDOQL" (which takes a
* String), "org.xorm.query.CodeQuery" (use CodeQuery.LANGUAGE), and
* QueryLanguage.LANGUAGE.
*/
public Query newQuery(String language, Object query) {
assertNotClosed();
if (QueryLanguage.LANGUAGE.equals(language)) {
return new QueryImpl(this, (QueryLanguage) query);
} else if (JDOQL_LANGUAGE.equals(language)) {
return newQuery((Class) null, (String) query);
} else if (CodeQuery.LANGUAGE.equals(language)) {
// First try to get Expression directly.
try {
return new QueryImpl(this, new CodeParser((Class) query));
} catch (Throwable e) {
// Code could not be turned into JDOQL.
return new CodeQuery(this, (Class) query);
}
}
throw new UnsupportedOperationException();
}
/** This operation is not currently supported. */
public Query newQuery(Class clazz, Collection extent) {
assertNotClosed();
throw new UnsupportedOperationException();
}
/** This operation is not currently supported. */
public Query newQuery(Class clazz, Collection extent, String filter) {
assertNotClosed();
throw new UnsupportedOperationException();
}
/**
* Returns a new objectId corresponding to the given class and
* String parameter.
*/
public Object newObjectIdInstance(Class clazz, String arg) {
assertNotClosed();
return JDOImplHelper.getInstance().newObjectIdInstance(clazz, arg);
}
/**
* At present, this is the same as getObjectId().
* Changing an ObjectId is not supported.
*/
public Object getTransactionalObjectId(Object object) {
return getObjectId(object);
}
/** This operation is not currently supported. */
public void retrieve(Object object) {
assertNotClosed();
throw new UnsupportedOperationException();
}
/** This operation is not currently supported. */
public void retrieveAll(Collection collection) {
retrieveAll(collection, false);
}
/** This operation is not currently supported. */
public void retrieveAll(Collection collection, boolean dfgOnly) {
assertNotClosed();
Iterator i = collection.iterator();
while (i.hasNext()) {
retrieve(i.next());
}
}
/** This operation is not currently supported. */
public void retrieveAll(Object[] array) {
retrieveAll(array, false);
}
/** This operation is not currently supported. */
public void retrieveAll(Object[] array, boolean dfgOnly) {
assertNotClosed();
for (int i = 0; i < array.length; i++) {
retrieve(array[i]);
}
}
/**
* When an InterfaceManager is garbage collected,
* ensure that any active transactions are closed.
*/
public void finalize() {
if (!closed) {
try {
closeImpl(false);
} catch (Exception e) {
logger.severe(I18N.msg("W_mgr_finalize"));
}
}
}
}