/*
* Copyright 2000-2001,2004 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.jetspeed.components.persistence.store.ojb.otm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jetspeed.components.persistence.store.Filter;
import org.apache.jetspeed.components.persistence.store.PersistenceStore;
import org.apache.jetspeed.components.persistence.store.PersistenceStoreEventListener;
import org.apache.jetspeed.components.persistence.store.Transaction;
import org.apache.jetspeed.components.persistence.store.TransactionEventListener;
import org.apache.jetspeed.components.persistence.store.LockFailedException;
import org.apache.jetspeed.components.persistence.store.impl.StoreEventInvoker;
import org.apache.jetspeed.components.persistence.store.ojb.CriteriaFilter;
import org.apache.ojb.broker.Identity;
import org.apache.ojb.broker.PBKey;
import org.apache.ojb.broker.PersistenceBrokerFactory;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.otm.OTMConnection;
import org.apache.ojb.otm.kit.SimpleKit;
import org.apache.ojb.otm.lock.LockType;
import org.apache.ojb.otm.lock.LockingException;
/**
* <p>
* OTMStoreImpl
* </p>
* PersistenceStore implemnetation over the
* <a href="http://db.apache.org/ojb">ObjectRelationalBridge</a>
* <a href="http://db.apache.org/ojb/otm-tutorial.html">OTM</a> api
*
* @
* @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
* @version $ $
*
*/
public class OTMStoreImpl implements PersistenceStore
{
private List listeners;
private Transaction tx;
private OTMConnection OTMConn;
private SimpleKit kit;
private PBKey pbKey;
private StoreEventInvoker invoker;
private String jcd;
private static final Log log = LogFactory.getLog(OTMStoreImpl.class);
/**
* Name of the JavaConnectionDescriptor this store will use to access
* native OJB OTM functionallity.
* @param jcd Name of the JavaConnectionDescriptor to use.
* @see http://db.apache.org/ojb/repository.html#jdbc-connection-descriptor
*/
public OTMStoreImpl(String jcd)
{
this.listeners = new ArrayList();
kit = SimpleKit.getInstance();
invoker = new StoreEventInvoker(listeners, this);
this.jcd = jcd;
if (jcd != null)
{
pbKey = new PBKey(jcd);
}
else
{
pbKey = PersistenceBrokerFactory.getDefaultKey();
}
OTMConn = kit.acquireConnection(pbKey);
}
/**
* <p>
* addEventListener
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#addEventListener(org.apache.jetspeed.components.persistence.store.PersistenceStoreEventListener)
* @param listener
*/
public void addEventListener(PersistenceStoreEventListener listener)
{
listeners.add(listener);
}
/**
* <p>
* close
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#close()
*
*/
public void close()
{
try
{
invoker.beforeClose();
if (tx != null && tx.isOpen())
{
tx.commit();
}
if (OTMConn != null && !OTMConn.isClosed())
{
OTMConn.close();
}
}
catch (RuntimeException re)
{
if (tx != null && tx.isOpen())
{
tx.rollback();
}
throw re;
}
finally
{
tx = null;
invoker.afterClose();
}
}
/**
* <p>
* deletePersistent
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#deletePersistent(java.lang.Object)
* @param obj
*/
public void deletePersistent(Object obj) throws LockFailedException
{
try
{
invoker.beforeDeletePersistent(obj);
OTMConn.deletePersistent(obj);
invoker.afterDeletePersistent(obj);
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* <p>
* deleteAll
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#deleteAll(java.lang.Object)
* @param query
*/
public void deleteAll(Object query) throws LockFailedException
{
try
{
Iterator itr = getCollectionByQuery(query).iterator();
while (itr.hasNext())
{
OTMConn.deletePersistent(itr.next());
}
}
catch (Exception e)
{
log.warn("Problem encountered deleting objects", e);
}
}
/**
* <p>
* getCollectionByQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getCollectionByQuery(java.lang.Object)
* @param query
* @return
*/
public Collection getCollectionByQuery(Object query)
{
return getCollectionByQuery(query, LOCK_READ);
}
/**
* <p>
* getCollectionByQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getCollectionByQuery(java.lang.Object, int)
* @param query
* @param lockLevel
* @return
*/
public Collection getCollectionByQuery(Object query, int lockLevel)
{
int lock = LockType.READ_LOCK;
// Map to the OTM LockType
switch (lockLevel)
{
case LOCK_NO_LOCK :
lock = LockType.NO_LOCK;
case LOCK_PESSIMISTIC :
lock = LockType.WRITE_LOCK;
case LOCK_READ :
lock = LockType.READ_LOCK;
}
invoker.beforeLookup();
Collection results = OTMConn.getCollectionByQuery((Query) query, lock);
invoker.afterLookup(results);
return results;
}
/**
* <p>
* getObjectByQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getObjectByQuery(java.lang.Object)
* @param query
* @return
*/
public Object getObjectByQuery(Object query)
{
Collection results = getCollectionByQuery(query);
if (!results.isEmpty())
{
return results.iterator().next();
}
return null;
}
/**
* <p>
* getObjectByQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getObjectByQuery(java.lang.Object, int)
* @param query
* @param lockLevel
* @return
*/
public Object getObjectByQuery(Object query, int lockLevel)
{
Collection results = getCollectionByQuery(query, lockLevel);
if (!results.isEmpty())
{
return results.iterator().next();
}
return null;
}
/**
* <p>
* getObjectByIdentity
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getObjectByIdentity(java.lang.Object)
* @param object
* @return
*/
public Object getObjectByIdentity(Object object) throws LockFailedException
{
try
{
Identity oid = OTMConn.getIdentity(object);
invoker.beforeLookup();
Object obj = OTMConn.getObjectByIdentity(oid);
invoker.afterLookup(obj);
return obj;
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* <p>
* getObjectByIdentity
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getObjectByIdentity(java.lang.Object, int)
* @param object
* @param lockLevel
* @return
*/
public Object getObjectByIdentity(Object object, int lockLevel) throws LockFailedException
{
try
{
int lock = LockType.READ_LOCK;
// Map to the OTM LockType
switch (lockLevel)
{
case LOCK_NO_LOCK :
lock = LockType.NO_LOCK;
case LOCK_PESSIMISTIC :
lock = LockType.WRITE_LOCK;
case LOCK_READ :
lock = LockType.READ_LOCK;
}
Identity oid = OTMConn.getIdentity(object);
invoker.beforeLookup();
Object obj = OTMConn.getObjectByIdentity(oid, lock);
invoker.afterLookup(obj);
return obj;
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* <p>
* getCount
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getCount(java.lang.Object)
* @param query
* @return
*/
public int getCount(Object query)
{
return OTMConn.getCount((Query) query);
}
/**
* <p>
* getIteratorByQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getIteratorByQuery(java.lang.Object)
* @param query
* @return
*/
public Iterator getIteratorByQuery(Object query)
{
invoker.beforeLookup();
Iterator itr = OTMConn.getIteratorByQuery((Query) query);
invoker.afterLookup(itr);
return itr;
}
/**
* <p>
* getIteratorByQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getIteratorByQuery(java.lang.Object, int)
* @param query
* @param lockLevel
* @return
*/
public Iterator getIteratorByQuery(Object query, int lockLevel)
{
int lock = LockType.READ_LOCK;
// Map to the OTM LockType
switch (lockLevel)
{
case LOCK_NO_LOCK :
lock = LockType.NO_LOCK;
case LOCK_PESSIMISTIC :
lock = LockType.WRITE_LOCK;
case LOCK_READ :
lock = LockType.READ_LOCK;
}
invoker.beforeLookup();
Iterator itr = OTMConn.getIteratorByQuery((Query) query, lock);
invoker.afterLookup(itr);
return itr;
}
/**
* <p>
* isClose
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#isClose()
* @return
*/
public boolean isClosed()
{
return OTMConn.isClosed();
}
/**
* <p>
* getTransaction
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getTransaction()
* @return
*/
public Transaction getTransaction()
{
if (tx == null)
{
tx = new OTMTransactionImpl(OTMConn, kit, this);
for (int i = 0; i < listeners.size(); i++)
{
tx.addEventListener((TransactionEventListener) listeners.get(i));
}
}
return tx;
}
/**
* <p>
* invalidate
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#invalidate(java.lang.Object)
* @param obj
*/
public void invalidate(Object obj) throws LockFailedException
{
try
{
Identity oid = OTMConn.getIdentity(obj);
OTMConn.invalidate(oid);
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
public void invalidateAll() throws LockFailedException
{
try
{
OTMConn.invalidateAll();
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* <p>
* lockForWrite
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#lockForWrite(java.lang.Object)
* @param obj
*/
public void lockForWrite(Object obj) throws LockFailedException
{
try
{
OTMConn.lockForWrite(obj);
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* <p>
* makePersistent
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#makePersistent(java.lang.Object)
* @param obj
*/
public void makePersistent(Object obj) throws LockFailedException
{
try
{
invoker.beforeMakePersistent(obj);
OTMConn.makePersistent(obj);
invoker.afterMakePersistent(obj);
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* <p>
* newFilter
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#newFilter()
* @return
*/
public Filter newFilter()
{
return new CriteriaFilter();
}
/**
* <p>
* newQuery
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#newQuery(org.apache.jetspeed.components.persistence.store.Filter)
* @param filter
* @return
*/
public Object newQuery(Class clazz, Filter filter)
{
Criteria c = ((CriteriaFilter) filter).getOjbCriteria();
Query query = QueryFactory.newQuery(clazz, c);
return query;
}
/**
* <p>
* getExtent
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getExtent(java.lang.Class, int)
* @param clazz
* @param lcokLevel
* @return
*/
public Collection getExtent(Class clazz, int lockLevel)
{
Filter filter = newFilter();
Object query = newQuery(clazz, filter);
return getCollectionByQuery(query, lockLevel);
}
/**
* <p>
* getExtent
* </p>
*
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#getExtent(java.lang.Class)
* @param clazz
* @return
*/
public Collection getExtent(Class clazz)
{
return getExtent(clazz, LOCK_READ);
}
/**
* @param transaction
*/
protected void setTransaction(Transaction transaction)
{
tx = transaction;
}
/**
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#invalidateByQuery(java.lang.Object)
*/
public void invalidateByQuery(Object query) throws LockFailedException
{
Iterator itr = getCollectionByQuery(query).iterator();
try
{
while (itr.hasNext())
{
Identity oid = OTMConn.getIdentity(itr.next());
OTMConn.invalidate(oid);
}
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
/**
* @see org.apache.jetspeed.components.persistence.store.PersistenceStore#invalidateExtent(java.lang.Class)
*/
public void invalidateExtent(Class clazz) throws LockFailedException
{
Iterator itr = getExtent(clazz).iterator();
try
{
while (itr.hasNext())
{
Identity oid = OTMConn.getIdentity(itr.next());
OTMConn.invalidate(oid);
}
}
catch (LockingException e)
{
throw new LockFailedException(e.toString(), e);
}
}
}