Added generic support for lucene scalar functions and used the to implement CMIS Upper/Lower string functions (MOB-221)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14578 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind 2009-06-08 10:42:01 +00:00
parent 2c122bca4e
commit 1a261b54fd
33 changed files with 1385 additions and 242 deletions

View File

@ -27,6 +27,7 @@ package org.alfresco.cmis;
import java.io.Serializable;
import java.util.Collection;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.apache.lucene.queryParser.ParseException;
@ -43,15 +44,16 @@ public interface CMISPropertyLuceneBuilder
* @param lqp
* @param value
* @param mode
* @return
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException;
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* @param lqp
* @param not
* @return
* @return the query
* @throws ParseException
*/
public Query buildLuceneExists(LuceneQueryParser lqp, Boolean not) throws ParseException;
@ -60,24 +62,29 @@ public interface CMISPropertyLuceneBuilder
* @param lqp
* @param value
* @param mode
* @return
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException;
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* @param lqp
* @param value
* @param mode
* @return
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException;
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* @param lqp
* @param values
* @param not
* @param mode
* @return
* @return the query
* @throws ParseException
*/
public Query buildLuceneIn(LuceneQueryParser lqp, Collection<Serializable> values, Boolean not, PredicateMode mode) throws ParseException;
@ -85,40 +92,48 @@ public interface CMISPropertyLuceneBuilder
* @param lqp
* @param value
* @param mode
* @return
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException;
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* @param lqp
* @param value
* @param mode
* @return
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException;
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* @param lqp
* @param value
* @param mode
* @return
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException;
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* @param lqp
* @param value
* @param not
* @return
* @return the query
* @throws ParseException
*/
public Query buildLuceneLike(LuceneQueryParser lqp, Serializable value, Boolean not) throws ParseException;
/**
* @return
* @return the sort field
*/
public String getLuceneSortField();
/**
* @return the field name
*
*/
public String getLuceneFieldName();

View File

@ -29,6 +29,7 @@ import java.util.Collection;
import org.alfresco.cmis.CMISPropertyAccessor;
import org.alfresco.cmis.CMISPropertyLuceneBuilder;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.ServiceRegistry;
@ -88,7 +89,7 @@ public abstract class AbstractProperty implements CMISPropertyAccessor, CMISProp
}
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return null;
}
@ -98,12 +99,12 @@ public abstract class AbstractProperty implements CMISPropertyAccessor, CMISProp
return null;
}
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return null;
}
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return null;
}
@ -113,17 +114,17 @@ public abstract class AbstractProperty implements CMISPropertyAccessor, CMISProp
return null;
}
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return null;
}
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return null;
}
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return null;
}

View File

