package org.jboss.ejb.plugins.cmp.jdbc;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.ejb.FinderException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.GenericEntityObjectFactory;
import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
import org.jboss.logging.Logger;
public final class JDBCCustomFinderQuery implements JDBCQueryCommand
{
private final Logger log;
private final Method finderMethod;
private final JDBCReadAheadMetaData readAheadMetaData;
private final ReadAheadCache readAheadCache;
private final JDBCStoreManager manager;
public JDBCCustomFinderQuery(JDBCStoreManager manager, Method finderMethod)
{
this.finderMethod = finderMethod;
this.manager = manager;
JDBCReadAheadMetaData readAheadMetaData = manager.getMetaData().getReadAhead();
if((readAheadMetaData != null) && readAheadMetaData.isOnLoad())
{
this.readAheadCache = manager.getReadAheadCache();
this.readAheadMetaData = readAheadMetaData;
}
else
{
this.readAheadCache = null;
this.readAheadMetaData = null;
}
this.log = Logger.getLogger(
this.getClass().getName() +
"." +
manager.getMetaData().getName() +
"." +
finderMethod.getName());
if(log.isDebugEnabled())
log.debug("Finder: Custom finder " + finderMethod.getName());
}
public JDBCStoreManager getSelectManager()
{
return manager;
}
public Collection execute(Method unused,
Object[] args,
EntityEnterpriseContext ctx,
GenericEntityObjectFactory factory)
throws FinderException
{
try
{
Object value = finderMethod.invoke(ctx.getInstance(), args);
if(value instanceof Enumeration)
{
Enumeration enum = (Enumeration)value;
List result = new ArrayList();
while(enum.hasMoreElements())
{
result.add(enum.nextElement());
}
cacheResults(result);
return GenericEntityObjectFactory.UTIL.getEntityCollection(factory, result);
}
else if(value instanceof Collection)
{
List result;
if (value instanceof List)
result = (List)value;
else
result = new ArrayList((Collection)value);
cacheResults(result);
return GenericEntityObjectFactory.UTIL.getEntityCollection(factory, result);
}
else
{
return Collections.singleton(factory.getEntityEJBObject(value));
}
}
catch(IllegalAccessException e)
{
log.error("Error invoking custom finder " + finderMethod.getName(), e);
throw new FinderException("Unable to access finder implementation: " +
finderMethod.getName());
}
catch(IllegalArgumentException e)
{
log.error("Error invoking custom finder " + finderMethod.getName(), e);
throw new FinderException("Illegal arguments for finder " +
"implementation: " + finderMethod.getName());
}
catch(InvocationTargetException e)
{
Throwable ex = e.getTargetException();
if( ex instanceof FinderException )
{
throw (FinderException) ex;
}
else
{
throw new FinderException("Errror invoking cutom finder " +
finderMethod.getName() + ": " + ex);
}
}
}
private void cacheResults(List listOfPKs)
{
if(readAheadCache != null)
{
readAheadCache.addFinderResults(listOfPKs, readAheadMetaData);
}
}
}