/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S. Chassande-Barrioz
*
*/
package org.objectweb.speedo.query.lib;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.jorm.api.PMapper;
import org.objectweb.medor.eval.prefetch.api.PrefetchBufferFactory;
import org.objectweb.medor.eval.prefetch.lib.PrefetchBufferFactoryImpl;
import org.objectweb.medor.lib.Log;
import org.objectweb.perseus.cache.api.CacheEntryFactory;
import org.objectweb.perseus.cache.api.CacheEvent;
import org.objectweb.perseus.cache.api.CacheEventListener;
import org.objectweb.perseus.cache.api.CacheException;
import org.objectweb.perseus.cache.api.CacheManager;
import org.objectweb.perseus.cache.api.FixableCacheEntry;
import org.objectweb.speedo.mapper.api.JormFactory;
import org.objectweb.speedo.pm.api.POManagerFactoryItf;
import org.objectweb.speedo.query.api.CompiledQuery;
import org.objectweb.speedo.query.api.QueryDefinition;
import org.objectweb.speedo.query.api.QueryManager;
import org.objectweb.speedo.query.api.QueryManagerAttribute;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.LoggerFactory;
/**
* SpeedoQueryManager manages the association between SpeedoQuery and the
* the compiled query: SpeedoCompiledQuery.
*
* @author S.Chassande-Barrioz
*/
public abstract class SpeedoQueryManager
implements QueryManager, CacheEntryFactory, CacheEventListener, BindingController, QueryManagerAttribute {
public final static String MAPPER_BINDING = "mapper";
public final static String JORM_FACTORY_BINDING = "jorm-factory";
public final static String COMPILED_QUERY_CACHE_BINDING = "compiled-query-cache";
public final static String PMF_BINDING = "po-manager-factory";
protected PMapper mapper = null;
protected JormFactory jormFactory = null;
private CacheManager compiledQueriesCache = null;
protected PrefetchBufferFactory prefetchBufferFactory;
/**
* The PMF
*/
private POManagerFactoryItf pmf = null;
protected Logger logger = null;
protected Logger cqlogger = null;
protected Logger cqpvlogger = null;
protected Logger cqpflogger = null;
private boolean prefetchingOnQuery = true;
private boolean prefetchingOnExtent = true;
/**
* creates a new SpeedoQueryManager object.
*/
public SpeedoQueryManager() {
prefetchBufferFactory = new PrefetchBufferFactoryImpl();
}
public FixableCacheEntry create(Object id, Object obj) {
return (CompiledQuery) obj;
}
public boolean getPrefetchActivatedOnQuery() {
return prefetchingOnQuery;
}
public void setPrefetchActivatedOnQuery(boolean prefetch) {
prefetchingOnQuery = prefetch;
}
public boolean getPrefetchActivatedOnExtent() {
return prefetchingOnExtent;
}
public void setPrefetchActivatedOnExtent(boolean prefetch) {
prefetchingOnExtent = prefetch;
}
// IMPLEMENTATION OF UserBindingController INTERFACE //
//---------------------------------------------------//
public String[] listFc() {
return new String[] {
MAPPER_BINDING,
JORM_FACTORY_BINDING,
COMPILED_QUERY_CACHE_BINDING,
PMF_BINDING
};
}
public Object lookupFc(String s) {
if (MAPPER_BINDING.equals(s))
return mapper;
else if (JORM_FACTORY_BINDING.equals(s))
return jormFactory;
else if (COMPILED_QUERY_CACHE_BINDING.equals(s))
return compiledQueriesCache;
else if (PMF_BINDING.equals(s))
return pmf;
else
return null;
}
public void bindFc(String s, Object o) {
if ("monolog-factory".equals(s)) {
Log.loggerFactory = (LoggerFactory) o;
String bn = logger.getName();
cqlogger = Log.loggerFactory.getLogger(bn + ".compiled-query");
cqpvlogger = Log.loggerFactory.getLogger(cqlogger.getName() + ".parser.variable");
cqpflogger = Log.loggerFactory.getLogger(cqlogger.getName() + ".parser.filter");
logger = Log.loggerFactory.getLogger(cqlogger.getName() + ".allocator");
} else if ("logger".equals(s)) {
logger = (Logger) o;
} else if (PMF_BINDING.equals(s)) {
pmf = (POManagerFactoryItf) o;
} else if (MAPPER_BINDING.equals(s))
mapper = (PMapper) o;
else if (COMPILED_QUERY_CACHE_BINDING.equals(s))
compiledQueriesCache = (CacheManager) o;
else if (JORM_FACTORY_BINDING.equals(s))
jormFactory = (JormFactory) o;
}
public void unbindFc(String s) {
if (MAPPER_BINDING.equals(s))
mapper = null;
else if (JORM_FACTORY_BINDING.equals(s))
jormFactory = null;
else if (COMPILED_QUERY_CACHE_BINDING.equals(s))
compiledQueriesCache = null;
}
// IMPLEMENTATION OF CacheEventListener INTERFACE //
//------------------------------------------------//
/**
* An entry has been added in the cache.
* @param event describes the added entry
*/
public void entryBound(CacheEvent event) {
}
/**
* An entry has been evicted from the cache.
* @param event describes the evicted entry
*/
public void entryUnbound(CacheEvent event) {
}
// IMPLEMENTATION OF QueryManager INTERFACE //
//------------------------------------------//
/**
* returns a CompiledQuery implementation, creates it if it does not exists,
* or just returns an existing one.
* @param qd a QueryDefinition
* @return a (new/existing) CompiledQuery instance.
*/
public synchronized CompiledQuery getQueryCompiler(QueryDefinition qd) {
CompiledQuery cq = (CompiledQuery) compiledQueriesCache.lookup(qd);
if (cq == null) {
if (logger.isLoggable(BasicLevel.DEBUG)) {
logger.log(BasicLevel.DEBUG, "Allocation of a new compiled query: "
+ qd.qdToString(false));
}
cq = createCompileQuery(qd);
qd.withPrefetch(prefetchingOnExtent && qd.withPrefetch());
try {
compiledQueriesCache.bind(cq.getCeIdentifier(), cq);
} catch (CacheException e) {
logger.log(BasicLevel.WARN,
"Impossible to bind a new compiled query from the cache: ", e);
//nothing to do, the compiled query is not cached
}
} else {
if (logger.isLoggable(BasicLevel.DEBUG)) {
logger.log(BasicLevel.DEBUG, "Reuse a compiled query: "
+ qd.qdToString(false));
}
}
return cq;
}
public POManagerFactoryItf getPMF() {
return pmf;
}
public void setPMF(POManagerFactoryItf pmf) {
this.pmf = pmf;
}
public void clean() {
try {
//clean the compiled query cache
compiledQueriesCache.unbindAll();
} catch (CacheException e) {
logger.log(BasicLevel.WARN,
"Impossible to clean the compiled query cache: ", e);
}
}
protected abstract CompiledQuery createCompileQuery(QueryDefinition qd);
}