@ -28,6 +28,7 @@ import java.io.Serializable;
import java.util.Collection;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.ServiceRegistry;
@ -76,9 +77,9 @@ public abstract class AbstractSimpleProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneEquality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
return lqp.getFieldQuery(getLuceneFieldName(), getValueAsString(value), AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(getLuceneFieldName(), getValueAsString(value), AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
@ -89,11 +90,11 @@ public abstract class AbstractSimpleProperty extends AbstractProperty
{
if (not)
{
return lqp.getFieldQuery("ISNULL", getQNameForExists().toString(), AnalysisMode.DEFAULT);
return lqp.getFieldQuery("ISNULL", getQNameForExists().toString(), AnalysisMode.DEFAULT, LuceneFunction.FIELD);
}
else
{
return lqp.getFieldQuery("ISNOTNULL", getQNameForExists().toString(), AnalysisMode.DEFAULT);
return lqp.getFieldQuery("ISNOTNULL", getQNameForExists().toString(), AnalysisMode.DEFAULT, LuceneFunction.FIELD);
}
}
@ -101,22 +102,22 @@ public abstract class AbstractSimpleProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getRangeQuery(field, stringValue, getRangeMax(), false, true, AnalysisMode.IDENTIFIER);
return lqp.getRangeQuery(field, stringValue, getRangeMax(), false, true, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getRangeQuery(field, stringValue, getRangeMax(), true, true, AnalysisMode.IDENTIFIER);
return lqp.getRangeQuery(field, stringValue, getRangeMax(), true, true, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
@ -149,11 +150,11 @@ public abstract class AbstractSimpleProperty extends AbstractProperty
String value = asStrings.iterator().next();
if (not)
{
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
else
{
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
}
else
@ -165,7 +166,7 @@ public abstract class AbstractSimpleProperty extends AbstractProperty
}
for (String value : asStrings)
{
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
if (not)
{
booleanQuery.add(any, Occur.MUST_NOT);
@ -183,33 +184,33 @@ public abstract class AbstractSimpleProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneInequality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getDoesNotMatchFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getRangeQuery(field, getRangeMin(), stringValue, true, false, AnalysisMode.IDENTIFIER);
return lqp.getRangeQuery(field, getRangeMin(), stringValue, true, false, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getRangeQuery(field, getRangeMin(), stringValue, true, true, AnalysisMode.IDENTIFIER);
return lqp.getRangeQuery(field, getRangeMin(), stringValue, true, true, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*

View File

@ -29,6 +29,7 @@ import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.ServiceRegistry;
@ -87,7 +88,7 @@ public class FixedValueProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneEquality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
if (EqualsHelper.nullSafeEquals(value, value))
{
@ -135,7 +136,7 @@ public class FixedValueProperty extends AbstractProperty
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
@SuppressWarnings("unchecked")
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
if (value instanceof Comparable)
{
@ -160,7 +161,7 @@ public class FixedValueProperty extends AbstractProperty
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
@SuppressWarnings("unchecked")
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
if (value instanceof Comparable)
{
@ -210,7 +211,7 @@ public class FixedValueProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneInequality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
if (!EqualsHelper.nullSafeEquals(value, value))
{
@ -227,7 +228,7 @@ public class FixedValueProperty extends AbstractProperty
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
@SuppressWarnings("unchecked")
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
if (value instanceof Comparable)
{
@ -252,7 +253,7 @@ public class FixedValueProperty extends AbstractProperty
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
@SuppressWarnings("unchecked")
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
if (value instanceof Comparable)
{

View File

@ -31,6 +31,7 @@ import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISQueryException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.ServiceRegistry;
@ -112,11 +113,11 @@ public class ObjectIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneEquality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
@ -139,7 +140,7 @@ public class ObjectIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() +" can not be used in a 'greater than' comparison");
}
@ -148,7 +149,7 @@ public class ObjectIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'greater than or equals' comparison");
}
@ -183,11 +184,11 @@ public class ObjectIdProperty extends AbstractProperty
String value = asStrings.iterator().next();
if (not)
{
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
else
{
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
}
else
@ -199,7 +200,7 @@ public class ObjectIdProperty extends AbstractProperty
}
for (String value : asStrings)
{
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
if (not)
{
booleanQuery.add(any, Occur.MUST_NOT);
@ -217,18 +218,18 @@ public class ObjectIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneInequality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getDoesNotMatchFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'less than' comparison");
}
@ -237,7 +238,7 @@ public class ObjectIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'less than or equals' comparison");
}

View File

@ -33,6 +33,7 @@ import org.alfresco.cmis.CMISQueryException;
import org.alfresco.cmis.CMISScope;
import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.ServiceRegistry;
@ -103,12 +104,12 @@ public class ObjectTypeIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneEquality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
CMISTypeDefinition type = getServiceRegistry().getCMISDictionaryService().findType(stringValue);
return lqp.getFieldQuery(field, type.getTypeId().getQName().toString(), AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, type.getTypeId().getQName().toString(), AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
@ -131,7 +132,7 @@ public class ObjectTypeIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'greater than' comparison");
}
@ -140,7 +141,7 @@ public class ObjectTypeIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneGreaterThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'greater than or equals' comparison");
}
@ -177,11 +178,11 @@ public class ObjectTypeIdProperty extends AbstractProperty
String value = asStrings.iterator().next();
if (not)
{
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
else
{
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
}
else
@ -193,7 +194,7 @@ public class ObjectTypeIdProperty extends AbstractProperty
}
for (String value : asStrings)
{
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
if (not)
{
booleanQuery.add(any, Occur.MUST_NOT);
@ -211,19 +212,19 @@ public class ObjectTypeIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneInequality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
CMISTypeDefinition type = getServiceRegistry().getCMISDictionaryService().findType(stringValue);
return lqp.getDoesNotMatchFieldQuery(field, type.getTypeId().getQName().toString(), AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, type.getTypeId().getQName().toString(), AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThan(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'less than' comparison");
}
@ -232,7 +233,7 @@ public class ObjectTypeIdProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneLessThanOrEquals(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new CMISQueryException("Property " + getName() + " can not be used in a 'less than or equals' comparison");
}

View File

@ -29,6 +29,7 @@ import java.util.Collection;
import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.ServiceRegistry;
@ -100,11 +101,11 @@ public class ParentProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneEquality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER, luceneFunction);
}
/*
@ -153,11 +154,11 @@ public class ParentProperty extends AbstractProperty
String value = asStrings.iterator().next();
if (not)
{
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
else
{
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
return lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
}
}
else
@ -169,7 +170,7 @@ public class ParentProperty extends AbstractProperty
}
for (String value : asStrings)
{
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER);
Query any = lqp.getFieldQuery(field, value, AnalysisMode.IDENTIFIER, LuceneFunction.FIELD);
if (not)
{
booleanQuery.add(any, Occur.MUST_NOT);
@ -187,11 +188,11 @@ public class ParentProperty extends AbstractProperty
* (non-Javadoc)
* @see org.alfresco.cmis.property.PropertyLuceneBuilder#buildLuceneInequality(org.alfresco.repo.search.impl.lucene.LuceneQueryParser, java.io.Serializable, org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
String field = getLuceneFieldName();
String stringValue = getValueAsString(value);
return lqp.getDoesNotMatchFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER);
return lqp.getDoesNotMatchFieldQuery(field, stringValue, AnalysisMode.IDENTIFIER, luceneFunction);
}

View File

@ -28,16 +28,19 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISDictionaryService;
import org.alfresco.cmis.CMISPropertyDefinition;
import org.alfresco.cmis.mapping.CMISMapping;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.FunctionArgument;
import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.repo.search.impl.querymodel.QueryModelException;
import org.alfresco.repo.search.impl.querymodel.impl.functions.Lower;
import org.alfresco.repo.search.impl.querymodel.impl.functions.Upper;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
@ -151,10 +154,10 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
this.score = score;
}
public Query buildLuceneEquality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
CMISPropertyDefinition propertyDef = cmisDictionaryService.findProperty(propertyName, null);
return propertyDef.getPropertyLuceneBuilder().buildLuceneEquality(lqp, value, mode);
return propertyDef.getPropertyLuceneBuilder().buildLuceneEquality(lqp, value, mode, luceneFunction);
}
/*
@ -176,10 +179,10 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
* org.alfresco.service.namespace.QName, java.io.Serializable,
* org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
CMISPropertyDefinition propertyDef = cmisDictionaryService.findProperty(propertyName, null);
return propertyDef.getPropertyLuceneBuilder().buildLuceneGreaterThan(lqp, value, mode);
return propertyDef.getPropertyLuceneBuilder().buildLuceneGreaterThan(lqp, value, mode, luceneFunction);
}
/*
@ -189,10 +192,10 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
* org.alfresco.service.namespace.QName, java.io.Serializable,
* org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
CMISPropertyDefinition propertyDef = cmisDictionaryService.findProperty(propertyName, null);
return propertyDef.getPropertyLuceneBuilder().buildLuceneGreaterThanOrEquals(lqp, value, mode);
return propertyDef.getPropertyLuceneBuilder().buildLuceneGreaterThanOrEquals(lqp, value, mode, luceneFunction);
}
/*
@ -215,10 +218,10 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
* org.alfresco.service.namespace.QName, java.io.Serializable,
* org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
CMISPropertyDefinition propertyDef = cmisDictionaryService.findProperty(propertyName, null);
return propertyDef.getPropertyLuceneBuilder().buildLuceneInequality(lqp, value, mode);
return propertyDef.getPropertyLuceneBuilder().buildLuceneInequality(lqp, value, mode, luceneFunction);
}
/*
@ -228,10 +231,10 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
* org.alfresco.service.namespace.QName, java.io.Serializable,
* org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
CMISPropertyDefinition propertyDef = cmisDictionaryService.findProperty(propertyName, null);
return propertyDef.getPropertyLuceneBuilder().buildLuceneLessThan(lqp, value, mode);
return propertyDef.getPropertyLuceneBuilder().buildLuceneLessThan(lqp, value, mode, luceneFunction);
}
/*
@ -241,10 +244,10 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
* org.alfresco.service.namespace.QName, java.io.Serializable,
* org.alfresco.repo.search.impl.querymodel.PredicateMode)
*/
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
CMISPropertyDefinition propertyDef = cmisDictionaryService.findProperty(propertyName, null);
return propertyDef.getPropertyLuceneBuilder().buildLuceneLessThanOrEquals(lqp, value, mode);
return propertyDef.getPropertyLuceneBuilder().buildLuceneLessThanOrEquals(lqp, value, mode, luceneFunction);
}
/*
@ -322,5 +325,29 @@ public class CmisFunctionEvaluationContext implements FunctionEvaluationContext
}
}
public LuceneFunction getLuceneFunction(FunctionArgument functionArgument)
{
if (functionArgument == null)
{
return LuceneFunction.FIELD;
}
else
{
String functionName = functionArgument.getFunction().getName();
if (functionName.equals(Upper.NAME))
{
return LuceneFunction.UPPER;
}
else if (functionName.equals(Lower.NAME))
{
return LuceneFunction.LOWER;
}
else
{
throw new QueryModelException("Unsupported function: " + functionName);
}
}
}
}

View File

@ -1474,6 +1474,26 @@ public class QueryTest extends BaseCMISTest
}
public void testUpperAndLower()
{
testQuery("SELECT * FROM Folder WHERE Name = 'Folder 1'", 1, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Name = 'FOLDER 1'", 0, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Name = 'folder 1'", 0, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) = 'FOLDER 1'", 1, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Lower(Name) = 'folder 1'", 1, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) = 'folder 1'", 0, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Lower(Name) = 'FOLDER 1'", 0, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) = 'Folder 1'", 0, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Lower(Name) = 'Folder 1'", 0, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) <> 'FOLDER 1'", 9, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) <= 'FOLDER 1'", 2, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) < 'FOLDER 1'", 1, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) >= 'FOLDER 1'", 9, false, "ObjectId", new String(), false);
testQuery("SELECT * FROM Folder WHERE Upper(Name) > 'FOLDER 1'", 8, false, "ObjectId", new String(), false);
}
public void testAllSimpleTextPredicates()
{
testQuery("SELECT * FROM Folder WHERE Name IS NOT NULL AND Name = 'Folder 1'", 1, false, "ObjectId", new String(), false);

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.search.impl.lucene;
/**
* Functions that can be applied to lucene fields
*
* Currently upper and lower that perform a case insensitive match for untokenised fields.
* (If the field is tokenised the match should already be case insensitive.)
*
* @author andyh
*
*/
public enum LuceneFunction
{
/**
* Match as if the field was converted to upper case.
*/
UPPER,
/**
* Match as if the field was converted to lower case.
*/
LOWER,
/**
* A normal lucene field match.
*/
FIELD;
}

View File

@ -45,7 +45,8 @@ import org.alfresco.repo.search.MLAnalysisMode;
import org.alfresco.repo.search.SearcherException;
import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.MLTokenDuplicator;
import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser;
import org.alfresco.repo.search.impl.lucene.query.CaseInsensitiveFieldQuery;
import org.alfresco.repo.search.impl.lucene.query.CaseInsensitiveFieldRangeQuery;
import org.alfresco.repo.search.impl.lucene.query.PathQuery;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
@ -66,7 +67,6 @@ import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.CharStream;
@ -132,7 +132,14 @@ public class LuceneQueryParser extends QueryParser
* the default field for query terms.
* @param analyzer
* used to find terms in the query text.
* @param namespacePrefixResolver
* @param dictionaryService
* @param tenantService
* @param defaultOperator
* @param searchParameters
* @param config
* @param indexReader
* @return - the query
* @throws ParseException
* if the parsing fails
*/
@ -161,31 +168,51 @@ public class LuceneQueryParser extends QueryParser
return result;
}
/**
* @param config
*/
public void setLuceneConfig(LuceneConfig config)
{
this.config = config;
}
/**
* @param indexReader
*/
public void setIndexReader(IndexReader indexReader)
{
this.indexReader = indexReader;
}
/**
* @param searchParameters
*/
public void setSearchParameters(SearchParameters searchParameters)
{
this.searchParameters = searchParameters;
}
/**
* @param namespacePrefixResolver
*/
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
{
this.namespacePrefixResolver = namespacePrefixResolver;
}
/**
* @param tenantService
*/
public void setTenantService(TenantService tenantService)
{
this.tenantService = tenantService;
}
/**
* Lucene default constructor
* @param arg0
* @param arg1
*/
public LuceneQueryParser(String arg0, Analyzer arg1)
{
super(arg0, arg1);
@ -195,11 +222,19 @@ public class LuceneQueryParser extends QueryParser
}
}
/**
* Lucene default constructor
* @param arg0
*/
public LuceneQueryParser(CharStream arg0)
{
super(arg0);
}
/**
* Lucene default constructor
* @param arg0
*/
public LuceneQueryParser(QueryParserTokenManager arg0)
{
super(arg0);
@ -220,12 +255,21 @@ public class LuceneQueryParser extends QueryParser
}
public Query getFieldQuery(String field, String queryText, AnalysisMode analysisMode, int slop) throws ParseException
/**
* @param field
* @param queryText
* @param analysisMode
* @param slop
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query getFieldQuery(String field, String queryText, AnalysisMode analysisMode, int slop, LuceneFunction luceneFunction) throws ParseException
{
try
{
internalSlop = slop;
Query query = getFieldQuery(field, queryText, analysisMode);
Query query = getFieldQuery(field, queryText, analysisMode, luceneFunction);
return query;
}
finally
@ -235,17 +279,32 @@ public class LuceneQueryParser extends QueryParser
}
/**
* @param field
* @param sqlLikeClause
* @param analysisMode
* @return the query
* @throws ParseException
*/
public Query getLikeQuery(String field, String sqlLikeClause, AnalysisMode analysisMode) throws ParseException
{
String luceneWildCardExpression = SearchLanguageConversion.convertSQLLikeToLucene(sqlLikeClause);
return getFieldQuery(field, luceneWildCardExpression, analysisMode);
return getFieldQuery(field, luceneWildCardExpression, analysisMode, LuceneFunction.FIELD);
}
public Query getDoesNotMatchFieldQuery(String field, String queryText, AnalysisMode analysisMode) throws ParseException
/**
* @param field
* @param queryText
* @param analysisMode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query getDoesNotMatchFieldQuery(String field, String queryText, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
BooleanQuery query = new BooleanQuery();
Query allQuery = new MatchAllDocsQuery();
Query matchQuery = getFieldQuery(field, queryText, analysisMode);
Query matchQuery = getFieldQuery(field, queryText, analysisMode, luceneFunction);
if ((matchQuery != null))
{
query.add(allQuery, Occur.MUST);
@ -260,9 +319,17 @@ public class LuceneQueryParser extends QueryParser
public Query getFieldQuery(String field, String queryText) throws ParseException
{
return getFieldQuery(field, queryText, AnalysisMode.DEFAULT);
return getFieldQuery(field, queryText, AnalysisMode.DEFAULT, LuceneFunction.FIELD);
}
/**
* @param field
* @param first
* @param last
* @param slop
* @param inOrder
* @return the query
*/
public Query getSpanQuery(String field, String first, String last, int slop, boolean inOrder)
{
if (field.equals("TEXT"))
@ -342,7 +409,15 @@ public class LuceneQueryParser extends QueryParser
}
public Query getFieldQuery(String field, String queryText, AnalysisMode analysisMode) throws ParseException
/**
* @param field
* @param queryText
* @param analysisMode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query getFieldQuery(String field, String queryText, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
try
{
@ -380,7 +455,7 @@ public class LuceneQueryParser extends QueryParser
for (QName qname : contentAttributes)
{
// The super implementation will create phrase queries etc if required
Query part = getFieldQuery("@" + qname.toString(), queryText, analysisMode);
Query part = getFieldQuery("@" + qname.toString(), queryText, analysisMode, luceneFunction);
if (part != null)
{
query.add(part, Occur.SHOULD);
@ -397,7 +472,7 @@ public class LuceneQueryParser extends QueryParser
BooleanQuery query = new BooleanQuery();
for (String fieldName : text)
{
Query part = getFieldQuery(fieldName, queryText, analysisMode);
Query part = getFieldQuery(fieldName, queryText, analysisMode, luceneFunction);
if (part != null)
{
query.add(part, Occur.SHOULD);
@ -497,7 +572,7 @@ public class LuceneQueryParser extends QueryParser
{
throw new SearcherException("Invalid type: " + queryText);
}
return getFieldQuery(target.isAspect() ? "ASPECT" : "TYPE", queryText, analysisMode);
return getFieldQuery(target.isAspect() ? "ASPECT" : "TYPE", queryText, analysisMode, luceneFunction);
}
else if (field.equals("TYPE"))
{
@ -634,7 +709,7 @@ public class LuceneQueryParser extends QueryParser
}
else if (field.startsWith("@"))
{
Query query = attributeQueryBuilder(field, queryText, new FieldQuery(), analysisMode);
Query query = attributeQueryBuilder(field, queryText, new FieldQuery(), analysisMode, luceneFunction);
return query;
}
else if (field.equals("ALL"))
@ -647,7 +722,7 @@ public class LuceneQueryParser extends QueryParser
for (QName qname : contentAttributes)
{
// The super implementation will create phrase queries etc if required
Query part = getFieldQuery("@" + qname.toString(), queryText, analysisMode);
Query part = getFieldQuery("@" + qname.toString(), queryText, analysisMode, luceneFunction);
if (part != null)
{
query.add(part, Occur.SHOULD);
@ -664,7 +739,7 @@ public class LuceneQueryParser extends QueryParser
BooleanQuery query = new BooleanQuery();
for (String fieldName : all)
{
Query part = getFieldQuery(fieldName, queryText, analysisMode);
Query part = getFieldQuery(fieldName, queryText, analysisMode, luceneFunction);
if (part != null)
{
query.add(part, Occur.SHOULD);
@ -689,7 +764,7 @@ public class LuceneQueryParser extends QueryParser
QName container = containerClass.getName();
BooleanQuery query = new BooleanQuery();
String classType = containerClass.isAspect() ? "ASPECT" : "TYPE";
Query typeQuery = getFieldQuery(classType, container.toString(), analysisMode);
Query typeQuery = getFieldQuery(classType, container.toString(), analysisMode, luceneFunction);
Query presenceQuery = getWildcardQuery("@" + qname.toString(), "*");
if ((typeQuery != null) && (presenceQuery != null))
{
@ -700,7 +775,7 @@ public class LuceneQueryParser extends QueryParser
}
else
{
return getFieldQueryImpl(field, queryText, analysisMode);
return getFieldQueryImpl(field, queryText, analysisMode, luceneFunction);
}
}
@ -722,7 +797,7 @@ public class LuceneQueryParser extends QueryParser
}
else
{
return getFieldQueryImpl(field, queryText, analysisMode);
return getFieldQueryImpl(field, queryText, analysisMode, luceneFunction);
}
}
@ -737,7 +812,7 @@ public class LuceneQueryParser extends QueryParser
QName container = containerClass.getName();
BooleanQuery query = new BooleanQuery();
String classType = containerClass.isAspect() ? "ASPECT" : "TYPE";
Query typeQuery = getFieldQuery(classType, container.toString(), analysisMode);
Query typeQuery = getFieldQuery(classType, container.toString(), analysisMode, luceneFunction);
Query presenceQuery = getWildcardQuery("@" + qname.toString(), "*");
if ((typeQuery != null) && (presenceQuery != null))
{
@ -748,7 +823,7 @@ public class LuceneQueryParser extends QueryParser
}
else
{
return getFieldQueryImpl(field, queryText, analysisMode);
return getFieldQueryImpl(field, queryText, analysisMode, luceneFunction);
}
}
@ -759,7 +834,7 @@ public class LuceneQueryParser extends QueryParser
for (QName qname : contentAttributes)
{
// The super implementation will create phrase queries etc if required
Query part = getFieldQuery("@" + qname.toString(), queryText, analysisMode);
Query part = getFieldQuery("@" + qname.toString(), queryText, analysisMode, luceneFunction);
if (part != null)
{
query.add(part, Occur.SHOULD);
@ -778,7 +853,7 @@ public class LuceneQueryParser extends QueryParser
}
else
{
return getFieldQueryImpl(field, queryText, analysisMode);
return getFieldQueryImpl(field, queryText, analysisMode, luceneFunction);
}
}
@ -789,10 +864,17 @@ public class LuceneQueryParser extends QueryParser
}
private Query getFieldQueryImpl(String field, String queryText, AnalysisMode analysisMode) throws ParseException
private Query getFieldQueryImpl(String field, String queryText, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
// Use the analyzer to get all the tokens, and then build a TermQuery,
// PhraseQuery, or nothing based on the term count
// PhraseQuery, or noth
// TODO: Untokenised columns with functions require special handling
if (luceneFunction != LuceneFunction.FIELD)
{
throw new UnsupportedOperationException("Field queries are not supported on lucene functions (UPPER, LOWER, etc)");
}
boolean requiresMLTokenDuplication = false;
String testText = queryText;
@ -1404,14 +1486,23 @@ public class LuceneQueryParser extends QueryParser
*/
protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive) throws ParseException
{
return getRangeQuery(field, part1, part2, inclusive, inclusive, AnalysisMode.DEFAULT);
return getRangeQuery(field, part1, part2, inclusive, inclusive, AnalysisMode.DEFAULT, LuceneFunction.FIELD);
}
/**
* @param field
* @param part1
* @param part2
* @param includeLower
* @param includeUpper
* @param analysisMode
* @param luceneFunction
* @return the query
* @exception ParseException
* throw in overridden method to disallow
*/
public Query getRangeQuery(String field, String part1, String part2, boolean includeLower, boolean includeUpper, AnalysisMode analysisMode) throws ParseException
public Query getRangeQuery(String field, String part1, String part2, boolean includeLower, boolean includeUpper, AnalysisMode analysisMode, LuceneFunction luceneFunction)
throws ParseException
{
if (field.startsWith("@"))
@ -1433,6 +1524,44 @@ public class LuceneQueryParser extends QueryParser
if (propertyDef != null)
{
if (luceneFunction != LuceneFunction.FIELD)
{
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT))
{
BooleanQuery booleanQuery = new BooleanQuery();
MLAnalysisMode mlAnalysisMode = searchParameters.getMlAnalaysisMode() == null ? config.getDefaultMLSearchAnalysisMode() : searchParameters
.getMlAnalaysisMode();
List<Locale> locales = searchParameters.getLocales();
List<Locale> expandedLocales = new ArrayList<Locale>();
for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections.singletonList(I18NUtil.getLocale()) : locales))
{
expandedLocales.addAll(MLAnalysisMode.getLocales(mlAnalysisMode, locale, false));
}
for (Locale locale : (((expandedLocales == null) || (expandedLocales.size() == 0)) ? Collections.singletonList(I18NUtil.getLocale()) : expandedLocales))
{
if (locale.toString().length() == 0)
{
continue;
}
String textFieldName = fieldName;
if (tokenisationMode == IndexTokenisationMode.BOTH)
{
textFieldName = textFieldName + "." + locale + ".sort";
}
addLocaleSpecificUntokenisedTextRangeFunction(field, part1, part2, includeLower, includeUpper, luceneFunction, booleanQuery, mlAnalysisMode, locale, textFieldName);
}
return booleanQuery;
}
else
{
throw new UnsupportedOperationException("Lucene Function");
}
}
if (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
{
throw new UnsupportedOperationException("Range is not supported against ml-text");
@ -1620,6 +1749,72 @@ public class LuceneQueryParser extends QueryParser
}
}
private void addLocaleSpecificUntokenisedTextRangeFunction(String expandedFieldName, String lower, String upper, boolean includeLower, boolean includeUpper, LuceneFunction luceneFunction, BooleanQuery booleanQuery,
MLAnalysisMode mlAnalysisMode, Locale locale, String textFieldName)
{
String lowerTermText = lower;
if (locale.toString().length() > 0)
{
lowerTermText = "{" + locale + "}" + lower;
}
String upperTermText = upper;
if (locale.toString().length() > 0)
{
upperTermText = "{" + locale + "}" + upper;
}
Query subQuery = buildRangeFunctionQuery(textFieldName, lowerTermText, upperTermText, includeLower, includeUpper, luceneFunction);
booleanQuery.add(subQuery, Occur.SHOULD);
if (booleanQuery.getClauses().length == 0)
{
booleanQuery.add(new TermQuery(new Term("NO_TOKENS", "__")), Occur.SHOULD);
}
}
private Query buildRangeFunctionQuery(String expandedFieldName, String lowerTermText, String upperTermText, boolean includeLower, boolean includeUpper, LuceneFunction luceneFunction)
{
String testLowerTermText = lowerTermText;
if (testLowerTermText.startsWith("{"))
{
int index = lowerTermText.indexOf("}");
testLowerTermText = lowerTermText.substring(index + 1);
}
String testUpperTermText = upperTermText;
if (testUpperTermText.startsWith("{"))
{
int index = upperTermText.indexOf("}");
testUpperTermText = upperTermText.substring(index + 1);
}
switch (luceneFunction)
{
case LOWER:
if (testLowerTermText.equals(testLowerTermText.toLowerCase()) && testUpperTermText.equals(testUpperTermText.toLowerCase()))
{
return new CaseInsensitiveFieldRangeQuery(expandedFieldName, lowerTermText, upperTermText, includeLower, includeUpper);
}
else
{
// No match
return new TermQuery(new Term("NO_TOKENS", "__"));
}
case UPPER:
if (testLowerTermText.equals(testLowerTermText.toUpperCase()) && testUpperTermText.equals(testUpperTermText.toUpperCase()))
{
return new CaseInsensitiveFieldRangeQuery(expandedFieldName, lowerTermText, upperTermText, includeLower, includeUpper);
}
else
{
// No match
return new TermQuery(new Term("NO_TOKENS", "__"));
}
default:
throw new UnsupportedOperationException("Unsupported Lucene Function " + luceneFunction);
}
}
private void addLocaleSpecificTokenisedTextRange(String part1, String part2, boolean includeLower, boolean includeUpper, AnalysisMode analysisMode, String fieldName,
BooleanQuery booleanQuery, Locale locale, String textFieldName) throws ParseException
{
@ -2394,7 +2589,7 @@ public class LuceneQueryParser extends QueryParser
{
if (field.startsWith("@"))
{
return attributeQueryBuilder(field, termStr, new PrefixQuery(), AnalysisMode.PREFIX);
return attributeQueryBuilder(field, termStr, new PrefixQuery(), AnalysisMode.PREFIX, LuceneFunction.FIELD);
}
else if (field.equals("TEXT"))
{
@ -2447,7 +2642,7 @@ public class LuceneQueryParser extends QueryParser
{
if (field.startsWith("@"))
{
return attributeQueryBuilder(field, termStr, new WildcardQuery(), AnalysisMode.WILD);
return attributeQueryBuilder(field, termStr, new WildcardQuery(), AnalysisMode.WILD, LuceneFunction.FIELD);
}
else if (field.equals("TEXT"))
@ -2501,7 +2696,7 @@ public class LuceneQueryParser extends QueryParser
{
if (field.startsWith("@"))
{
return attributeQueryBuilder(field, termStr, new FuzzyQuery(minSimilarity), AnalysisMode.FUZZY);
return attributeQueryBuilder(field, termStr, new FuzzyQuery(minSimilarity), AnalysisMode.FUZZY, LuceneFunction.FIELD);
}
else if (field.equals("TEXT"))
@ -2550,26 +2745,56 @@ public class LuceneQueryParser extends QueryParser
}
}
/**
* @param dictionaryService
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public Query getSuperFieldQuery(String field, String queryText, AnalysisMode analysisMode) throws ParseException
/**
* @param field
* @param queryText
* @param analysisMode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query getSuperFieldQuery(String field, String queryText, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
return getFieldQueryImpl(field, queryText, analysisMode);
return getFieldQueryImpl(field, queryText, analysisMode, luceneFunction);
}
/**
* @param field
* @param termStr
* @param minSimilarity
* @return the query
* @throws ParseException
*/
public Query getSuperFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException
{
return super.getFuzzyQuery(field, termStr, minSimilarity);
}
/**
* @param field
* @param termStr
* @return the query
* @throws ParseException
*/
public Query getSuperPrefixQuery(String field, String termStr) throws ParseException
{
return super.getPrefixQuery(field, termStr);
}
/**
* @param field
* @param termStr
* @return the query
* @throws ParseException
*/
public Query getSuperWildcardQuery(String field, String termStr) throws ParseException
{
return super.getWildcardQuery(field, termStr);
@ -2577,14 +2802,22 @@ public class LuceneQueryParser extends QueryParser
interface SubQuery
{
Query getQuery(String field, String queryText, AnalysisMode analysisMode) throws ParseException;
/**
* @param field
* @param queryText
* @param analysisMode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
Query getQuery(String field, String queryText, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException;
}
class FieldQuery implements SubQuery
{
public Query getQuery(String field, String queryText, AnalysisMode analysisMode) throws ParseException
public Query getQuery(String field, String queryText, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
return getSuperFieldQuery(field, queryText, analysisMode);
return getSuperFieldQuery(field, queryText, analysisMode, luceneFunction);
}
}
@ -2597,7 +2830,7 @@ public class LuceneQueryParser extends QueryParser
this.minSimilarity = minSimilarity;
}
public Query getQuery(String field, String termStr, AnalysisMode analysisMode) throws ParseException
public Query getQuery(String field, String termStr, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
return getSuperFuzzyQuery(field, termStr, minSimilarity);
}
@ -2605,7 +2838,7 @@ public class LuceneQueryParser extends QueryParser
class PrefixQuery implements SubQuery
{
public Query getQuery(String field, String termStr, AnalysisMode analysisMode) throws ParseException
public Query getQuery(String field, String termStr, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
return getSuperPrefixQuery(field, termStr);
}
@ -2613,13 +2846,13 @@ public class LuceneQueryParser extends QueryParser
class WildcardQuery implements SubQuery
{
public Query getQuery(String field, String termStr, AnalysisMode analysisMode) throws ParseException
public Query getQuery(String field, String termStr, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
return getSuperWildcardQuery(field, termStr);
}
}
private Query attributeQueryBuilder(String field, String queryText, SubQuery subQueryBuilder, AnalysisMode analysisMode) throws ParseException
private Query attributeQueryBuilder(String field, String queryText, SubQuery subQueryBuilder, AnalysisMode analysisMode, LuceneFunction luceneFunction) throws ParseException
{
// TODO: Fix duplicate token generation for mltext, content and text.
// -locale expansion here and in tokeisation -> duplicates
@ -2628,43 +2861,24 @@ public class LuceneQueryParser extends QueryParser
String expandedFieldName = expandAttributeFieldName(field);
// Mime type
// Get type info etc
QName propertyQName = null;
if (expandedFieldName.endsWith(".mimetype"))
{
QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 9));
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
}
propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 9));
}
else if (expandedFieldName.endsWith(".size"))
{
QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 5));
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
}
propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 5));
}
else if (expandedFieldName.endsWith(".locale"))
{
QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 7));
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 7));
}
else
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
propertyQName = QName.createQName(expandedFieldName.substring(1));
}
}
// Already in expanded form
// ML
QName propertyQName = QName.createQName(expandedFieldName.substring(1));
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
IndexTokenisationMode tokenisationMode = IndexTokenisationMode.TRUE;
if (propertyDef != null)
@ -2676,6 +2890,44 @@ public class LuceneQueryParser extends QueryParser
}
}
if (luceneFunction != LuceneFunction.FIELD)
{
if ((tokenisationMode == IndexTokenisationMode.FALSE) || (tokenisationMode == IndexTokenisationMode.BOTH))
{
return functionQueryBuilder(expandedFieldName, propertyQName, propertyDef, tokenisationMode, queryText, luceneFunction);
}
}
// Mime type
if (expandedFieldName.endsWith(".mimetype"))
{
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
}
}
else if (expandedFieldName.endsWith(".size"))
{
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
}
}
else if (expandedFieldName.endsWith(".locale"))
{
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
}
}
// Already in expanded form
// ML
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)))
{
// Build a sub query for each locale and or the results together - the analysis will take care of
@ -2713,18 +2965,20 @@ public class LuceneQueryParser extends QueryParser
default:
case DEFAULT:
case TOKENISE:
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, booleanQuery, locale, mlFieldName);
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, locale, mlFieldName);
break;
case IDENTIFIER:
case FUZZY:
case PREFIX:
case WILD:
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, booleanQuery, mlAnalysisMode, locale, mlFieldName);
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, mlAnalysisMode, locale,
mlFieldName);
break;
}
break;
case FALSE:
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, booleanQuery, mlAnalysisMode, locale, mlFieldName);
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, mlAnalysisMode, locale,
mlFieldName);
break;
case TRUE:
default:
@ -2734,12 +2988,13 @@ public class LuceneQueryParser extends QueryParser
case DEFAULT:
case TOKENISE:
case IDENTIFIER:
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, booleanQuery, locale, mlFieldName);
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, locale, mlFieldName);
break;
case FUZZY:
case PREFIX:
case WILD:
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, booleanQuery, mlAnalysisMode, locale, mlFieldName);
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, mlAnalysisMode, locale,
mlFieldName);
break;
}
}
@ -2758,7 +3013,7 @@ public class LuceneQueryParser extends QueryParser
if (mlAnalysisMode.includesAll())
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
}
List<Locale> locales = searchParameters.getLocales();
@ -2771,7 +3026,7 @@ public class LuceneQueryParser extends QueryParser
if (expandedLocales.size() > 0)
{
BooleanQuery booleanQuery = new BooleanQuery();
Query contentQuery = subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
Query contentQuery = subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
if (contentQuery != null)
{
booleanQuery.add(contentQuery, Occur.MUST);
@ -2812,7 +3067,7 @@ public class LuceneQueryParser extends QueryParser
}
else
{
Query query = subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
Query query = subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
if (query != null)
{
return query;
@ -2830,7 +3085,7 @@ public class LuceneQueryParser extends QueryParser
|| propertyQName.equals(ContentModel.PROP_USERNAME) || propertyQName.equals(ContentModel.PROP_AUTHORITY_NAME)
|| propertyQName.equals(ContentModel.PROP_MEMBERS))
{
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode);
return subQueryBuilder.getQuery(expandedFieldName, queryText, analysisMode, luceneFunction);
}
BooleanQuery booleanQuery = new BooleanQuery();
@ -2866,18 +3121,20 @@ public class LuceneQueryParser extends QueryParser
default:
case DEFAULT:
case TOKENISE:
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, booleanQuery, locale, textFieldName);
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, locale, textFieldName);
break;
case IDENTIFIER:
case FUZZY:
case PREFIX:
case WILD:
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, booleanQuery, mlAnalysisMode, locale, textFieldName);
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, mlAnalysisMode, locale,
textFieldName);
break;
}
break;
case FALSE:
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, booleanQuery, mlAnalysisMode, locale, textFieldName);
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, mlAnalysisMode, locale,
textFieldName);
break;
case TRUE:
default:
@ -2886,12 +3143,13 @@ public class LuceneQueryParser extends QueryParser
case DEFAULT:
case TOKENISE:
case IDENTIFIER:
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, booleanQuery, locale, textFieldName);
addLocaleSpecificTokenisedMLOrTextAttribute(queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, locale, textFieldName);
break;
case FUZZY:
case PREFIX:
case WILD:
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, booleanQuery, mlAnalysisMode, locale, textFieldName);
addLocaleSpecificUntokenisedMLOrTextAttribute(field, queryText, subQueryBuilder, analysisMode, luceneFunction, booleanQuery, mlAnalysisMode, locale,
textFieldName);
break;
}
break;
@ -2904,7 +3162,7 @@ public class LuceneQueryParser extends QueryParser
{
// Sort and id is only special for MLText, text, and content
// Dates are not special in this case
Query query = subQueryBuilder.getQuery(expandedFieldName, queryText, AnalysisMode.DEFAULT);
Query query = subQueryBuilder.getQuery(expandedFieldName, queryText, AnalysisMode.DEFAULT, luceneFunction);
if (query != null)
{
return query;
@ -2917,7 +3175,7 @@ public class LuceneQueryParser extends QueryParser
}
private void addLocaleSpecificUntokenisedMLOrTextAttribute(String sourceField, String queryText, SubQuery subQueryBuilder, AnalysisMode analysisMode,
BooleanQuery booleanQuery, MLAnalysisMode mlAnalysisMode, Locale locale, String actualField) throws ParseException
LuceneFunction luceneFunction, BooleanQuery booleanQuery, MLAnalysisMode mlAnalysisMode, Locale locale, String actualField) throws ParseException
{
String termText = queryText;
@ -2925,7 +3183,7 @@ public class LuceneQueryParser extends QueryParser
{
termText = "{" + locale + "}" + queryText;
}
Query subQuery = subQueryBuilder.getQuery(actualField, termText, analysisMode);
Query subQuery = subQueryBuilder.getQuery(actualField, termText, analysisMode, luceneFunction);
booleanQuery.add(subQuery, Occur.SHOULD);
if (booleanQuery.getClauses().length == 0)
@ -2934,12 +3192,12 @@ public class LuceneQueryParser extends QueryParser
}
}
private void addLocaleSpecificTokenisedMLOrTextAttribute(String queryText, SubQuery subQueryBuilder, AnalysisMode analysisMode, BooleanQuery booleanQuery, Locale locale,
String actualField) throws ParseException
private void addLocaleSpecificTokenisedMLOrTextAttribute(String queryText, SubQuery subQueryBuilder, AnalysisMode analysisMode, LuceneFunction luceneFunction,
BooleanQuery booleanQuery, Locale locale, String actualField) throws ParseException
{
StringBuilder builder = new StringBuilder(queryText.length() + 10);
builder.append("\u0000").append(locale.toString()).append("\u0000").append(queryText);
Query subQuery = subQueryBuilder.getQuery(actualField, builder.toString(), analysisMode);
Query subQuery = subQueryBuilder.getQuery(actualField, builder.toString(), analysisMode, luceneFunction);
if (subQuery != null)
{
booleanQuery.add(subQuery, Occur.SHOULD);
@ -2950,6 +3208,161 @@ public class LuceneQueryParser extends QueryParser
}
}
private Query functionQueryBuilder(String expandedFieldName, QName propertyQName, PropertyDefinition propertyDef, IndexTokenisationMode tokenisationMode, String queryText,
LuceneFunction luceneFunction) throws ParseException
{
// Mime type
if (expandedFieldName.endsWith(".mimetype"))
{
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
throw new UnsupportedOperationException("Lucene Function");
}
}
else if (expandedFieldName.endsWith(".size"))
{
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
throw new UnsupportedOperationException("Lucene Function");
}
}
else if (expandedFieldName.endsWith(".locale"))
{
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
throw new UnsupportedOperationException("Lucene Function");
}
}
// Already in expanded form
// ML
if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)))
{
// Build a sub query for each locale and or the results together - the analysis will take care of
// cross language matching for each entry
BooleanQuery booleanQuery = new BooleanQuery();
MLAnalysisMode mlAnalysisMode = searchParameters.getMlAnalaysisMode() == null ? config.getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode();
List<Locale> locales = searchParameters.getLocales();
List<Locale> expandedLocales = new ArrayList<Locale>();
for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections.singletonList(I18NUtil.getLocale()) : locales))
{
expandedLocales.addAll(MLAnalysisMode.getLocales(mlAnalysisMode, locale, false));
}
for (Locale locale : (((expandedLocales == null) || (expandedLocales.size() == 0)) ? Collections.singletonList(I18NUtil.getLocale()) : expandedLocales))
{
String mlFieldName = expandedFieldName;
if (tokenisationMode == IndexTokenisationMode.BOTH)
{
mlFieldName = mlFieldName + "." + locale + ".sort";
}
addLocaleSpecificUntokenisedMLOrTextFunction(expandedFieldName, queryText, luceneFunction, booleanQuery, mlAnalysisMode, locale, mlFieldName);
}
return booleanQuery;
}
// Content
else if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
throw new UnsupportedOperationException("Lucene functions not supported for content");
}
else if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT)))
{
if (propertyQName.equals(ContentModel.PROP_USER_USERNAME)
|| propertyQName.equals(ContentModel.PROP_USERNAME) || propertyQName.equals(ContentModel.PROP_AUTHORITY_NAME)
|| propertyQName.equals(ContentModel.PROP_MEMBERS))
{
throw new UnsupportedOperationException("Functions are not supported agaisnt special text fields");
}
BooleanQuery booleanQuery = new BooleanQuery();
MLAnalysisMode mlAnalysisMode = searchParameters.getMlAnalaysisMode() == null ? config.getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode();
List<Locale> locales = searchParameters.getLocales();
List<Locale> expandedLocales = new ArrayList<Locale>();
for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections.singletonList(I18NUtil.getLocale()) : locales))
{
expandedLocales.addAll(MLAnalysisMode.getLocales(mlAnalysisMode, locale, false));
}
for (Locale locale : (((expandedLocales == null) || (expandedLocales.size() == 0)) ? Collections.singletonList(I18NUtil.getLocale()) : expandedLocales))
{
String textFieldName = expandedFieldName;
if (tokenisationMode == IndexTokenisationMode.BOTH)
{
textFieldName = textFieldName + "." + locale + ".sort";
}
addLocaleSpecificUntokenisedMLOrTextFunction(expandedFieldName, queryText, luceneFunction, booleanQuery, mlAnalysisMode, locale, textFieldName);
}
return booleanQuery;
}
else
{
throw new UnsupportedOperationException("Lucene Function");
}
}
private void addLocaleSpecificUntokenisedMLOrTextFunction(String expandedFieldName, String queryText, LuceneFunction luceneFunction, BooleanQuery booleanQuery,
MLAnalysisMode mlAnalysisMode, Locale locale, String textFieldName)
{
String termText = queryText;
if (locale.toString().length() > 0)
{
termText = "{" + locale + "}" + queryText;
}
Query subQuery = buildFunctionQuery(textFieldName, termText, luceneFunction);
booleanQuery.add(subQuery, Occur.SHOULD);
if (booleanQuery.getClauses().length == 0)
{
booleanQuery.add(new TermQuery(new Term("NO_TOKENS", "__")), Occur.SHOULD);
}
}
private Query buildFunctionQuery(String expandedFieldName, String termText, LuceneFunction luceneFunction)
{
String testText = termText;
if (termText.startsWith("{"))
{
int index = termText.indexOf("}");
testText = termText.substring(index + 1);
}
switch (luceneFunction)
{
case LOWER:
if (testText.equals(testText.toLowerCase()))
{
return new CaseInsensitiveFieldQuery(new Term(expandedFieldName, termText));
}
else
{
// No match
return new TermQuery(new Term("NO_TOKENS", "__"));
}
case UPPER:
if (testText.equals(testText.toUpperCase()))
{
return new CaseInsensitiveFieldQuery(new Term(expandedFieldName, termText));
}
else
{
// No match
return new TermQuery(new Term("NO_TOKENS", "__"));
}
default:
throw new UnsupportedOperationException("Unsupported Lucene Function " + luceneFunction);
}
}
public static void main(String[] args) throws ParseException, java.text.ParseException
{
Query query;

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.search.impl.lucene.query;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FilteredTermEnum;
import org.apache.lucene.search.MultiTermQuery;
/**
* Perform a case insensitive match against a field
*
* @author andyh
*
*/
public class CaseInsensitiveFieldQuery extends MultiTermQuery
{
/**
*
*/
private static final long serialVersionUID = -2570803495329346982L;
/**
* @param term - the term for the match
*/
public CaseInsensitiveFieldQuery(Term term)
{
super(term);
}
@Override
protected FilteredTermEnum getEnum(IndexReader reader) throws IOException
{
Term term = new Term(getTerm().field(), getTerm().text());
return new CaseInsensitiveTermEnum(reader, term);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.search.impl.lucene.query;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FilteredTermEnum;
import org.apache.lucene.search.MultiTermQuery;
/**
* Find terms that match a range ignoring case
*
* @author andyh
*/
public class CaseInsensitiveFieldRangeQuery extends MultiTermQuery
{
/**
*
*/
private static final long serialVersionUID = -5859977841901861122L;
String expandedFieldName;
String lowerTermText;
String upperTermText;
boolean includeLower;
boolean includeUpper;
/**
* @param expandedFieldName -
* field
* @param lowerTermText -
* upper range value
* @param upperTermText -
* lower range value
* @param includeLower -
* include the lower value
* @param includeUpper -
* include the upper value
*/
public CaseInsensitiveFieldRangeQuery(String expandedFieldName, String lowerTermText, String upperTermText, boolean includeLower, boolean includeUpper)
{
super(new Term(expandedFieldName, ""));
this.expandedFieldName = expandedFieldName;
this.lowerTermText = lowerTermText;
this.upperTermText = upperTermText;
this.includeLower = includeLower;
this.includeUpper = includeUpper;
}
@Override
protected FilteredTermEnum getEnum(IndexReader reader) throws IOException
{
return new CaseInsensitiveTermRangeEnum(reader, expandedFieldName, lowerTermText, upperTermText, includeLower, includeUpper);
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.search.impl.lucene.query;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FilteredTermEnum;
/**
* A term enum to find case insensitive matches - used for Upper and Lower
*
* @author andyh
*/
public class CaseInsensitiveTermEnum extends FilteredTermEnum
{
private String field = "";
private boolean endEnum = false;
private String text;
/**
* @param reader =
* the index reader
* @param term -
* the term to match
* @throws IOException
*/
public CaseInsensitiveTermEnum(IndexReader reader, Term term) throws IOException
{
super();
field = term.field();
text = term.text();
// position at the start - we could do slightly better
setEnum(reader.terms(new Term(term.field(), "")));
}
@Override
public float difference()
{
return 1.0f;
}
@Override
protected boolean endEnum()
{
return endEnum;
}
@Override
protected boolean termCompare(Term term)
{
if (field.equals(term.field()))
{
String searchText = term.text();
return searchText.equalsIgnoreCase(text);
}
endEnum = true;
return false;
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.search.impl.lucene.query;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FilteredTermEnum;
/**
* A term enum that finds terms that lie with in some range ignoring case
*
* @author andyh
*/
public class CaseInsensitiveTermRangeEnum extends FilteredTermEnum
{
private boolean endEnum = false;
String expandedFieldName;
String lowerTermText;
String upperTermText;
boolean includeLower;
boolean includeUpper;
/**
* @param reader
* the index reader
* @param expandedFieldName -
* field
* @param lowerTermText -
* upper range value
* @param upperTermText -
* lower range value
* @param includeLower -
* include the lower value
* @param includeUpper -
* include the upper value
* @throws IOException
*/
public CaseInsensitiveTermRangeEnum(IndexReader reader, String expandedFieldName, String lowerTermText, String upperTermText, boolean includeLower, boolean includeUpper)
throws IOException
{
super();
this.expandedFieldName = expandedFieldName;
this.lowerTermText = lowerTermText.toLowerCase();
this.upperTermText = upperTermText.toLowerCase();
this.includeLower = includeLower;
this.includeUpper = includeUpper;
setEnum(reader.terms(new Term(expandedFieldName, "")));
}
@Override
public float difference()
{
return 1.0f;
}
@Override
protected boolean endEnum()
{
return endEnum;
}
@Override
protected boolean termCompare(Term term)
{
if (expandedFieldName.equals(term.field()))
{
String searchText = term.text().toLowerCase();
return checkLower(searchText) && checkUpper(searchText);
}
endEnum = true;
return false;
}
private boolean checkLower(String searchText)
{
if (includeLower)
{
return (lowerTermText.compareTo(searchText) <= 0);
}
else
{
return (lowerTermText.compareTo(searchText) < 0);
}
}
private boolean checkUpper(String searchText)
{
if (includeUpper)
{
return (upperTermText.compareTo(searchText) >= 0);
}
else
{
return (upperTermText.compareTo(searchText) > 0);
}
}
}

View File

@ -29,7 +29,9 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.FunctionArgument;
import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext;
import org.alfresco.repo.search.impl.querymodel.PredicateMode;
import org.alfresco.service.cmr.dictionary.DictionaryService;
@ -40,6 +42,11 @@ import org.alfresco.service.namespace.QName;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
/**
* Alfrecso function evaluation context for evaluating FTS expressions against lucene.
* @author andyh
*
*/
public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationContext
{
private static HashSet<String> EXPOSED_FIELDS = new HashSet<String>();
@ -72,6 +79,11 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
EXPOSED_FIELDS.add("ISNOTNULL");
}
/**
* @param namespacePrefixResolver
* @param dictionaryService
* @param defaultNamespace
*/
public AlfrescoFunctionEvaluationContext(NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService, String defaultNamespace)
{
this.namespacePrefixResolver = namespacePrefixResolver;
@ -79,7 +91,7 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
this.defaultNamespace = defaultNamespace;
}
public Query buildLuceneEquality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneEquality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new UnsupportedOperationException();
}
@ -89,12 +101,12 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
throw new UnsupportedOperationException();
}
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new UnsupportedOperationException();
}
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new UnsupportedOperationException();
}
@ -104,17 +116,17 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
throw new UnsupportedOperationException();
}
public Query buildLuceneInequality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneInequality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new UnsupportedOperationException();
}
public Query buildLuceneLessThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new UnsupportedOperationException();
}
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException
{
throw new UnsupportedOperationException();
}
@ -177,7 +189,7 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
return propertyName;
}
if(propertyName.startsWith("{"))
if (propertyName.startsWith("{"))
{
QName qname = QName.createQName(propertyName);
if (dictionaryService.getProperty(qname) != null)
@ -186,7 +198,7 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
}
else
{
throw new FTSQueryException("Unknown property: "+propertyName);
throw new FTSQueryException("Unknown property: " + propertyName);
}
}
@ -201,7 +213,7 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
}
else
{
throw new FTSQueryException("Unknown property: "+propertyName);
throw new FTSQueryException("Unknown property: " + propertyName);
}
}
@ -209,18 +221,18 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
if (index != -1)
{
// Try as a property, if invalid pass through
QName qname = QName.createQName(propertyName.substring(0, index), propertyName.substring(index+1), namespacePrefixResolver);
QName qname = QName.createQName(propertyName.substring(0, index), propertyName.substring(index + 1), namespacePrefixResolver);
if (dictionaryService.getProperty(qname) != null)
{
return "@" + qname.toString();
}
else
{
throw new FTSQueryException("Unknown property: "+propertyName);
throw new FTSQueryException("Unknown property: " + propertyName);
}
}
if(EXPOSED_FIELDS.contains(propertyName))
if (EXPOSED_FIELDS.contains(propertyName))
{
return propertyName;
}
@ -232,9 +244,14 @@ public class AlfrescoFunctionEvaluationContext implements FunctionEvaluationCont
}
else
{
throw new FTSQueryException("Unknown property: "+propertyName);
throw new FTSQueryException("Unknown property: " + propertyName);
}
}
public LuceneFunction getLuceneFunction(FunctionArgument functionArgument)
{
throw new UnsupportedOperationException();
}
}

View File

@ -28,53 +28,184 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
/**
* The function evaluation context for lucene query implementations.
*
* This context is used at query time and also when navigating the results to get column values.
*
* @author andyh
*/
public interface FunctionEvaluationContext
{
/**
* @return the matching nodes by selector (at navigation time)
*/
public Map<String, NodeRef> getNodeRefs();
/**
* @return the scores by selector (at navigation time)
*/
public Map<String, Float> getScores();
/**
* Get a property
* @param nodeRef
* @param propertyName
* @return the property (at navigation time)
*/
public Serializable getProperty(NodeRef nodeRef, String propertyName);
/**
* @return the node service
*/
public NodeService getNodeService();
/**
* @return the score (at navigation time)
*/
public Float getScore();
public Query buildLuceneEquality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException;
/**
* @param lqp
* @param propertyName
* @param value
* @param mode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneEquality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* Note: null and not null are not required to support functions from the spec
* @param lqp
* @param propertyName
* @param not
* @return the query
* @throws ParseException
*/
public Query buildLuceneExists(LuceneQueryParser lqp, String propertyName, Boolean not) throws ParseException;
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException;
/**
* @param lqp
* @param propertyName
* @param value
* @param mode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneGreaterThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException;
/**
* @param lqp
* @param propertyName
* @param value
* @param mode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneGreaterThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
public Query buildLuceneLessThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException;
/**
* @param lqp
* @param propertyName
* @param value
* @param mode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneLessThan(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException;
/**
* @param lqp
* @param propertyName
* @param value
* @param mode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneLessThanOrEquals(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* Note: Like is not required to support functions from the spec
* @param lqp
* @param propertyName
* @param value
* @param not
* @return the query
* @throws ParseException
*/
public Query buildLuceneLike(LuceneQueryParser lqp, String propertyName, Serializable value, Boolean not) throws ParseException;
public Query buildLuceneInequality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode) throws ParseException;
/**
* @param lqp
* @param propertyName
* @param value
* @param mode
* @param luceneFunction
* @return the query
* @throws ParseException
*/
public Query buildLuceneInequality(LuceneQueryParser lqp, String propertyName, Serializable value, PredicateMode mode, LuceneFunction luceneFunction) throws ParseException;
/**
* Note: In is not required to support functions from the spec
* @param lqp
* @param propertyName
* @param values
* @param not
* @param mode
* @return the query
* @throws ParseException
*/
public Query buildLuceneIn(LuceneQueryParser lqp, String propertyName, Collection<Serializable> values, Boolean not, PredicateMode mode) throws ParseException;
/**
* @param propertyName
* @return the field used for sorting the given property
*/
public String getLuceneSortField(String propertyName);
/**
* @param propertyName
* @return - is this an object id
*/
public boolean isObjectId(String propertyName);
/**
* @param propertyName
* @return is this property queryable
*/
public boolean isQueryable(String propertyName);
/**
* @param propertyName
* @return Is this property orderable
*/
public boolean isOrderable(String propertyName);
/**
* @param propertyName
* @return the lucene field name for the property
*/
public String getLuceneFieldName(String propertyName);
/**
* @param functionArgument
* @return the lucene function appropriate to a function argument
*/
public LuceneFunction getLuceneFunction(FunctionArgument functionArgument);
}

View File

@ -29,10 +29,13 @@ import java.util.Map;
import org.alfresco.repo.search.impl.querymodel.Argument;
import org.alfresco.repo.search.impl.querymodel.ArgumentDefinition;
import org.alfresco.repo.search.impl.querymodel.FunctionArgument;
import org.alfresco.repo.search.impl.querymodel.Multiplicity;
import org.alfresco.repo.search.impl.querymodel.PropertyArgument;
import org.alfresco.repo.search.impl.querymodel.QueryModelException;
import org.alfresco.repo.search.impl.querymodel.StaticArgument;
import org.alfresco.repo.search.impl.querymodel.impl.functions.Lower;
import org.alfresco.repo.search.impl.querymodel.impl.functions.Upper;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.namespace.QName;
@ -41,21 +44,32 @@ import org.alfresco.service.namespace.QName;
*/
public abstract class BaseComparison extends BaseFunction
{
/**
* Left hand side
*/
public final static String ARG_LHS = "LHS";
/**
* Right hand side
*/
public final static String ARG_RHS = "RHS";
public static LinkedHashMap<String, ArgumentDefinition> args;
/**
* Args
*/
public static LinkedHashMap<String, ArgumentDefinition> ARGS;
private PropertyArgument propertyArgument;
private StaticArgument staticArgument;
private FunctionArgument functionArgument;
static
{
args = new LinkedHashMap<String, ArgumentDefinition>();
args.put(ARG_LHS, new BaseArgumentDefinition(Multiplicity.ANY, ARG_LHS, DataTypeDefinition.ANY, true));
args.put(ARG_RHS, new BaseArgumentDefinition(Multiplicity.ANY, ARG_RHS, DataTypeDefinition.ANY, true));
ARGS = new LinkedHashMap<String, ArgumentDefinition>();
ARGS.put(ARG_LHS, new BaseArgumentDefinition(Multiplicity.ANY, ARG_LHS, DataTypeDefinition.ANY, true));
ARGS.put(ARG_RHS, new BaseArgumentDefinition(Multiplicity.ANY, ARG_RHS, DataTypeDefinition.ANY, true));
}
/**
@ -68,14 +82,14 @@ public abstract class BaseComparison extends BaseFunction
super(name, returnType, argumentDefinitions);
}
public void setPropertyAndStaticArguments(Map<String, Argument> functionArgs)
protected void setPropertyAndStaticArguments(Map<String, Argument> functionArgs)
{
Argument lhs = functionArgs.get(ARG_LHS);
Argument rhs = functionArgs.get(ARG_RHS);
if (lhs instanceof PropertyArgument)
{
if (rhs instanceof PropertyArgument)
if ((rhs instanceof PropertyArgument) || (rhs instanceof FunctionArgument))
{
throw new QueryModelException("Implicit join is not supported");
}
@ -89,9 +103,29 @@ public abstract class BaseComparison extends BaseFunction
throw new QueryModelException("Argument of type " + rhs.getClass().getName() + " is not supported");
}
}
else if (lhs instanceof FunctionArgument)
{
if ((rhs instanceof PropertyArgument) || (rhs instanceof FunctionArgument))
{
throw new QueryModelException("Implicit join is not supported");
}
else if (rhs instanceof StaticArgument)
{
functionArgument = (FunctionArgument) lhs;
staticArgument = (StaticArgument) rhs;
}
else
{
throw new QueryModelException("Argument of type " + rhs.getClass().getName() + " is not supported");
}
}
else if (rhs instanceof PropertyArgument)
{
if (lhs instanceof StaticArgument)
if ((lhs instanceof PropertyArgument) || (lhs instanceof FunctionArgument))
{
throw new QueryModelException("Implicit join is not supported");
}
else if (lhs instanceof StaticArgument)
{
propertyArgument = (PropertyArgument) rhs;
staticArgument = (StaticArgument) lhs;
@ -101,6 +135,22 @@ public abstract class BaseComparison extends BaseFunction
throw new QueryModelException("Argument of type " + lhs.getClass().getName() + " is not supported");
}
}
else if (rhs instanceof FunctionArgument)
{
if ((lhs instanceof PropertyArgument) || (lhs instanceof FunctionArgument))
{
throw new QueryModelException("Implicit join is not supported");
}
else if (lhs instanceof StaticArgument)
{
functionArgument = (FunctionArgument) rhs;
staticArgument = (StaticArgument) lhs;
}
else
{
throw new QueryModelException("Argument of type " + lhs.getClass().getName() + " is not supported");
}
}
else
{
throw new QueryModelException("Equals must have one property argument");
@ -108,7 +158,7 @@ public abstract class BaseComparison extends BaseFunction
}
/**
* @return the propertyArgument
* @return the propertyArgument - there must be a property argument of a function argument
*/
protected PropertyArgument getPropertyArgument()
{
@ -116,13 +166,63 @@ public abstract class BaseComparison extends BaseFunction
}
/**
* @return the staticArgument
* @return the staticArgument - must be set
*/
protected StaticArgument getStaticArgument()
{
return staticArgument;
}
/**
* @return the functionArgument
*/
protected FunctionArgument getFunctionArgument()
{
return functionArgument;
}
protected String getPropertyName()
{
if (propertyArgument != null)
{
return propertyArgument.getPropertyName();
}
else if (functionArgument != null)
{
String functionName = functionArgument.getFunction().getName();
if (functionName.equals(Upper.NAME))
{
Argument arg = functionArgument.getFunctionArguments().get(Upper.ARG_ARG);
if (arg instanceof PropertyArgument)
{
return ((PropertyArgument) arg).getPropertyName();
}
else
{
throw new QueryModelException("Upper must have a column argument " + arg);
}
}
else if (functionName.equals(Lower.NAME))
{
Argument arg = functionArgument.getFunctionArguments().get(Lower.ARG_ARG);
if (arg instanceof PropertyArgument)
{
return ((PropertyArgument) arg).getPropertyName();
}
else
{
throw new QueryModelException("Lower must have a column argument " + arg);
}
}
else
{
throw new QueryModelException("Unsupported function: " + functionName);
}
}
else
{
throw new QueryModelException("A property of function argument must be provided");
}
}
}

View File

@ -47,7 +47,7 @@ public class Equals extends BaseComparison
*/
public Equals()
{
super(NAME, DataTypeDefinition.BOOLEAN, args);
super(NAME, DataTypeDefinition.BOOLEAN, ARGS);
}
/* (non-Javadoc)

View File

@ -47,7 +47,7 @@ public class GreaterThan extends BaseComparison
*/
public GreaterThan()
{
super(NAME, DataTypeDefinition.BOOLEAN, args);
super(NAME, DataTypeDefinition.BOOLEAN, ARGS);
}
/* (non-Javadoc)

View File

@ -47,7 +47,7 @@ public class GreaterThanOrEquals extends BaseComparison
*/
public GreaterThanOrEquals()
{
super(NAME, DataTypeDefinition.BOOLEAN, args);
super(NAME, DataTypeDefinition.BOOLEAN, ARGS);
}
/* (non-Javadoc)

View File

@ -46,7 +46,7 @@ public class LessThan extends BaseComparison
*/
public LessThan()
{
super(NAME, DataTypeDefinition.BOOLEAN, args);
super(NAME, DataTypeDefinition.BOOLEAN, ARGS);
}
/*

View File

@ -46,7 +46,7 @@ public class LessThanOrEquals extends BaseComparison
*/
public LessThanOrEquals()
{
super(NAME, DataTypeDefinition.BOOLEAN, args);
super(NAME, DataTypeDefinition.BOOLEAN, ARGS);
}
/*

View File

@ -46,7 +46,7 @@ public class NotEquals extends BaseComparison
*/
public NotEquals()
{
super(NAME, DataTypeDefinition.BOOLEAN, args);
super(NAME, DataTypeDefinition.BOOLEAN, ARGS);
}
/*

View File

@ -65,7 +65,7 @@ public class LuceneEquals extends Equals implements LuceneQueryBuilderComponent
LuceneQueryParser lqp = luceneContext.getLuceneQueryParser();
setPropertyAndStaticArguments(functionArgs);
Query query = functionContext.buildLuceneEquality(lqp, getPropertyArgument().getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY);
Query query = functionContext.buildLuceneEquality(lqp, getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY, functionContext.getLuceneFunction(getFunctionArgument()));
if(query == null)
{

View File

@ -28,6 +28,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.Argument;
import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext;
@ -78,11 +79,11 @@ public class LuceneFTSPhrase extends FTSPhrase implements LuceneQueryBuilderComp
if (propArg != null)
{
String prop = propArg.getPropertyName();
query = lqp.getFieldQuery(functionContext.getLuceneFieldName(prop), term, AnalysisMode.TOKENISE, slop);
query = lqp.getFieldQuery(functionContext.getLuceneFieldName(prop), term, AnalysisMode.TOKENISE, slop, LuceneFunction.FIELD);
}
else
{
query = lqp.getFieldQuery("TEXT", term, AnalysisMode.TOKENISE, slop);
query = lqp.getFieldQuery("TEXT", term, AnalysisMode.TOKENISE, slop, LuceneFunction.FIELD);
}
return query;

View File

@ -28,6 +28,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.querymodel.Argument;
import org.alfresco.repo.search.impl.querymodel.FunctionEvaluationContext;
@ -78,11 +79,11 @@ public class LuceneFTSRange extends FTSRange implements LuceneQueryBuilderCompon
if (propArg != null)
{
String prop = propArg.getPropertyName();
query = lqp.getRangeQuery(functionContext.getLuceneFieldName(prop), from, to, fromInc, toInc, AnalysisMode.DEFAULT);
query = lqp.getRangeQuery(functionContext.getLuceneFieldName(prop), from, to, fromInc, toInc, AnalysisMode.DEFAULT, LuceneFunction.FIELD);
}
else
{
query = lqp.getRangeQuery("TEXT", from, to, fromInc, toInc, AnalysisMode.DEFAULT);
query = lqp.getRangeQuery("TEXT", from, to, fromInc, toInc, AnalysisMode.DEFAULT, LuceneFunction.FIELD);
}
return query;
}

View File

@ -27,6 +27,7 @@ package org.alfresco.repo.search.impl.querymodel.impl.lucene.functions;
import java.util.Map;
import java.util.Set;
import org.alfresco.repo.search.impl.lucene.LuceneFunction;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.search.impl.lucene.AnalysisMode;
import org.alfresco.repo.search.impl.querymodel.Argument;
@ -72,11 +73,11 @@ public class LuceneFTSTerm extends FTSTerm implements LuceneQueryBuilderComponen
if (propArg != null)
{
String prop = propArg.getPropertyName();
query = lqp.getFieldQuery(functionContext.getLuceneFieldName(prop), term, mode);
query = lqp.getFieldQuery(functionContext.getLuceneFieldName(prop), term, mode, LuceneFunction.FIELD);
}
else
{
query = lqp.getFieldQuery("TEXT", term, mode);
query = lqp.getFieldQuery("TEXT", term, mode, LuceneFunction.FIELD);
}
return query;

View File

@ -65,7 +65,7 @@ public class LuceneGreaterThan extends GreaterThan implements LuceneQueryBuilder
LuceneQueryParser lqp = luceneContext.getLuceneQueryParser();
setPropertyAndStaticArguments(functionArgs);
Query query = functionContext.buildLuceneGreaterThan(lqp, getPropertyArgument().getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY);
Query query = functionContext.buildLuceneGreaterThan(lqp, getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY, functionContext.getLuceneFunction(getFunctionArgument()));
if(query == null)
{

View File

@ -66,7 +66,7 @@ public class LuceneGreaterThanOrEquals extends GreaterThanOrEquals implements Lu
LuceneQueryParser lqp = luceneContext.getLuceneQueryParser();
setPropertyAndStaticArguments(functionArgs);
Query query = functionContext.buildLuceneGreaterThanOrEquals(lqp, getPropertyArgument().getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY);
Query query = functionContext.buildLuceneGreaterThanOrEquals(lqp, getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY, functionContext.getLuceneFunction(getFunctionArgument()));
if(query == null)
{

View File

@ -66,7 +66,7 @@ public class LuceneLessThan extends LessThan implements LuceneQueryBuilderCompon
LuceneQueryParser lqp = luceneContext.getLuceneQueryParser();
setPropertyAndStaticArguments(functionArgs);
Query query = functionContext.buildLuceneLessThan(lqp, getPropertyArgument().getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY);
Query query = functionContext.buildLuceneLessThan(lqp, getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY, functionContext.getLuceneFunction(getFunctionArgument()));
if(query == null)
{

View File

@ -66,7 +66,7 @@ public class LuceneLessThanOrEquals extends LessThanOrEquals implements LuceneQu
LuceneQueryParser lqp = luceneContext.getLuceneQueryParser();
setPropertyAndStaticArguments(functionArgs);
Query query = functionContext.buildLuceneLessThanOrEquals(lqp, getPropertyArgument().getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY);
Query query = functionContext.buildLuceneLessThanOrEquals(lqp, getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY, functionContext.getLuceneFunction(getFunctionArgument()));
if(query == null)
{
throw new QueryModelException("No query time mapping for property "+getPropertyArgument().getPropertyName()+", it should not be allowed in predicates");

View File

@ -40,7 +40,6 @@ import org.apache.lucene.search.Query;
/**
* @author andyh
*
*/
public class LuceneNotEquals extends NotEquals implements LuceneQueryBuilderComponent
{
@ -66,15 +65,15 @@ public class LuceneNotEquals extends NotEquals implements LuceneQueryBuilderComp
LuceneQueryParser lqp = luceneContext.getLuceneQueryParser();
setPropertyAndStaticArguments(functionArgs);
Query query = functionContext.buildLuceneInequality(lqp, getPropertyArgument().getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY);
Query query = functionContext.buildLuceneInequality(lqp, getPropertyName(), getStaticArgument().getValue(functionContext), PredicateMode.ANY, functionContext
.getLuceneFunction(getFunctionArgument()));
if(query == null)
if (query == null)
{
throw new QueryModelException("No query time mapping for property "+getPropertyArgument().getPropertyName()+", it should not be allowed in predicates");
throw new QueryModelException("No query time mapping for property " + getPropertyArgument().getPropertyName() + ", it should not be allowed in predicates");
}
return query;
}
}