You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by lu...@apache.org on 2004/11/08 10:45:17 UTC
cvs commit: jakarta-slide/src/stores/org/apache/slide/index/lucene AbstractLuceneIndexer.java
luetzkendorf 2004/11/08 01:45:17
Added: src/stores/org/apache/slide/index/lucene
AbstractLuceneIndexer.java
Log:
factored out the AbstractLuceneIndexer
Revision Changes Path
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/AbstractLuceneIndexer.java
Index: AbstractLuceneIndexer.java
===================================================================
/*
*
* ====================================================================
*
* Copyright 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.slide.index.lucene;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.apache.commons.transaction.util.LoggerFacade;
import org.apache.commons.transaction.util.xa.AbstractTransactionalResource;
import org.apache.commons.transaction.util.xa.AbstractXAResource;
import org.apache.commons.transaction.util.xa.TransactionalResource;
import org.apache.slide.common.AbstractServiceBase;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.ServiceConnectionFailedException;
import org.apache.slide.common.ServiceDisconnectionFailedException;
import org.apache.slide.common.ServiceInitializationFailedException;
import org.apache.slide.common.ServiceParameterErrorException;
import org.apache.slide.common.ServiceParameterMissingException;
import org.apache.slide.common.ServiceResetFailedException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.search.IndexException;
import org.apache.slide.search.basic.IBasicExpressionFactory;
import org.apache.slide.store.IndexStore;
import org.apache.slide.util.logger.Logger;
import org.apache.slide.util.logger.TxLogger;
/**
* Common base class for lucene bases index stores.
*/
public abstract class AbstractLuceneIndexer extends AbstractServiceBase implements
IndexStore
{
private static final String INCLUDE_PARAM = "includes";
private static final String INDEX_PATH_PARAM = "indexpath";
private static final String ASYNC_INDEX_PARAM = "asynchron";
private static final String PRIORITY_PARAM = "priority";
private static final String OPT_THESHOLD_PARAM = "optimization-threshold";
/**
* XAResource implementation to delegate all XAResource requests to.
*/
private XAResourceImpl xaResource = null;
private boolean started = false;
protected Index index = null;
protected IndexConfiguration indexConfiguration = new IndexConfiguration();
private Collection includes;
protected AbstractLuceneIndexer() {
TxLogger txLogger = new TxLogger(getLogger(), LOG_CHANNEL);
this.xaResource = new XAResourceImpl(txLogger);
}
public void initialize(NamespaceAccessToken token)
throws ServiceInitializationFailedException
{
debug("initialize");
this.indexConfiguration.setNamespaceName(token.getName());
}
public void setParameters(Hashtable parameters)
throws ServiceParameterErrorException,
ServiceParameterMissingException
{
String indexpath = (String) parameters.get(INDEX_PATH_PARAM);
if (indexpath == null || indexpath.length() == 0) {
throw new ServiceParameterMissingException(this, INDEX_PATH_PARAM);
}
this.indexConfiguration.setIndexPath(indexpath);
this.indexConfiguration.setIndexAsynchron(
"true".equals(parameters.get(ASYNC_INDEX_PARAM)));
String p = (String)parameters.get(PRIORITY_PARAM);
if (p != null) {
try {
this.indexConfiguration.setPriority(Integer.parseInt(p));
} catch (NumberFormatException e) {
error("Invalid " + PRIORITY_PARAM + " parameter: {0} ({1})", p, e);
}
}
p = (String)parameters.get(OPT_THESHOLD_PARAM);
if (p != null) {
try {
this.indexConfiguration.setOptimizeThreshold(Integer.parseInt(p));
} catch (NumberFormatException e) {
error("Invalid " + OPT_THESHOLD_PARAM + " parameter: {0} ({1})", p, e);
}
}
String includes = (String) parameters.get(INCLUDE_PARAM);
if (includes != null && includes.length() > 0) {
StringTokenizer tokenizer = new StringTokenizer(includes, ",");
this.includes = new ArrayList(tokenizer.countTokens());
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (!token.endsWith("/")) token = token + "/";
this.includes.add(token);
}
}
}
protected boolean isIncluded(String uri)
{
if (includes == null) {
return true;
}
Iterator iter = includes.iterator();
while (iter.hasNext()) {
if (uri.startsWith((String) iter.next())) {
return true;
}
}
return false;
}
/**
* Deletes service underlying data source, if possible (and meaningful).
*
* @exception ServiceResetFailedException
* Reset failed
*/
public void reset() throws ServiceResetFailedException
{
debug("reset");
// TODO should this empty the index?
}
/**
* Method getFactory
*
* @return an IBasicExpressionFactory
*
*/
public IBasicExpressionFactory getBasicExpressionFactory()
{
return new LuceneExpressionFactory(this.index);
}
// -- Service methods ------------------------------------------------------
/**
* Connects to the underlying data source (if any is needed).
*
* @exception ServiceConnectionFailedException
* Connection failed
*/
public void connect() throws ServiceConnectionFailedException
{
debug("connect");
this.index.start();
started = true;
}
/**
* This function tells whether or not the service is connected.
*
* @return boolean true if we are connected
* @exception ServiceAccessException
* Service access error
*/
public boolean isConnected() throws ServiceAccessException
{
return started;
}
/**
* Disconnects from the underlying data source.
*
* @exception ServiceDisconnectionFailedException
* Disconnection failed
*/
public void disconnect() throws ServiceDisconnectionFailedException
{
debug("disconnect");
this.index.stop();
started = false;
}
// -------------------------------------------------------------------------
// XAResource interface, all request are deletgated to this.xaResource
public void commit(Xid xid, boolean onePhase) throws XAException
{
this.xaResource.commit(xid, onePhase);
}
public void end(Xid xid, int flags) throws XAException
{
this.xaResource.end(xid, flags);
}
public void forget(Xid xid) throws XAException
{
this.xaResource.forget(xid);
}
public int getTransactionTimeout() throws XAException
{
return this.xaResource.getTransactionTimeout();
}
public boolean isSameRM(XAResource xares) throws XAException
{
return this.xaResource != null && this.xaResource.isSameRM(xares); // ??
}
public int prepare(Xid xid) throws XAException
{
return this.xaResource.prepare(xid);
}
public Xid[] recover(int flag) throws XAException
{
return this.xaResource.recover(flag);
}
public void rollback(Xid xid) throws XAException
{
this.xaResource.rollback(xid);
}
public boolean setTransactionTimeout(int sec) throws XAException
{
return this.xaResource.setTransactionTimeout(sec);
}
public void start(Xid xid, int flags) throws XAException
{
this.xaResource.start(xid, flags);
}
//--------------------------------------------------------------------------
protected TransactionalIndexResource getCurrentTxn() {
return xaResource.getCurrentTxn();
}
protected TransactionalResource createTransactionResource(Xid xid)
throws Exception
{
return new TransactionalIndexResource(xid, index);
}
private class XAResourceImpl extends AbstractXAResource
{
private LoggerFacade loggerFacade;
XAResourceImpl(LoggerFacade loggerFacade)
{
this.loggerFacade = loggerFacade;
}
protected TransactionalResource createTransactionResource(Xid xid)
throws Exception
{
return AbstractLuceneIndexer.this.createTransactionResource(xid);
}
TransactionalIndexResource getCurrentTxn() {
return (TransactionalIndexResource)getCurrentlyActiveTransactionalResource();
}
protected LoggerFacade getLoggerFacade()
{
return this.loggerFacade;
}
protected boolean includeBranchInXid()
{
return true;
}
public boolean isSameRM(XAResource xares) throws XAException
{
return xares == this;
}
public Xid[] recover(int flag) throws XAException
{
// TODO Auto-generated method stub
return null;
}
public int getTransactionTimeout() throws XAException
{
return 0;
}
public boolean setTransactionTimeout(int seconds) throws XAException
{
return false;
}
}
/**
* Simple transaction resource that stores index jobs in memory and
* schedules them at the index on commit.
*/
protected static class TransactionalIndexResource extends
AbstractTransactionalResource
{
private Index idx;
private Set indexJobs = new HashSet();
private Set removeJobs = new HashSet();
TransactionalIndexResource(Xid xid, Index index)
{
super(xid);
this.idx = index;
}
void addIndexJob(Uri uri, NodeRevisionDescriptor descriptor) {
this.indexJobs.add(this.idx.createIndexJob(uri, descriptor));
}
void addIndexJob(Uri uri, NodeRevisionDescriptor descriptor,
InputStream content) {
this.indexJobs.add(this.idx.createIndexJob(uri, descriptor, content));
}
void addRemoveJob(Uri uri, NodeRevisionNumber version) {
Index.IndexJob job = this.idx.createDeleteJob(uri, version);
this.indexJobs.remove(job);
this.removeJobs.add(job);
}
void addUpdateJob(Uri uri,
NodeRevisionDescriptor descriptor) {
Index.IndexJob job = this.idx.createIndexJob(uri, descriptor);
this.removeJobs.add(job);
this.indexJobs.add(job);
}
void addUpdateJob(Uri uri,
NodeRevisionDescriptor descriptor,
InputStream content)
{
Index.IndexJob job = this.idx.createIndexJob(uri, descriptor, content);
this.removeJobs.add(job);
this.indexJobs.add(job);
}
public void begin() throws XAException
{
}
public void commit() throws XAException
{
try {
this.idx.scheduleIndexTransaction(this.removeJobs, this.indexJobs);
} catch (IndexException e) {
throw new XAException(e.toString());
}
}
public int prepare() throws XAException
{
return 0;
}
public void resume() throws XAException
{
}
public void rollback() throws XAException
{
}
public void suspend() throws XAException
{
}
}
void info(String msg)
{
if (this.getLogger().isEnabled(Logger.INFO)) {
this.getLogger().log(msg, LOG_CHANNEL, Logger.INFO);
}
}
void info(String msg, Object o)
{
if (this.getLogger().isEnabled(Logger.INFO)) {
Object[] args = { o};
this.getLogger().log(MessageFormat.format(msg, args), LOG_CHANNEL,
Logger.INFO);
}
}
void debug(String msg)
{
if (this.getLogger().isEnabled(Logger.DEBUG)) {
this.getLogger().log(msg, LOG_CHANNEL, Logger.DEBUG);
}
}
void debug(String msg, Object o1, Object o2)
{
if (this.getLogger().isEnabled(Logger.DEBUG)) {
Object[] args = { o1, o2};
this.getLogger().log(MessageFormat.format(msg, args), LOG_CHANNEL,
Logger.DEBUG);
}
}
void error(String msg, Object o1)
{
if (this.getLogger().isEnabled(Logger.ERROR)) {
Object[] args = { o1};
this.getLogger().log(MessageFormat.format(msg, args), LOG_CHANNEL,
Logger.ERROR);
}
}
void error(String msg, Object o1, Object o2)
{
if (this.getLogger().isEnabled(Logger.ERROR)) {
Object[] args = { o1, o2};
this.getLogger().log(MessageFormat.format(msg, args), LOG_CHANNEL,
Logger.ERROR);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org