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/10/18 11:27:36 UTC
cvs commit: jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions AbstractExpression.java BetweenExpression.java EqExpression.java GtExpression.java IsCollectionExpression.java IsDefinedExpression.java IsPrincipalExpression.java LikeExpression.java LtExpression.java MergeExpression.java PropcontainsExpression.java
luetzkendorf 2004/10/18 02:27:36
Added: src/stores/org/apache/slide/index/lucene Index.java
IndexConfiguration.java IndexException.java
LuceneExpressionFactory.java
LucenePropertiesIndexer.java
src/stores/org/apache/slide/index/lucene/expressions
AbstractExpression.java BetweenExpression.java
EqExpression.java GtExpression.java
IsCollectionExpression.java
IsDefinedExpression.java IsPrincipalExpression.java
LikeExpression.java LtExpression.java
MergeExpression.java PropcontainsExpression.java
Log:
added first version of lucene based properties indexer
Revision Changes Path
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/Index.java
Index: Index.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/Index.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.slide.util.logger.Logger;
/**
* Wrapper for Lucene index.
*/
public class Index
{
public static final String KEY_FIELD_NAME = "SLIDE_KEY";
public static final String URI_FIELD_NAME = "SLIDE_URI";
public static final String SCOPE_FIELD_NAME = "SLIDE_SCOPE";
public static final String VERSION_FIELD_NAME = "SLIDE_VERSION";
public static final String IS_DEFINED_FIELD_NAME = "SLIDE_ISDEFINED";
protected static final SimpleDateFormat DATE_INDEX_FORMAT =
new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.UK);
protected static final DecimalFormat INT_INDEX_FORMAT =
new DecimalFormat("b0000000000000000000;a0000000000000000000");
public static final String DATE_LOWER_BOUND = DATE_INDEX_FORMAT.format(new Date(0));
public static final String DATE_UPPER_BOUND = DATE_INDEX_FORMAT.format(new Date(Long.MAX_VALUE));
public static final String INT_LOWER_BOUND = INT_INDEX_FORMAT.format(Long.MIN_VALUE);
public static final String INT_UPPER_BOUND = INT_INDEX_FORMAT.format(Long.MAX_VALUE);
private Analyzer analyzer;
private IndexConfiguration configuration;
private String directoryName;
private Logger logger;
public Index(String directoryName, Analyzer analyzer, Logger logger) throws IndexException
{
this.directoryName = directoryName;
this.analyzer = analyzer;
this.logger = logger;
this.configuration = new IndexConfiguration();
this.configuration.initDefaultConfiguration();
File file = new File(this.directoryName);
if (!file.exists() && !file.mkdirs()) {
throw new IndexException(
"Error can't get or create index directory: ",
this.directoryName);
}
try {
Directory directory = getDirectory();
if (IndexReader.indexExists(directory)) {
if (IndexReader.isLocked(directory)) {
IndexReader.unlock(directory);
}
} else {
IndexWriter writer = new IndexWriter(directory,
this.analyzer, true);
writer.close();
}
} catch (IOException e) {
throw new IndexException("Error while creating index: ",
this.directoryName, e);
}
// TODO make configurable
BooleanQuery.setMaxClauseCount(10000);
}
public IndexConfiguration getConfiguration() {
return this.configuration;
}
public Logger getLogger() {
return this.logger;
}
public IndexSearcher getSearcher() throws IOException {
// TODO can this be reused?
return new IndexSearcher(this.directoryName);
}
private Directory getDirectory() throws IOException
{
// file system based directory
return FSDirectory.getDirectory(this.directoryName, false);
}
synchronized void addIndexJob(Map toAdd, Set toRemove) throws IOException {
// TODO make async by option
if (toRemove.size() > 0) {
IndexReader reader = IndexReader.open(getDirectory());
for(Iterator i = toRemove.iterator(); i.hasNext();) {
String key = (String)i.next();
reader.delete(new Term(Index.KEY_FIELD_NAME, key));
}
reader.close();
}
if (toAdd.size() > 0) {
IndexWriter writer = new IndexWriter(getDirectory(),
this.analyzer, false);
for(Iterator i = toAdd.values().iterator(); i.hasNext(); ) {
Document doc = (Document)i.next();
writer.addDocument(doc);
}
writer.close();
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/IndexConfiguration.java
Index: IndexConfiguration.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/IndexConfiguration.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.analysis.Analyzer;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionNumber;
import org.jdom.Element;
/**
*/
public class IndexConfiguration
{
private Set keywordProperties = new HashSet();
private Set textProperties = new HashSet();
private Set dateProperties = new HashSet();
private Set intProperties = new HashSet();
private Set supportsIsdefinedProperties = new HashSet();
private Set indexedProperties = new HashSet();
private Map analyzers = new HashMap();
public void addKeywordProperty(String namespace, String name) {
String key = namespace + name;
this.keywordProperties.add(key);
this.indexedProperties.add(key);
}
public boolean isKeywordProperty(NodeProperty property) {
return this.keywordProperties.contains(
property.getNamespace() + property.getName());
}
public void addTextProperty(String namespace, String name) {
String key = namespace + name;
this.textProperties.add(key);
this.indexedProperties.add(key);
}
public boolean isTextProperty(NodeProperty property) {
return this.textProperties.contains(
property.getNamespace() + property.getName());
}
public void addDateProperty(String namespace, String name) {
String key = namespace + name;
this.dateProperties.add(key);
this.indexedProperties.add(key);
}
public boolean isDateProperty(String namespace, String name) {
return this.dateProperties.contains(namespace + name);
}
public boolean isDateProperty(NodeProperty property) {
return isDateProperty(property.getNamespace(), property.getName());
}
public boolean isDateProperty(Element element) {
return isDateProperty(element.getNamespaceURI(), element.getName());
}
public void addIntProperty(String namespace, String name) {
String key = namespace + name;
this.intProperties.add(key);
this.indexedProperties.add(key);
}
public boolean isIntProperty(String namespace, String name) {
return this.intProperties.contains(namespace + name);
}
public boolean isIntProperty(NodeProperty property) {
return isIntProperty(property.getNamespace(), property.getName());
}
public boolean isIntProperty(Element element) {
return isIntProperty(element.getNamespaceURI(), element.getName());
}
public void addSupportsIsdefinedProperty(String namespace, String name) {
String key = namespace + name;
this.supportsIsdefinedProperties.add(key);
this.indexedProperties.add(key);
}
public boolean supportsIsDefined(String namespace, String name) {
return this.supportsIsdefinedProperties.contains(namespace + name);
}
public boolean supportsIsDefined(NodeProperty property) {
return supportsIsDefined(property.getNamespace(), property.getName());
}
public boolean supportsIsDefined(Element element) {
return supportsIsDefined(element.getNamespaceURI(), element.getName());
}
public boolean isIndexedProperty(String namespace, String name) {
return this.indexedProperties.contains(namespace + name);
}
public boolean isIndexedProperty(NodeProperty property) {
return isIndexedProperty(property.getNamespace(), property.getName());
}
public void addAnalyzer(String namespace, String name, Analyzer analyzer) {
this.analyzers.put(namespace + name, analyzer);
}
void initDefaultConfiguration() {
addKeywordProperty("DAV:", "displayname");
addKeywordProperty("DAV:", "getcontenttype");
addSupportsIsdefinedProperty("DAV:", "getcontenttype");
addKeywordProperty("DAV:", "getcontentlanguage");
addKeywordProperty("DAV:", "owner");
addSupportsIsdefinedProperty("DAV:", "owner");
addKeywordProperty("DAV:", "modificationuser");
addSupportsIsdefinedProperty("DAV:", "modificationuser");
addIntProperty("DAV:", "getcontentlength");
addDateProperty("DAV:", "getlastmodified");
addDateProperty("DAV:", "creationdate");
addDateProperty("DAV:", "modificationdate");
}
// ------ data type helper -------------------------------------------------
/**
* Generates a field name for "normal fields".
*/
public String generateFieldName(String namespaceUri, String name) {
return namespaceUri + name;
}
public String generateFieldName(NodeProperty property) {
return generateFieldName(property.getNamespace(), property.getName());
}
public String generateFieldName(Element element) {
return generateFieldName(element.getNamespaceURI(), element.getName());
}
public String generateKey(Uri uri, NodeRevisionNumber number) {
return uri.toString() + "#" + number;
}
public String dateToIndexString(Date date) {
synchronized (Index.DATE_INDEX_FORMAT) {
return Index.DATE_INDEX_FORMAT.format(date);
}
}
public static String intToIndexString(long value) {
synchronized (Index.INT_INDEX_FORMAT) {
if (value >= 0) {
return Index.INT_INDEX_FORMAT.format(value);
} else {
return Index.INT_INDEX_FORMAT.format(-(Long.MAX_VALUE + value));
}
}
}
private static final SimpleDateFormat formats[] = {
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
};
/**
* Helper that converts property values to dates.
* @param value
* @return a date of <code>null</code> if value can't convert
*/
public static Date getDateValue(Object value) {
if (value instanceof Date) {
return (Date)value;
} else {
String valstr = value.toString();
// Parsing the HTTP Date
for (int i = 0; i < formats.length; i++) {
try {
synchronized (formats[i]) {
return formats[i].parse(valstr);
}
} catch (ParseException e) {
}
}
return null;
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/IndexException.java
Index: IndexException.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/IndexException.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.text.MessageFormat;
/**
*/
class IndexException extends Exception
{
public IndexException()
{
super();
}
public IndexException(String message)
{
super(message);
}
public IndexException(String message, Object param)
{
super(MessageFormat.format(message, new Object[]{param}));
}
public IndexException(String message, Object param1, Object param2)
{
super(MessageFormat.format(message, new Object[]{param1, param2}));
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/LuceneExpressionFactory.java
Index: LuceneExpressionFactory.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/LuceneExpressionFactory.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.util.Collection;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.index.lucene.expressions.AbstractExpression;
import org.apache.slide.index.lucene.expressions.BetweenExpression;
import org.apache.slide.index.lucene.expressions.EqExpression;
import org.apache.slide.index.lucene.expressions.GtExpression;
import org.apache.slide.index.lucene.expressions.IsCollectionExpression;
import org.apache.slide.index.lucene.expressions.IsDefinedExpression;
import org.apache.slide.index.lucene.expressions.IsPrincipalExpression;
import org.apache.slide.index.lucene.expressions.LikeExpression;
import org.apache.slide.index.lucene.expressions.LtExpression;
import org.apache.slide.index.lucene.expressions.MergeExpression;
import org.apache.slide.index.lucene.expressions.PropcontainsExpression;
import org.apache.slide.search.BadQueryException;
import org.apache.slide.search.PropertyProvider;
import org.apache.slide.search.basic.BasicExpressionFactory;
import org.apache.slide.search.basic.IBasicExpression;
import org.apache.slide.search.basic.IBasicQuery;
import org.apache.slide.search.basic.Literals;
import org.jdom.Element;
/**
*/
public class LuceneExpressionFactory extends BasicExpressionFactory {
private Index index;
/**
* Constructor
*
*/
public LuceneExpressionFactory(Index index) {
this.index = index;
}
public IBasicExpression createMergeExpression (String mergeOperator,
String namespace,
Collection expressionsToMerge)
throws BadQueryException
{
IBasicExpression result = null;
// TODO what if expressionsToMerge contains non lucene expressions
if (namespace.equals (NodeProperty.NamespaceCache.DEFAULT_URI)) {
if (mergeOperator.equals(Literals.OR)) {
result = new MergeExpression(this.index, false, expressionsToMerge);
}
else if (mergeOperator.equals(Literals.AND)) {
result = new MergeExpression(this.index, true, expressionsToMerge);
}
else {
// TODO
}
}
if (result != null) {
result.setFactory(this);
}
// TODO
return result;
}
public IBasicExpression createExpression (Element element)
throws BadQueryException
{
IBasicExpression result = null;
if (element == null)
{
throw new BadQueryException ("expected a where criteria");
}
else
{
String namespace = element.getNamespace().getURI();
if (namespace.equals (NodeProperty.NamespaceCache.DEFAULT_URI)) {
result = createDAVExpression(element);
}
else if (namespace.equals(NodeProperty.NamespaceCache.SLIDE_URI)) {
result = createSlideExpression(element);
}
else {
result = super.createExpression(element);
}
}
if (result != null) {
result.setFactory(this);
}
return result;
}
private IBasicExpression createDAVExpression (Element e)
throws BadQueryException
{
String name = e.getName();
if (name.equals(Literals.EQ)) {
return new EqExpression(this.index, e, false);
}
else if (name.equals(Literals.NOT_EQ)) {
return new EqExpression(this.index, e, true);
}
else if (name.equals(Literals.LT) || name.equals(Literals.NOT_GTE)) {
return new LtExpression(this.index, e, false);
}
else if (name.equals(Literals.LTE) || name.equals(Literals.NOT_GT)) {
return new LtExpression(this.index, e, true);
}
else if (name.equals(Literals.GT) || name.equals(Literals.NOT_LTE)) {
return new GtExpression(this.index, e, false);
}
else if (name.equals(Literals.GTE) || name.equals(Literals.NOT_LT)) {
return new GtExpression(this.index, e, true);
}
else if (name.equals(Literals.ISCOLLECTION)) {
return new IsCollectionExpression(this.index, false);
}
else if (name.equals(Literals.NOT_ISCOLLECTION)) {
return new IsCollectionExpression(this.index, true);
}
else if (name.equals(Literals.LIKE)) {
return new LikeExpression(this.index, e);
}
else if (name.equals(Literals.ISDEFINED)) {
Element property = AbstractExpression.getPropertyElement(e);
if (index.getConfiguration().supportsIsDefined(property)) {
return new IsDefinedExpression(this.index, e, false);
}
}
else if (name.equals(Literals.NOT_ISDEFINED)) {
Element property = AbstractExpression.getPropertyElement(e);
if (index.getConfiguration().supportsIsDefined(property)) {
return new IsDefinedExpression(this.index, e, true);
}
}
return super.createExpression(e);
}
private IBasicExpression createSlideExpression (Element e)
throws BadQueryException
{
String name = e.getName();
if (name.equals(Literals.ISPRINCIPAL)) {
return new IsPrincipalExpression(this.index, false);
}
if (name.equals(Literals.NOT_ISPRINCIPAL)) {
return new IsPrincipalExpression(this.index, true);
}
if (name.equals(Literals.PROPCONTAINS)) {
return new PropcontainsExpression(this.index, e);
}
if (name.equals("between")) {
return new BetweenExpression(this.index, e, false);
}
if (name.equals("between-inclusive")) {
return new BetweenExpression(this.index, e, true);
}
return super.createExpression(e);
}
/**
* called by BasicExpressionCompiler after construction.
*
* @param query the associated BasicQuery
* @param propertyProvider the PropertyProvider for this expression.
*
* @throws BadQueryException
*
*/
public void init(IBasicQuery query, PropertyProvider propertyProvider)
throws BadQueryException
{
this.query = (IBasicQuery) query;
this.propertyProvider = propertyProvider;
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/LucenePropertiesIndexer.java
Index: LucenePropertiesIndexer.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.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
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.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
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.NodeProperty;
import org.apache.slide.content.NodeRevisionContent;
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;
/**
* IndexStore implementation for indexing properties based on Jakarta Lucene.
*/
public class LucenePropertiesIndexer extends AbstractServiceBase implements
IndexStore
{
private static final String LOG_CHANNEL = LucenePropertiesIndexer.class
.getName();
private static final String INDEX_PATH = "indexpath";
private static final String INCLUDES = "includes";
private static final String ANALYZER = "analyzer";
public static final String URI_FIELD = "uri";
public static final String CONTENT_TEXT = "content";
//------------------
private String indexpath = "";
private Collection includes;
private String analyzerClassName;
private boolean started = false;
protected Index index = null;
private XAResourceImpl xaResource = null;
/**
* Create Index, if not yet done.
*
* @param token
* a NamespaceAccessToken
*
* @throws org.apache.slide.common.ServiceInitializationFailedException
*
*/
public void initialize(NamespaceAccessToken token)
throws ServiceInitializationFailedException
{
debug("initialize");
TxLogger txLogger = new TxLogger(getLogger(), LOG_CHANNEL);
this.xaResource = new XAResourceImpl(txLogger);
try {
this.index = new Index(this.indexpath, initAnalyzer(), getLogger());
}
catch (org.apache.slide.index.lucene.IndexException e) {
throw new ServiceInitializationFailedException(this, e);
}
}
/**
* Index an object content.
*
* @param uri
* Uri
* @exception IndexException
* Error accessing the Data Source
*/
public void createIndex(Uri uri,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent) throws IndexException
{
debug("createIndex {0} {1}", uri, revisionDescriptor.getRevisionNumber());
TransactionalIndexResource indexResource = xaResource.getCurrentTxn();
Document doc = createLuceneDocument(uri, revisionDescriptor);
indexResource.addIndexJob(uri,
revisionDescriptor.getRevisionNumber(), doc);
}
/**
* Method updateIndex
*
* @param uri
* an Uri
* @param revisionDescriptor
* a NodeRevisionDescriptor
* @param revisionContent
* a NodeRevisionContent
*
* @throws IndexException
*
*/
public void updateIndex(Uri uri,
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent) throws IndexException
{
debug("updateIndex {0} {1}", uri, revisionDescriptor
.getRevisionNumber());
boolean needsUpdate = false;
for(Enumeration e = revisionDescriptor.enumerateUpdatedProperties();e.hasMoreElements();) {
NodeProperty property = (NodeProperty)e.nextElement();
if(index.getConfiguration().isIndexedProperty(property)) {
needsUpdate = true;
break;
}
}
for(Enumeration e = revisionDescriptor.enumerateUpdatedProperties();!needsUpdate && e.hasMoreElements();) {
NodeProperty property = (NodeProperty)e.nextElement();
if(index.getConfiguration().isIndexedProperty(property)) {
needsUpdate = true;
break;
}
}
if (needsUpdate) {
TransactionalIndexResource indexResource = xaResource.getCurrentTxn();
Document doc = createLuceneDocument(uri, revisionDescriptor);
indexResource.addRemoveJob(uri, revisionDescriptor.getRevisionNumber());
indexResource.addIndexJob(uri, revisionDescriptor.getRevisionNumber(), doc);
}
}
/**
* Drop an object revision from the index.
*
* @param uri
* Uri
* @exception IndexException
*/
public void dropIndex(Uri uri, NodeRevisionNumber number)
throws IndexException
{
debug("dropIndex {0} {1}", uri, number);
TransactionalIndexResource indexResource = xaResource.getCurrentTxn();
indexResource.addRemoveJob(uri, number);
}
private Field unstoredString(String fieldName, String value) {
return new Field(fieldName, value, false, true, false);
}
private Field storedString(String fieldName, String value) {
return new Field(fieldName, value, true, true, false);
}
private Document createLuceneDocument(Uri uri, NodeRevisionDescriptor descriptor) {
Document doc = new Document();
IndexConfiguration config = index.getConfiguration();
doc.add(unstoredString(Index.KEY_FIELD_NAME,
config.generateKey(uri, descriptor.getRevisionNumber())));
doc.add(storedString(Index.URI_FIELD_NAME, uri.toString()));
for(Enumeration e = uri.getScopes(); e.hasMoreElements();) {
doc.add(unstoredString(Index.SCOPE_FIELD_NAME, e.nextElement().toString()));
}
doc.add(unstoredString(Index.VERSION_FIELD_NAME,
descriptor.getRevisionNumber().toString()));
String rtype = descriptor.getResourceType();
if (rtype.indexOf("collection") != -1) {
doc.add(unstoredString(config.generateFieldName(
NodeProperty.DEFAULT_NAMESPACE, "resourcetype"),
"collection"));
if (rtype.indexOf("principal") != -1) {
doc.add(unstoredString(config.generateFieldName(
NodeProperty.DEFAULT_NAMESPACE, "resourcetype"),
"principal"));
}
}
for(Enumeration e = descriptor.enumerateProperties(); e.hasMoreElements();) {
NodeProperty property = (NodeProperty)e.nextElement();
Object value = property.getValue();
if (value == null) continue;
if (config.isKeywordProperty(property)) {
doc.add(unstoredString(config.generateFieldName(property), value.toString()));
}
if (config.isDateProperty(property)) {
Date date = config.getDateValue(value);
if (date != null) {
doc.add(unstoredString(config.generateFieldName(property),
config.dateToIndexString(date)));
}
}
if (config.isIntProperty(property)) {
try {
doc.add(unstoredString(config.generateFieldName(property),
config.intToIndexString(Long.parseLong(value.toString()))));
} catch (NumberFormatException ex) {
// TODO log warning
}
}
if (config.supportsIsDefined(property)) {
doc.add(unstoredString(Index.IS_DEFINED_FIELD_NAME,
config.generateFieldName(property)));
}
}
return doc;
}
/**
* Method getFactory
*
* @return an IBasicExpressionFactory
*
*/
public IBasicExpressionFactory getBasicExpressionFactory()
{
return new LuceneExpressionFactory(this.index);
}
/**
* Connects to the underlying data source (if any is needed).
*
* @exception ServiceConnectionFailedException
* Connection failed
*/
public void connect() throws ServiceConnectionFailedException
{
debug("connect");
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;
}
/**
* Parametrize the service. This index store expects a parameter
* "indexpath" to contain the path to the directory to store the index.
* Another optional parameter "includes" lists the paths of resources that
* are to be indexed in a comma-separated format. Everything under an
* included path is indexed. If not specified all resources will be
* indexed.
*
* @param parameters
* Hashtable containing the parameters' names and associated
* values
* @exception ServiceParameterErrorException
* Incorrect service parameter
* @exception ServiceParameterMissingException
* Service parameter missing
*/
public void setParameters(Hashtable parameters)
throws ServiceParameterErrorException,
ServiceParameterMissingException
{
indexpath = (String) parameters.get(INDEX_PATH);
if (indexpath == null || indexpath.length() == 0) {
throw new ServiceParameterMissingException(this, INDEX_PATH);
}
String includes = (String) parameters.get(INCLUDES);
if (includes != null && includes.length() > 0) {
StringTokenizer tokenizer = new StringTokenizer(includes, ",");
this.includes = new ArrayList(tokenizer.countTokens());
while (tokenizer.hasMoreTokens()) {
this.includes.add(tokenizer.nextToken());
}
}
analyzerClassName = (String) parameters.get(ANALYZER);
}
/**
* Disconnects from the underlying data source.
*
* @exception ServiceDisconnectionFailedException
* Disconnection failed
*/
public void disconnect() throws ServiceDisconnectionFailedException
{
debug("disconnect");
started = false;
}
/**
* Deletes service underlying data source, if possible (and meaningful).
*
* @exception ServiceResetFailedException
* Reset failed
*/
public void reset() throws ServiceResetFailedException
{
debug("reset");
}
protected Enumeration readProperties(
NodeRevisionDescriptor revisionDescriptor,
NodeRevisionContent revisionContent) throws IOException
{
Enumeration em = revisionDescriptor.enumerateProperties();
return em;
}
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;
}
protected Analyzer initAnalyzer() throws ServiceInitializationFailedException
{
if (analyzerClassName == null || analyzerClassName.length() == 0) {
info("using Lucene StandardAnalyzer");
return new StandardAnalyzer();
} else {
info("using Lucene analyzer: {0}", analyzerClassName);
try {
Class analyzerClazz = Class.forName(analyzerClassName);
return (Analyzer) analyzerClazz.newInstance();
} catch (ClassNotFoundException e) {
error("Error while instantiating analyzer {0} {1}",
analyzerClassName, e.getMessage());
throw new ServiceInitializationFailedException(this, e);
} catch (InstantiationException e) {
error("Error while instantiating analyzer {0} {1}",
analyzerClassName, e.getMessage());
throw new ServiceInitializationFailedException(this, e);
} catch (IllegalAccessException e) {
error("Error while instantiating analyzer {0} {1}",
analyzerClassName, e.getMessage());
throw new ServiceInitializationFailedException(this, e);
}
}
}
// -------------------------------------------------------------------------
// 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);
}
private class XAResourceImpl extends AbstractXAResource
{
private LoggerFacade loggerFacade;
XAResourceImpl(LoggerFacade loggerFacade)
{
this.loggerFacade = loggerFacade;
}
protected TransactionalResource createTransactionResource(Xid xid)
throws Exception
{
return new TransactionalIndexResource(xid, index);
}
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;
}
}
private static class TransactionalIndexResource extends
AbstractTransactionalResource
{
private Index idx;
private Map indexJobs = new HashMap();
private Set removeJobs = new HashSet();
TransactionalIndexResource(Xid xid, Index index)
{
super(xid);
this.idx = index;
}
void addIndexJob(Uri uri, NodeRevisionNumber version, Document doc) {
String key = idx.getConfiguration().generateKey(uri, version);
this.indexJobs.put(key, doc);
}
void addRemoveJob(Uri uri, NodeRevisionNumber version) {
String key = idx.getConfiguration().generateKey(uri, version);
this.indexJobs.remove(key);
this.removeJobs.add(key);
}
public void begin() throws XAException
{
}
public void commit() throws XAException
{
try {
this.idx.addIndexJob(this.indexJobs, this.removeJobs);
} catch (IOException 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);
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/AbstractExpression.java
Index: AbstractExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/AbstractExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import java.io.IOException;
import java.util.List;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.slide.common.SlideException;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.search.BadQueryException;
import org.apache.slide.search.InvalidScopeException;
import org.apache.slide.search.RequestedResource;
import org.apache.slide.search.SearchException;
import org.apache.slide.search.basic.BasicResultSetImpl;
import org.apache.slide.search.basic.ComparableResourceImpl;
import org.apache.slide.search.basic.IBasicExpression;
import org.apache.slide.search.basic.IBasicExpressionFactory;
import org.apache.slide.search.basic.IBasicQuery;
import org.apache.slide.search.basic.IBasicResultSet;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.util.logger.Logger;
import org.jdom.Element;
/**
* @author Stefan L�tzkendorf
*/
public abstract class AbstractExpression implements IBasicExpression
{
static final String LOG_CHANNEL = "org.apache.slide.index.lucene.expressions";
protected IBasicExpressionFactory factory;
protected Index index;
private Query query;
public AbstractExpression(Index index) {
this.index = index;
}
protected final void setQuery(Query query) {
this.query = query;
}
protected final Query getQuery() {
return this.query;
}
public IBasicExpressionFactory getFactory()
{
return factory;
}
public void setFactory(IBasicExpressionFactory factory)
{
this.factory = factory;
}
public IBasicResultSet execute() throws SearchException
{
Query luceneQuery = this.getQuery();
IBasicQuery q = factory.getQuery();
String scope = q.getSearchToken().getSlideContext().getSlidePath(q.getScope().getHref());
if (!scope.equals("/")) {
// add a scope restriction
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(luceneQuery, true, false);
booleanQuery.add(new TermQuery(new Term(Index.SCOPE_FIELD_NAME, scope)), true, false);
luceneQuery = booleanQuery;
}
IndexSearcher searcher = null;
try {
index.getLogger().log("start query execution: " + luceneQuery.toString(), LOG_CHANNEL, Logger.DEBUG);
long start = System.currentTimeMillis();
searcher = this.index.getSearcher();
Hits hits = searcher.search(luceneQuery);
index.getLogger().log("finished: " + hits.length() + " hits (" +
(System.currentTimeMillis() - start) + "s)" , LOG_CHANNEL, Logger.DEBUG);
IBasicResultSet result = new BasicResultSetImpl(false);
for (int i = 0, l = hits.length(); i < l; i++) {
Document doc = hits.doc(i);
String uri = doc.get(Index.URI_FIELD_NAME);
RequestedResource resource = createResource(uri);
result.add(resource);
}
return result;
} catch (InvalidScopeException e) {
throw e;
} catch (SearchException e) {
throw e;
} catch (IOException e) {
throw new SearchException(e);
} finally {
if (searcher != null) {
try {
searcher.close();
} catch (IOException e1) {
// ignore
}
}
}
}
protected Query getNegatedQuery(Query query) {
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(
new TermQuery(new Term(Index.SCOPE_FIELD_NAME, "/")),
true, false);
booleanQuery.add(
query,
false, true);
return booleanQuery;
}
protected RequestedResource createResource(String uri) throws SearchException
{
ObjectNode node = new SubjectNode(uri); // this will return the root
// folder
RequestedResource resource = null;
IBasicQuery query = factory.getQuery();
try {
resource = new ComparableResourceImpl(node, query.getSearchToken(),
query.getScope(), factory.getPropertyProvider());
} catch (SlideException e) {
throw new SearchException(e);
}
return resource;
}
protected static Element getFirstElement(Element node)
{
List children = node.getChildren();
for (int i = 0; i < children.size(); i++) {
if (children.get(i) instanceof Element) {
return (Element)children.get(i);
}
}
return null;
}
/**
* Returns the first <code>D:prop</code> element.
* @param operator
* @return Element
* @throws BadQueryException if element not found
*/
public static Element getPropertyElement(Element operator) throws BadQueryException
{
Element prop = operator.getChild("prop",
NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
if (prop == null) throw new BadQueryException("Missing prop element");
prop = getFirstElement(prop);
if (prop == null) throw new BadQueryException("Empty prop element given");
return prop;
}
/**
* Retruns the first <code>D:literal</code> element.
* @param operator
* @return
* @throws BadQueryException if element not found
*/
protected Element getLiteralElement(Element operator) throws BadQueryException
{
Element literal = operator.getChild("literal",
NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
if (literal == null) throw new BadQueryException("Missing literal element");
return literal;
}
protected Element getLiteral2Element(Element operator) throws BadQueryException
{
List children = operator.getChildren("literal",
NodeProperty.NamespaceCache.DEFAULT_NAMESPACE);
if (children.size() > 1) {
return (Element)children.get(1);
} else {
throw new BadQueryException("Missing second literal element");
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/BetweenExpression.java
Index: BetweenExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/BetweenExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* Implements a slide specific <code>between</code> operator.
*
* <p>
* With lucene <code>(between prop val1 val2)</code> will be much more efficient
* than <code>(and (gt prop1 val1) (lt prop val2))</code>.
*
* <p>TODO May be could optimize such expressions by transformation.
*
* <p>Usage:
* <pre>
* <searchrequest xmlns:D="DAV:" xmlns:S="http://jakarta.apache.org/slide/">
* <S:between>
* <D:prop><D:getlastmodified/></D:prop>
* <D:literal>Fri, 14 Oct 2004 10:00:00 GMT</D:literal>
* <D:literal>Fri, 15 Oct 2004 10:00:00 GMT</D:literal>
* </S:between>
* </pre>
*/
public class BetweenExpression extends AbstractExpression
{
public BetweenExpression(Index index, Element element, boolean inclusive)
throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
Element literal1 = getLiteralElement(element);
Element literal2 = getLiteral2Element(element);
String value1;
String value2;
if (index.getConfiguration().isDateProperty(prop)) {
value1 = config.dateToIndexString(
config.getDateValue(literal1.getTextTrim()));
value2 = config.dateToIndexString(
config.getDateValue(literal2.getTextTrim()));
}
else if (index.getConfiguration().isIntProperty(prop)) {
value1 = config.intToIndexString(Long.parseLong(literal1.getTextTrim()));
value2 = config.intToIndexString(Long.parseLong(literal2.getTextTrim()));
}
else {
value1 = literal1.getTextTrim();
value2 = literal2.getTextTrim();
}
int comp = value1.compareTo(value2);
if (comp == 0) {
// value1 == value2
setQuery(new TermQuery(new Term(field, value1)));
} else if (comp < 0) {
// value1 < value2
setQuery(new RangeQuery(
new Term(field, value1),
new Term(field, value2),
inclusive)); // inclusive or not
} else {
// value1 > value2
setQuery(new RangeQuery(
new Term(field, value2),
new Term(field, value1),
inclusive)); // inclusive or not
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/EqExpression.java
Index: EqExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/EqExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.TermQuery;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* Implements <code>eq</code> and <code>not-eq</code>.
*/
public class EqExpression extends AbstractExpression
{
public EqExpression(Index index, Element element, boolean negated)
throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
Element literal = getLiteralElement(element);
String value;
if (index.getConfiguration().isDateProperty(prop)) {
value = config.dateToIndexString(config.getDateValue(literal.getTextTrim()));
}
else if (index.getConfiguration().isIntProperty(prop)) {
value = config.intToIndexString(Long.parseLong(literal.getTextTrim()));
}
else {
value = literal.getTextTrim();
}
Term term = new Term(field, value);
setQuery(new TermQuery(term));
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/GtExpression.java
Index: GtExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/GtExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import java.util.Date;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.RangeQuery;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* Implements <code>gt</code> and <code>gte</code> expression.
*/
public class GtExpression extends AbstractExpression
{
public GtExpression(Index index, Element element, boolean inclusive)
throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
Element literal = getLiteralElement(element);
String value;
String upperBound;
if (index.getConfiguration().isDateProperty(prop)) {
Date date = config.getDateValue(literal.getTextTrim());
value = config.dateToIndexString(date);
upperBound = Index.DATE_UPPER_BOUND;
}
else if (index.getConfiguration().isIntProperty(prop)) {
value = config.intToIndexString(Long.parseLong(literal.getTextTrim()));
upperBound = Index.INT_UPPER_BOUND;
}
else {
value = literal.getTextTrim();
upperBound = "ZZZZZZZZ"; //TODO
}
RangeQuery rangeQuery = new RangeQuery(
new Term(field, value),
new Term(field, upperBound),
inclusive); // inclusive or not
setQuery(rangeQuery);
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/IsCollectionExpression.java
Index: IsCollectionExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/IsCollectionExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.TermQuery;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
/**
* Implements the <code>is-collection</code> and the <code>not-is-collection</code>
* expression.
*/
public class IsCollectionExpression extends AbstractExpression
{
public IsCollectionExpression(Index index, boolean negated)
{
super(index);
IndexConfiguration config = index.getConfiguration();
setQuery(new TermQuery(new Term(config.generateFieldName(
NodeProperty.DEFAULT_NAMESPACE, "resourcetype"),
"collection")));
if (negated) {
setQuery(getNegatedQuery(getQuery()));
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/IsDefinedExpression.java
Index: IsDefinedExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/IsDefinedExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.TermQuery;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* @author Stefan L�tzkendorf
*/
public class IsDefinedExpression extends AbstractExpression
{
public IsDefinedExpression(Index index, Element element, boolean negated)
throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
if (config.supportsIsDefined(prop)) {
setQuery(new TermQuery(new Term(Index.IS_DEFINED_FIELD_NAME, field)));
}
if (negated) {
setQuery(getNegatedQuery(getQuery()));
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/IsPrincipalExpression.java
Index: IsPrincipalExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/IsPrincipalExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.TermQuery;
import org.apache.slide.content.NodeProperty;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
/**
* Implements the <code>is-pricipal</code> and the <code>not-is-pricipal</code>
* expression.
*/
public class IsPrincipalExpression extends AbstractExpression
{
public IsPrincipalExpression(Index index, boolean negated)
{
super(index);
IndexConfiguration config = index.getConfiguration();
setQuery(new TermQuery(new Term(config.generateFieldName(
NodeProperty.DEFAULT_NAMESPACE, "resourcetype"),
"principal")));
if (negated) {
setQuery(getNegatedQuery(getQuery()));
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/LikeExpression.java
Index: LikeExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/LikeExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.WildcardTermEnum;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* Implements the <code>like</code> operator.
*
*/
public class LikeExpression extends AbstractExpression
{
public LikeExpression(Index index, Element element) throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
Element literal = getLiteralElement(element);
String text = literal.getTextTrim();
// TODO check what to do with Date or Int fields
if (text.indexOf('_') == -1 && text.indexOf('%') == text.length()-1) {
// some thing line "apple%"
setQuery(new PrefixQuery(new Term(field,
text.substring(0, text.length()-1))));
} else {
setQuery(new WildcardQuery(new Term(field,
transformQuerytext(text))));
}
}
private String transformQuerytext(String text)
throws BadQueryException
{
StringBuffer result = new StringBuffer(text.length());
for(int i = 0, l = text.length(); i<l; i++) {
char c = text.charAt(i);
switch(c) {
case '%':
result.append(WildcardTermEnum.WILDCARD_STRING);
break;
case '_':
result.append(WildcardTermEnum.WILDCARD_CHAR);
break;
default:
result.append(c);
}
}
return result.toString();
}
public static void main(String[] a) {
System.out.println("abc".indexOf("c"));
System.out.println("abc".substring(0, "abc".length()-1));
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/LtExpression.java
Index: LtExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/LtExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import java.util.Calendar;
import java.util.Date;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.RangeQuery;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* Implements <code>lt</code> and <code>lte</code> expression.
*/
public class LtExpression extends AbstractExpression
{
public LtExpression(Index index, Element element, boolean inclusive)
throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
Element literal = getLiteralElement(element);
String value;
String lowerBound;
if (index.getConfiguration().isDateProperty(prop)) {
Date date = config.getDateValue(literal.getTextTrim());
Calendar c = Calendar.getInstance();
c.setTime(date);
inclusive = c.get(Calendar.SECOND) > 0;
value = config.dateToIndexString(date);
lowerBound = Index.DATE_LOWER_BOUND;
}
else if (index.getConfiguration().isIntProperty(prop)) {
value = config.intToIndexString(Long.parseLong(literal.getTextTrim()));
lowerBound = Index.INT_LOWER_BOUND;
}
else {
value = literal.getTextTrim();
lowerBound = ""; //TODO
}
RangeQuery rangeQuery = new RangeQuery(
new Term(field, lowerBound),
new Term(field, value),
inclusive); // inclusive or not
setQuery(rangeQuery);
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/MergeExpression.java
Index: MergeExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/MergeExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import java.util.Collection;
import java.util.Iterator;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.slide.index.lucene.Index;
/**
* Implements <code>and</code> and <code>or</code>.
*/
public class MergeExpression extends AbstractExpression
{
/**
* Constructor.
* @param index The index to be searched.
* @param and <code>true</code> if AND or <code>false</code> if OR
* @param expressions list of expressions
*/
public MergeExpression(Index index, boolean and, Collection expressions)
{
super(index);
if (expressions.size() > 0) {
BooleanQuery booleanQuery = new BooleanQuery();
for(Iterator i = expressions.iterator(); i.hasNext();) {
Object e = i.next();
if (e instanceof AbstractExpression) {
Query q = ((AbstractExpression)e).getQuery();
booleanQuery.add(q, and, false);
} else {
// TODO
System.out.println("merge with non lucene expression");
}
}
setQuery(booleanQuery);
} else {
// TODO
System.out.println("merge without expressions");
}
}
}
1.1 jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/PropcontainsExpression.java
Index: PropcontainsExpression.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/stores/org/apache/slide/index/lucene/expressions/PropcontainsExpression.java,v 1.1 2004/10/18 09:27:36 luetzkendorf Exp $
* $Revision: 1.1 $
* $Date: 2004/10/18 09:27:36 $
*
* ====================================================================
*
* Copyright 1999-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.expressions;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.WildcardQuery;
import org.apache.slide.index.lucene.Index;
import org.apache.slide.index.lucene.IndexConfiguration;
import org.apache.slide.search.BadQueryException;
import org.jdom.Element;
/**
* Implements the <code>propcontains</code> operator.
*
*/
public class PropcontainsExpression extends AbstractExpression
{
public PropcontainsExpression(Index index, Element element) throws BadQueryException
{
super(index);
IndexConfiguration config = index.getConfiguration();
Element prop = getPropertyElement(element);
String field = config.generateFieldName(prop);
Element literal = getLiteralElement(element);
String text = literal.getTextTrim();
setQuery(new WildcardQuery(new Term(field, "*" + text + "*")));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org