LUCENE-1567: New flexible QueryParser framework.

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@800191 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Busch 2009-08-03 03:38:44 +00:00
parent ca38f0a917
commit 343992fcbb
189 changed files with 21715 additions and 9 deletions

View File

@ -359,6 +359,11 @@ API Changes
34. LUCENE-1460: Changed TokenStreams/TokenFilters in contrib to
use the new TokenStream API. (Robert Muir, Michael Busch)
35. LUCENE-1567: Deprecated Queryparser, which will be replaced by a
new QueryParser framework in Lucene 3.0, that is currently located
in contrib. (see New Features 35.)
(Luis Alves and Adriano Campos via Michael Busch)
Bug fixes
1. LUCENE-1415: MultiPhraseQuery has incorrect hashCode() and equals()
@ -641,7 +646,14 @@ New features
operations. This is currently used to fix offset problems when
multiple fields with the same name are added to a document.
(Mike McCandless, Mark Miller, Michael Busch)
35. LUCENE-1567: Added a new QueryParser framework to contrib, that
allows implementing a new query syntax in a flexible and efficient
way. This new QueryParser will be moved to Lucene's core in release
3.0 and will then replace the current core QueryParser, which
has been deprecated with this patch.
(Luis Alves and Adriano Campos via Michael Busch)
Optimizations
1. LUCENE-1427: Fixed QueryWrapperFilter to not waste time computing

View File

@ -330,6 +330,7 @@
<packageset dir="contrib/wikipedia/src/java"/>
<packageset dir="contrib/wordnet/src/java"/>
<packageset dir="contrib/xml-query-parser/src/java"/>
<packageset dir="contrib/queryparser/src/java"/>
<!-- end alpha sort -->
<!-- If the main javadoc Group listing includes an "Other -->
@ -352,6 +353,7 @@
<group title="contrib: Memory" packages="org.apache.lucene.index.memory*"/>
<group title="contrib: Miscellaneous " packages="org.apache.lucene.misc*:org.apache.lucene.queryParser.analyzing*:org.apache.lucene.queryParser.precedence*"/>
<group title="contrib: Queries" packages="org.apache.lucene.search.similar*"/>
<group title="contrib: Query Parser" packages="org.apache.lucene.queryParser*"/>
<group title="contrib: RegEx" packages="org.apache.lucene.search.regex*:org.apache.regexp*"/>
<group title="contrib: Snowball" packages="org.apache.lucene.analysis.snowball*:net.sf.snowball*"/>
<group title="contrib: Spatial" packages="org.apache.lucene.spatial*"/>
@ -361,7 +363,7 @@
<group title="contrib: Wikipedia" packages="org.apache.lucene.wikipedia*"/>
<group title="contrib: WordNet" packages="org.apache.lucene.wordnet*"/>
<group title="contrib: XML Query Parser" packages="org.apache.lucene.xmlparser*"/>
</sources>
</invoke-javadoc>
</sequential>

View File

@ -100,6 +100,13 @@ New features
and fine tune how regular expressions are compiled and
matched. (Marc Zampetti zampettim@aim.com via Mike McCandless)
12. LUCENE-1567: Added a new QueryParser framework, that allows
implementing a new query syntax in a flexible and efficient way.
This new QueryParser will be moved to Lucene's core in release
3.0 and will then replace the current core QueryParser, which
has been deprecated with this patch.
(Luis Alves and Adriano Campos via Michael Busch)
Optimizations
1. LUCENE-1643: Re-use the collation key (RawCollationKey) for

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project name="queryparser" default="default">
<description>
Flexible Query Parser
</description>
<property name="javac.source" value="1.5" />
<property name="javac.target" value="1.5" />
<import file="../contrib-build.xml"/>
</project>

View File

@ -0,0 +1,40 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-contrib</artifactId>
<version>@version@</version>
</parent>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<name>Lucene Query Parser</name>
<version>@version@</version>
<description>
This is the Flexible Query Parser for apache lucene java
</description>
<packaging>jar</packaging>
<dependencies>
</dependencies>
</project>

View File

@ -0,0 +1,37 @@
package org.apache.lucene.messages;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.Serializable;
import java.util.Locale;
/**
* Message Interface for a lazy loading.
* For Native Language Support (NLS), system of software internationalization.
*/
public interface Message extends Serializable {
public String getKey();
public Object[] getArguments();
public String getLocalizedMessage();
public String getLocalizedMessage(Locale locale);
}

View File

@ -0,0 +1,71 @@
package org.apache.lucene.messages;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Locale;
/**
* Default implementation of Message interface.
* For Native Language Support (NLS), system of software internationalization.
*/
public class MessageImpl implements Message {
private static final long serialVersionUID = -3077643314630884523L;
private String key;
private Object[] arguments = new Object[0];
public MessageImpl(String key) {
this.key = key;
}
public MessageImpl(String key, Object... args) {
this(key);
this.arguments = args;
}
public Object[] getArguments() {
return this.arguments;
}
public String getKey() {
return this.key;
}
public String getLocalizedMessage() {
return getLocalizedMessage(Locale.getDefault());
}
public String getLocalizedMessage(Locale locale) {
return NLS.getLocalizedMessage(getKey(), locale, getArguments());
}
public String toString() {
Object[] args = getArguments();
String argsString = "";
if (args != null) {
for (int i = 0; i < args.length; i++) {
argsString += args[i] + (i < args.length ? "" : ", ");
}
}
return getKey() + " " + argsString;
}
}

View File

@ -0,0 +1,209 @@
package org.apache.lucene.messages;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* MessageBundles classes extend this class, to implement a bundle.
*
* For Native Language Support (NLS), system of software internationalization.
*
* This interface is similar to the NLS class in eclipse.osgi.util.NLS class -
* initializeMessages() method resets the values of all static strings, should
* only be called by classes that extend from NLS (see TestMessages.java for
* reference) - performs validation of all message in a bundle, at class load
* time - performs per message validation at runtime - see NLSTest.java for
* usage reference
*
* MessageBundle classes may subclass this type.
*/
public class NLS {
private static Map<String, Class<Object>> bundles = new HashMap<String, Class<Object>>(
0);
protected NLS() {
// Do not instantiate
}
public static String getLocalizedMessage(String key) {
return getLocalizedMessage(key, Locale.getDefault());
}
public static String getLocalizedMessage(String key, Locale locale) {
Object message = getResourceBundleObject(key, locale);
if (message == null) {
return "Message with key:" + key + " and locale: " + locale
+ " not found.";
}
return message.toString();
}
public static String getLocalizedMessage(String key, Locale locale,
Object... args) {
String str = getLocalizedMessage(key, locale);
if (args.length > 0) {
str = MessageFormat.format(str, args);
}
return str;
}
public static String getLocalizedMessage(String key, Object... args) {
return getLocalizedMessage(key, Locale.getDefault(), args);
}
/**
* Initialize a given class with the message bundle Keys Should be called from
* a class that extends NLS in a static block at class load time.
*
* @param bundleName
* Property file with that contains the message bundle
* @param clazz
* where constants will reside
*/
@SuppressWarnings("unchecked")
protected static void initializeMessages(String bundleName, Class clazz) {
try {
load(clazz);
if (!bundles.containsKey(bundleName))
bundles.put(bundleName, clazz);
} catch (Throwable e) {
// ignore all errors and exceptions
// because this function is supposed to be called at class load time.
}
}
private static Object getResourceBundleObject(String messageKey, Locale locale) {
// slow resource checking
// need to loop thru all registered resource bundles
for (Iterator<String> it = bundles.keySet().iterator(); it.hasNext();) {
Class<Object> clazz = bundles.get(it.next());
ResourceBundle resourceBundle = ResourceBundle.getBundle(clazz.getName(),
locale);
if (resourceBundle != null) {
try {
Object obj = resourceBundle.getObject(messageKey);
if (obj != null)
return obj;
} catch (MissingResourceException e) {
// just continue it might be on the next resource bundle
}
}
}
// if resource is not found
return null;
}
/**
* @param bundleName
* @param clazz
*/
private static void load(Class<Object> clazz) {
final Field[] fieldArray = clazz.getDeclaredFields();
boolean isFieldAccessible = (clazz.getModifiers() & Modifier.PUBLIC) != 0;
// build a map of field names to Field objects
final int len = fieldArray.length;
Map<String, Field> fields = new HashMap<String, Field>(len * 2);
for (int i = 0; i < len; i++) {
fields.put(fieldArray[i].getName(), fieldArray[i]);
loadfieldValue(fieldArray[i], isFieldAccessible, clazz);
}
}
/**
* @param field
* @param isFieldAccessible
*/
private static void loadfieldValue(Field field, boolean isFieldAccessible,
Class<Object> clazz) {
int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED)
return;
// Set a value for this empty field.
if (!isFieldAccessible)
makeAccessible(field);
try {
field.set(null, field.getName());
validateMessage(field.getName(), clazz);
} catch (IllegalArgumentException e) {
// should not happen
} catch (IllegalAccessException e) {
// should not happen
}
}
/**
* @param key
* - Message Key
*/
private static void validateMessage(String key, Class<Object> clazz) {
// Test if the message is present in the resource bundle
try {
ResourceBundle resourceBundle = ResourceBundle.getBundle(clazz.getName(),
Locale.getDefault());
if (resourceBundle != null) {
Object obj = resourceBundle.getObject(key);
if (obj == null)
System.err.println("WARN: Message with key:" + key + " and locale: "
+ Locale.getDefault() + " not found.");
}
} catch (MissingResourceException e) {
System.err.println("WARN: Message with key:" + key + " and locale: "
+ Locale.getDefault() + " not found.");
} catch (Throwable e) {
// ignore all other errors and exceptions
// since this code is just a test to see if the message is present on the
// system
}
}
/*
* Make a class field accessible
*/
@SuppressWarnings("unchecked")
private static void makeAccessible(final Field field) {
if (System.getSecurityManager() == null) {
field.setAccessible(true);
} else {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
field.setAccessible(true);
return null;
}
});
}
}
}

View File

@ -0,0 +1,34 @@
package org.apache.lucene.messages;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Interface that exceptions should implement to support lazy loading of messages.
*
* For Native Language Support (NLS), system of software internationalization.
*
* This Interface should be implemented by all exceptions that require
* translation
*
*/
public interface NLSException {
/**
* @return a instance of a class that implements the Message interface
*/
public Message getMessageObject();
}

View File

@ -0,0 +1,99 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
For Native Language Support (NLS), system of software internationalization.
<h2>NLS message API</h2>
<p>
This utility API, adds support for NLS messages in the apache code.
It is currently used by the lucene "New Flexible Query PArser".
</p>
<p>
Features:
<ol>
<li>Message reference in the code, using static Strings</li>
<li>Message resource validation at class load time, for easier debugging</li>
<li>Allows for message IDs to be re-factored using eclipse or other code re-factor tools</li>
<li>Allows for reference count on messages, just like code</li>
<li>Lazy loading of Message Strings</li>
<li>Normal loading Message Strings</li>
</ol>
</p>
<br/>
<br/>
<p>
Lazy loading of Message Strings
<pre>
public class MessagesTestBundle extends NLS {
private static final String BUNDLE_NAME = MessagesTestBundle.class.getName();
private MessagesTestBundle() {
// should never be instantiated
}
static {
// register all string ids with NLS class and initialize static string
// values
NLS.initializeMessages(BUNDLE_NAME, MessagesTestBundle.class);
}
// static string must match the strings in the property files.
public static String Q0001E_INVALID_SYNTAX;
public static String Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION;
// this message is missing from the properties file
public static String Q0005E_MESSAGE_NOT_IN_BUNDLE;
}
// Create a message reference
Message invalidSyntax = new MessageImpl(MessagesTestBundle.Q0001E_INVALID_SYNTAX, "XXX");
// Do other stuff in the code...
// when is time to display the message to the user or log the message on a file
// the message is loaded from the correct bundle
String message1 = invalidSyntax.getLocalizedMessage();
String message2 = invalidSyntax.getLocalizedMessage(Locale.JAPANESE);
</pre>
</p>
<br/>
<br/>
<p>
Normal loading of Message Strings
<pre>
String message1 = NLS.getLocalizedMessage(MessagesTestBundle.Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION);
String message2 = NLS.getLocalizedMessage(MessagesTestBundle.Q0004E_INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION, Locale.JAPANESE);
</pre>
</p>
<p>
The org.apache.lucene.messages.TestNLS junit contains several other examples.
The TestNLS java code is available from the Apache Lucene code repository.
</p>
</body>
</html>

View File

@ -0,0 +1,75 @@
package org.apache.lucene.queryParser.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.Message;
import org.apache.lucene.messages.NLSException;
/**
* Error class with NLS support
*
* @see org.apache.lucene.messages.NLS
* @see org.apache.lucene.messages.Message
*/
public class QueryNodeError extends Error implements NLSException {
private static final long serialVersionUID = 1804855832182710327L;
private Message message;
/**
* @param message
* - NLS Message Object
*/
public QueryNodeError(Message message) {
super(message.getKey());
this.message = message;
}
/**
* @param throwable
* - @see java.lang.Error
*/
public QueryNodeError(Throwable throwable) {
super(throwable);
}
/**
* @param message
* - NLS Message Object
* @param throwable
* - @see java.lang.Error
*/
public QueryNodeError(Message message, Throwable throwable) {
super(message.getKey(), throwable);
this.message = message;
}
/*
* (non-Javadoc)
*
* @see org.apache.lucene.messages.NLSException#getMessageObject()
*/
public Message getMessageObject() {
return this.message;
}
}

View File

@ -0,0 +1,87 @@
package org.apache.lucene.queryParser.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Locale;
import org.apache.lucene.messages.Message;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.messages.NLS;
import org.apache.lucene.messages.NLSException;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* <p>
* This exception should be thrown if something wrong happens when dealing with
* {@link QueryNode}s.
* </p>
* <p>
* It also supports NLS messages.
* </p>
*
* @see Message
* @see NLS
* @see NLSException
* @see QueryNode
*/
public class QueryNodeException extends Exception implements NLSException {
private static final long serialVersionUID = -5962648855261624214L;
protected Message message = new MessageImpl(QueryParserMessages.EMPTY_MESSAGE);
public QueryNodeException(Message message) {
super(message.getKey());
this.message = message;
}
public QueryNodeException(Throwable throwable) {
super(throwable);
}
public QueryNodeException(Message message, Throwable throwable) {
super(message.getKey(), throwable);
this.message = message;
}
public Message getMessageObject() {
return this.message;
}
public String getMessage() {
return getLocalizedMessage();
}
public String getLocalizedMessage() {
return getLocalizedMessage(Locale.getDefault());
}
public String getLocalizedMessage(Locale locale) {
return this.message.getLocalizedMessage(locale);
}
public String toString() {
return this.message.getKey() + ": " + getLocalizedMessage();
}
}

View File

@ -0,0 +1,121 @@
package org.apache.lucene.queryParser.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.Message;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.parser.SyntaxParser;
/**
* This should be thrown when an exception happens during the query parsing from
* string to the query node tree.
*
* @see QueryNodeException
* @see SyntaxParser
* @see QueryNode
*/
public class QueryNodeParseException extends QueryNodeException {
private static final long serialVersionUID = 8197535103538766773L;
private CharSequence query;
private int beginColumn = -1;
private int beginLine = -1;
private String errorToken = "";
public QueryNodeParseException(Message message) {
super(message);
}
public QueryNodeParseException(Throwable throwable) {
super(throwable);
}
public QueryNodeParseException(Message message, Throwable throwable) {
super(message, throwable);
}
public void setQuery(CharSequence query) {
this.query = query;
this.message = new MessageImpl(
QueryParserMessages.INVALID_SYNTAX_CANNOT_PARSE, query, "");
}
public CharSequence getQuery() {
return this.query;
}
/**
* @param errorToken
* the errorToken in the query
*/
protected void setErrorToken(String errorToken) {
this.errorToken = errorToken;
}
public String getErrorToken() {
return this.errorToken;
}
public void setNonLocalizedMessage(Message message) {
this.message = message;
}
/**
* For EndOfLine and EndOfFile ("<EOF>") parsing problems the last char in the
* string is returned For the case where the parser is not able to figure out
* the line and column number -1 will be returned
*
* @return line where the problem was found
*/
public int getBeginLine() {
return this.beginLine;
}
/**
* For EndOfLine and EndOfFile ("<EOF>") parsing problems the last char in the
* string is returned For the case where the parser is not able to figure out
* the line and column number -1 will be returned
*
* @return column of the first char where the problem was found
*/
public int getBeginColumn() {
return this.beginColumn;
}
/**
* @param beginLine
* the beginLine to set
*/
protected void setBeginLine(int beginLine) {
this.beginLine = beginLine;
}
/**
* @param beginColumn
* the beginColumn to set
*/
protected void setBeginColumn(int beginColumn) {
this.beginColumn = beginColumn;
}
}

View File

@ -0,0 +1,261 @@
package org.apache.lucene.queryParser.core;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.builders.QueryBuilder;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.parser.SyntaxParser;
import org.apache.lucene.queryParser.core.processors.QueryNodeProcessor;
/**
* <p>
* This class is a helper for the query parser framework, it does all the three
* query parser phrases at once: text parsing, query processing and query
* building.
* </p>
* <p>
* It contains methods that allows the user to change the implementation used on
* the three phases.
* </p>
*
* @see QueryNodeProcessor
* @see SyntaxParser
* @see QueryBuilder
* @see QueryConfigHandler
*/
public class QueryParserHelper {
private QueryNodeProcessor processor;
private SyntaxParser syntaxParser;
private QueryBuilder builder;
private QueryConfigHandler config;
/**
* Creates a query parser helper object using the specified configuration,
* text parser, processor and builder.
*
* @param queryConfigHandler
* the query configuration handler that will be initially set to this
* helper
* @param syntaxParser
* the text parser that will be initially set to this helper
* @param processor
* the query processor that will be initially set to this helper
* @param builder
* the query builder that will be initially set to this helper
*
* @see QueryNodeProcessor
* @see SyntaxParser
* @see QueryBuilder
* @see QueryConfigHandler
*/
public QueryParserHelper(QueryConfigHandler queryConfigHandler, SyntaxParser syntaxParser, QueryNodeProcessor processor,
QueryBuilder builder) {
this.syntaxParser = syntaxParser;
this.config = queryConfigHandler;
this.processor = processor;
this.builder = builder;
if (processor != null) {
processor.setQueryConfigHandler(queryConfigHandler);
}
}
/**
* Returns the processor object used to process the query node tree, it
* returns <code>null</code> if no processor is used.
*
* @return the actual processor used to process the query node tree,
* <code>null</code> if no processor is used
*
* @see QueryNodeProcessor
* @see #setQueryNodeProcessor(QueryNodeProcessor)
*/
public QueryNodeProcessor getQueryNodeProcessor() {
return processor;
}
/**
* Sets the processor that will be used to process the query node tree. If
* there is any {@link QueryConfigHandler} returned by
* {@link #getQueryConfigHandler()}, it will be set on the processor. The
* argument can be <code>null</code>, which means that no processor will be
* used to process the query node tree.
*
* @param processor
* the processor that will be used to process the query node tree,
* this argument can be <code>null</code>
*
* @see #getQueryNodeProcessor()
* @see QueryNodeProcessor
*/
public void setQueryNodeProcessor(QueryNodeProcessor processor) {
this.processor = processor;
this.processor.setQueryConfigHandler(getQueryConfigHandler());
}
/**
* Sets the text parser that will be used to parse the query string, it cannot
* be <code>null</code>.
*
* @param syntaxParser
* the text parser that will be used to parse the query string
*
* @see #getTextParser()
* @see SyntaxParser
*/
public void setSyntaxParser(SyntaxParser syntaxParser) {
if (syntaxParser == null) {
throw new IllegalArgumentException("textParser should not be null!");
}
this.syntaxParser = syntaxParser;
}
/**
* The query builder that will be used to build an object from the query node
* tree. It cannot be <code>null</code>.
*
* @param queryBuilder
* the query builder used to build something from the query node tree
*
* @see #getQueryBuilder()
* @see QueryBuilder
*/
public void setQueryBuilder(QueryBuilder queryBuilder) {
if (queryBuilder == null) {
throw new IllegalArgumentException("queryBuilder should not be null!");
}
this.builder = queryBuilder;
}
/**
* Returns the query configuration handler, which is used during the query
* node tree processing. It can be <code>null</code>.
*
* @return the query configuration handler used on the query processing,
* <code>null</code> if not query configuration handler is defined
*
* @see QueryConfigHandler
* @see #setQueryConfigHandler(QueryConfigHandler)
*/
public QueryConfigHandler getQueryConfigHandler() {
return config;
}
/**
* Returns the query builder used to build a object from the query node tree.
* The object produced by this builder is returned by
* {@link #parse(String, String)}.
*
* @return the query builder
*
* @see #setQueryBuilder(QueryBuilder)
* @see QueryBuilder
*/
public QueryBuilder getQueryBuilder() {
return this.builder;
}
/**
* Returns the text parser used to build a query node tree from a query
* string. The default text parser instance returned by this method is a
* {@link SyntaxParser}.
*
* @return the text parse used to build query node trees.
*
* @see SyntaxParser
* @see #setSyntaxParser(SyntaxParser)
*/
public SyntaxParser getTextParser() {
return this.syntaxParser;
}
/**
* Sets the query configuration handler that will be used during query
* processing. It can be <code>null</code>. It's also set to the processor
* returned by {@link #getQueryNodeProcessor()}.
*
* @param config
* the query configuration handler used during query processing, it
* can be <code>null</code>
*
* @see #getQueryConfigHandler()
* @see QueryConfigHandler
*/
public void setQueryConfigHandler(QueryConfigHandler config) {
this.config = config;
QueryNodeProcessor processor = getQueryNodeProcessor();
if (processor != null) {
processor.setQueryConfigHandler(config);
}
}
/**
* Parses a query string to an object, usually some query object. <br/>
* <br/>
* In this method the three phases are executed: <br/>
* <br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1st - the query string is parsed using the
* text parser returned by {@link #getTextParser()}, the result is a query
* node tree <br/>
* <br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2nd - the query node tree is processed by the
* processor returned by {@link #getQueryNodeProcessor()} <br/>
* <br/>
* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3th - a object is built from the query node
* tree using the builder returned by {@link #getQueryBuilder()}
*
* @param query
* the query string
* @param defaultField
* the default field used by the text parser
*
* @return the object built from the query
*
* @throws QueryNodeException
* if something wrong happens along the three phases
*/
public Object parse(String query, String defaultField)
throws QueryNodeException {
QueryNode queryTree = getTextParser().parse(query, defaultField);
QueryNodeProcessor processor = getQueryNodeProcessor();
if (processor != null) {
queryTree = processor.process(queryTree);
}
return getQueryBuilder().build(queryTree);
}
}

View File

@ -0,0 +1,43 @@
package org.apache.lucene.queryParser.core.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* This interface is used by implementors classes that builds some kind of
* object from a query tree.
*
* @see QueryTreeBuilder
*/
public interface QueryBuilder {
/**
* Builds some kind of object from a query tree.
*
* @param queryNode
* the query tree root node
*
* @return some object generated from the query tree
*
* @throws QueryNodeException
*/
Object build(QueryNode queryNode) throws QueryNodeException;
}

View File

@ -0,0 +1,222 @@
package org.apache.lucene.queryParser.core.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.HashMap;
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.FieldableNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.original.parser.EscapeQuerySyntaxImpl;
/**
* This class should be used when there is a builder for each type of node.
*
* The type of node may be defined in 2 different ways: - by the field name,
* when the node implements the {@link FieldableNode} interface - by its class,
* it keeps checking the class and all the interfaces and classes this class
* implements/extends until it finds a builder for that class/interface
*
* This class always check if there is a builder for the field name before it
* checks for the node class. So, field name builders have precedence over class
* builders.
*
* When a builder is found for a node, it's called and the node is passed to the
* builder. If the returned built object is not <code>null</code>, it's tagged
* on the node using the tag {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID}.
*
* The children are usually built before the parent node. However, if a builder
* associated to a node is an instance of {@link QueryTreeBuilder}, the node is
* delegated to this builder and it's responsible to build the node and its
* children.
*
* @see QueryBuilder
*/
public class QueryTreeBuilder implements QueryBuilder {
/**
* This tag is used to tag the nodes in a query tree with the built objects
* produced from their own associated builder.
*/
public static final String QUERY_TREE_BUILDER_TAGID = QueryTreeBuilder.class
.getName();
private HashMap<Class<? extends QueryNode>, QueryBuilder> queryNodeBuilders;
private HashMap<CharSequence, QueryBuilder> fieldNameBuilders;
/**
* {@link QueryTreeBuilder} constructor.
*/
public QueryTreeBuilder() {
// empty constructor
}
/**
* Associates a field name with a builder.
*
* @param fieldName
* the field name
* @param builder
* the builder to be associated
*/
public void setBuilder(CharSequence fieldName, QueryBuilder builder) {
if (this.fieldNameBuilders == null) {
this.fieldNameBuilders = new HashMap<CharSequence, QueryBuilder>();
}
this.fieldNameBuilders.put(fieldName, builder);
}
/**
* Associates a class with a builder
*
* @param queryNodeClass
* the class
* @param builder
* the builder to be associated
*/
public void setBuilder(Class<? extends QueryNode> queryNodeClass,
QueryBuilder builder) {
if (this.queryNodeBuilders == null) {
this.queryNodeBuilders = new HashMap<Class<? extends QueryNode>, QueryBuilder>();
}
this.queryNodeBuilders.put(queryNodeClass, builder);
}
private void process(QueryNode node) throws QueryNodeException {
if (node != null) {
QueryBuilder builder = getBuilder(node);
if (!(builder instanceof QueryTreeBuilder)) {
List<QueryNode> children = node.getChildren();
if (children != null) {
for (QueryNode child : children) {
process(child);
}
}
}
processNode(node, builder);
}
}
private QueryBuilder getBuilder(QueryNode node) {
QueryBuilder builder = null;
if (this.fieldNameBuilders != null && node instanceof FieldableNode) {
builder = this.fieldNameBuilders.get(((FieldableNode) node).getField());
}
if (builder == null && this.queryNodeBuilders != null) {
Class<?> clazz = node.getClass();
do {
builder = getQueryBuilder(clazz);
if (builder == null) {
Class<?>[] classes = node.getClass().getInterfaces();
for (Class<?> actualClass : classes) {
builder = getQueryBuilder(actualClass);
if (builder != null) {
break;
}
}
}
} while (builder == null && (clazz = clazz.getSuperclass()) != null);
}
return builder;
}
private void processNode(QueryNode node, QueryBuilder builder)
throws QueryNodeException {
if (builder == null) {
throw new QueryNodeException(new MessageImpl(
QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, node
.toQueryString(new EscapeQuerySyntaxImpl()), node.getClass()
.getName()));
}
Object obj = builder.build(node);
if (obj != null) {
node.setTag(QUERY_TREE_BUILDER_TAGID, obj);
}
}
private QueryBuilder getQueryBuilder(Class<?> clazz) {
if (QueryNode.class.isAssignableFrom(clazz)) {
return this.queryNodeBuilders.get(clazz);
}
return null;
}
/**
* Builds some kind of object from a query tree. Each node in the query tree
* is built using an specific builder associated to it.
*
* @param queryNode
* the query tree root node
*
* @return the built object
*
* @throws QueryNodeException
* if some node builder throws a {@link QueryNodeException} or if
* there is a node which had no builder associated to it
*/
public Object build(QueryNode queryNode) throws QueryNodeException {
process(queryNode);
return queryNode.getTag(QUERY_TREE_BUILDER_TAGID);
}
}

View File

@ -0,0 +1,39 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Contains the necessary classes to implement query builders
<h2>Query Parser Builders</h2>
<p>
The package <tt>org.apache.lucene.queryParser.builders</tt> contains the interface that
builders must implement, it also contain a utility {@link org.apache.lucene.queryParser.core.builders.QueryTreeBuilder}, which walks the tree
and call the Builder for each node in the tree.
Builder normally convert QueryNode Object into a Lucene Query Object,
and normally it's a one-to-one mapping class.
But other builders implementations can by written to convert QueryNode objects to other non lucene objects.
</p>
<p>
</p>
</body>
</html>

View File

@ -0,0 +1,64 @@
package org.apache.lucene.queryParser.core.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.util.AttributeSource;
/**
* This class represents a field configuration. Every configuration should be
* set using the methods inherited from {@link AttributeSource}.
*
* @see QueryConfigHandler
* @see org.apache.lucene.util.Attribute
*/
public class FieldConfig extends AttributeSource {
private CharSequence fieldName;
/**
* Constructs a {@link FieldConfig}
*
* @param fieldName
* the field name, it cannot be null
* @throws IllegalArgumentException
* if the field name is null
*/
public FieldConfig(CharSequence fieldName) {
if (fieldName == null) {
throw new IllegalArgumentException("field name should not be null!");
}
this.fieldName = fieldName;
}
/**
* Returns the field name this configuration represents.
*
* @return the field name
*/
public CharSequence getFieldName() {
return this.fieldName;
}
public String toString(){
return "<fieldconfig name=\"" + this.fieldName + "\" attributes=\"" + super.toString() + "\"/>";
}
}

View File

@ -0,0 +1,21 @@
package org.apache.lucene.queryParser.core.config;
/**
* This interface should be implemented by classes that wants to listen for
* field configuration requests. The implementation receives a
* {@link FieldConfig} object and may add/change its attributes.
*
* @see FieldConfig
* @see QueryConfigHandler
*/
public interface FieldConfigListener {
/**
* This method is called ever time a field configuration is requested.
*
* @param fieldConfig
* the field configuration requested, should never be null
*/
void buildFieldConfig(FieldConfig fieldConfig);
}

View File

@ -0,0 +1,85 @@
package org.apache.lucene.queryParser.core.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.LinkedList;
import org.apache.lucene.queryParser.core.processors.QueryNodeProcessor;
import org.apache.lucene.util.Attribute;
import org.apache.lucene.util.AttributeSource;
/**
* This class can be used to hold any query configuration and no field
* configuration. For field configuration, it creates a empty
* {@link FieldConfig} object and delegate it to field config listeners,
* these are responsible for setting up all the field configuration.
*
* {@link QueryConfigHandler} should be extended by classes that intends to
* provide configuration to {@link QueryNodeProcessor} objects.
*
* This class extends {@link AttributeSource}, so {@link Attribute}s can be
* attached to it.
*
* The class that extends {@link QueryConfigHandler} should also provide
* {@link FieldConfig} objects for each collection field.
*
* @see Attribute
* @see FieldConfig
* @see FieldConfigListener
* @see QueryConfigHandler
*/
public abstract class QueryConfigHandler extends AttributeSource {
private LinkedList<FieldConfigListener> listeners = new LinkedList<FieldConfigListener>();;
/**
* Returns an implementation of
* {@link FieldConfig} for a specific field name. If the implemented
* {@link QueryConfigHandler} does not know a specific field name, it may
* return <code>null</code>, indicating there is no configuration for that
* field.
*
* @param fieldName
* the field name
* @return a {@link FieldConfig} object containing the field name
* configuration or <code>null</code>, if the implemented
* {@link QueryConfigHandler} has no configuration for that field
*/
public FieldConfig getFieldConfig(CharSequence fieldName) {
FieldConfig fieldConfig = new FieldConfig(fieldName);
for (FieldConfigListener listener : this.listeners) {
listener.buildFieldConfig(fieldConfig);
}
return fieldConfig;
}
/**
* Adds a listener. The added listeners are called in the order they are
* added.
*
* @param listener
* the listener to be added
*/
public void addFieldConfigListener(FieldConfigListener listener) {
this.listeners.add(listener);
}
}

View File

@ -0,0 +1,50 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Contains the base classes used to configure the query processing
<h2>Query Configuration Interfaces</h2>
<p>
The package <tt>org.apache.lucene.queryParser.config</tt> contains query configuration handler
abstract class that all config handlers should extend.
</p>
<p>
See {@link org.apache.lucene.queryParser.original.config.OriginalQueryConfigHandler} for a reference
implementation.
</p>
<p>
{@link org.apache.lucene.queryParser.core.config.FieldConfig} and {@link org.apache.lucene.queryParser.core.config.QueryConfigHandler}
should use {@link org.apache.lucene.util.Attribute} to store all attributes
required by the config implementation. See <tt>org.apache.lucene.queryParser.original.config.*Attribute</tt>
for reference implementation.
</p>
<p>
The {@link org.apache.lucene.queryParser.core.config.QueryConfigHandler}, {@link org.apache.lucene.queryParser.core.config.FieldConfig},
and {@link org.apache.lucene.util.Attribute}s are used in the processors to access config
information in a flexible and independent way.
See {@link org.apache.lucene.queryParser.original.processors.ParametricRangeQueryNodeProcessor} for a
reference implementation.
</p>
</body>
</html

View File

@ -0,0 +1,54 @@
package org.apache.lucene.queryParser.core.messages;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.NLS;
/**
* Flexible Query Parser message bundle class
*/
public class QueryParserMessages extends NLS {
private static final String BUNDLE_NAME = QueryParserMessages.class.getName();
private QueryParserMessages() {
// Do not instantiate
}
static {
// register all string ids with NLS class and initialize static string
// values
NLS.initializeMessages(BUNDLE_NAME, QueryParserMessages.class);
}
// static string must match the strings in the property files.
public static String INVALID_SYNTAX;
public static String INVALID_SYNTAX_CANNOT_PARSE;
public static String INVALID_SYNTAX_FUZZY_LIMITS;
public static String INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION;
public static String INVALID_SYNTAX_ESCAPE_CHARACTER;
public static String INVALID_SYNTAX_ESCAPE_NONE_HEX_UNICODE;
public static String NODE_ACTION_NOT_SUPPORTED;
public static String PARAMETER_VALUE_NOT_SUPPORTED;
public static String LUCENE_QUERY_CONVERSION_ERROR;
public static String EMPTY_MESSAGE;
public static String WILDCARD_NOT_SUPPORTED;
public static String TOO_MANY_BOOLEAN_CLAUSES;
public static String LEADING_WILDCARD_NOT_ALLOWED;
}

View File

@ -0,0 +1,45 @@
# This resource bundle contains Flexible Query Parser messages.
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
# <REPLACEMENT arg="{0}" value="detailed_message"/>
INVALID_SYNTAX = Syntax Error: {0}
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
# <REPLACEMENT arg="{0}" value="invalid_query"/>
# <REPLACEMENT arg="{1}" value="detailed_message"/>
INVALID_SYNTAX_CANNOT_PARSE = Syntax Error, cannot parse {0}: {1}
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
INVALID_SYNTAX_FUZZY_LIMITS = The similarity value for a fuzzy search must be between 0.0 and 1.0.
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
INVALID_SYNTAX_ESCAPE_UNICODE_TRUNCATION = Truncated unicode escape sequence.
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
INVALID_SYNTAX_ESCAPE_CHARACTER = Term can not end with escape character.
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
INVALID_SYNTAX_ESCAPE_NONE_HEX_UNICODE = None-hex character in unicode escape sequence: {0}
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
NODE_ACTION_NOT_SUPPORTED = This node does not support this action.
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
PARAMETER_VALUE_NOT_SUPPORTED = Parameter {1} with value {0} not supported.
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
# <REPLACEMENT arg="{0}" value="query"/>
# <REPLACEMENT arg="{1}" value="error/class"/>
LUCENE_QUERY_CONVERSION_ERROR = Cannot convert query to lucene syntax: {0} error: {1}
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
EMPTY_MESSAGE =
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
WILDCARD_NOT_SUPPORTED = Wildcard is not supported for query: {0}
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
TOO_MANY_BOOLEAN_CLAUSES = Too many boolean clauses, the maximum supported is {0}: {1}
#<CREATEDBY>Apache Lucene Community</CREATEDBY>
LEADING_WILDCARD_NOT_ALLOWED = Leading wildcard is not allowed: {0}

View File

@ -0,0 +1,31 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Contains messages usually used by query parser implementations
<h2>Query Parser Messages</h2>
Messages for the Flexible Query Parser, they use <tt>org.apache.lucene.messages.NLS</tt> API.
</body>
</html>

View File

@ -0,0 +1,77 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link AndQueryNode} represents an AND boolean operation performed on a
* list of nodes.
*/
public class AndQueryNode extends BooleanQueryNode {
private static final long serialVersionUID = 118496077529151825L;
/**
* @param clauses
* - the query nodes to be and'ed
*/
public AndQueryNode(List<QueryNode> clauses) {
super(clauses);
if ((clauses == null) || (clauses.size() == 0)) {
throw new IllegalArgumentException(
"AND query must have at least one clause");
}
}
public String toString() {
if (getChildren() == null || getChildren().size() == 0)
return "<boolean operation='and'/>";
StringBuilder sb = new StringBuilder();
sb.append("<boolean operation='and'>");
for (QueryNode child : getChildren()) {
sb.append("\n");
sb.append(child.toString());
}
sb.append("\n</boolean>");
return sb.toString();
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChildren() == null || getChildren().size() == 0)
return "";
StringBuilder sb = new StringBuilder();
String filler = "";
for (QueryNode child : getChildren()) {
sb.append(filler).append(child.toQueryString(escapeSyntaxParser));
filler = " AND ";
}
// in case is root or the parent is a group node avoid parenthesis
if ((getParent() != null && getParent() instanceof GroupQueryNode)
|| isRoot())
return sb.toString();
else
return "( " + sb.toString() + " )";
}
}

View File

@ -0,0 +1,143 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link AnyQueryNode} represents an ANY operator performed on a list of
* nodes.
*/
public class AnyQueryNode extends AndQueryNode {
private static final long serialVersionUID = 1000791433562954187L;
private CharSequence field = null;
private int minimumMatchingmElements = 0;
/**
* @param clauses
* - the query nodes to be or'ed
*/
public AnyQueryNode(List<QueryNode> clauses, CharSequence field,
int minimumMatchingElements) {
super(clauses);
this.field = field;
this.minimumMatchingmElements = minimumMatchingElements;
if (clauses != null) {
for (QueryNode clause : clauses) {
if (clause instanceof FieldQueryNode) {
if (clause instanceof QueryNodeImpl) {
((QueryNodeImpl) clause).toQueryStringIgnoreFields = true;
}
if (clause instanceof FieldableNode) {
((FieldableNode) clause).setField(field);
}
}
}
}
}
public int getMinimumMatchingElements() {
return this.minimumMatchingmElements;
}
/**
* returns null if the field was not specified
*
* @return the field
*/
public CharSequence getField() {
return this.field;
}
/**
* returns - null if the field was not specified
*
* @return the field as a String
*/
public String getFieldAsString() {
if (this.field == null)
return null;
else
return this.field.toString();
}
/**
* @param field
* - the field to set
*/
public void setField(CharSequence field) {
this.field = field;
}
public QueryNode cloneTree() throws CloneNotSupportedException {
AnyQueryNode clone = (AnyQueryNode) super.cloneTree();
clone.field = this.field;
clone.minimumMatchingmElements = this.minimumMatchingmElements;
return clone;
}
public String toString() {
if (getChildren() == null || getChildren().size() == 0)
return "<any field='" + this.field + "' matchelements="
+ this.minimumMatchingmElements + "/>";
StringBuilder sb = new StringBuilder();
sb.append("<any field='" + this.field + "' matchelements="
+ this.minimumMatchingmElements + ">");
for (QueryNode clause : getChildren()) {
sb.append("\n");
sb.append(clause.toString());
}
sb.append("\n</any>");
return sb.toString();
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
String anySTR = "ANY " + this.minimumMatchingmElements;
StringBuilder sb = new StringBuilder();
if (getChildren() == null || getChildren().size() == 0) {
// no childs case
} else {
String filler = "";
for (QueryNode clause : getChildren()) {
sb.append(filler).append(clause.toQueryString(escapeSyntaxParser));
filler = " ";
}
}
if (isDefaultField(this.field)) {
return "( " + sb.toString() + " ) " + anySTR;
} else {
return this.field + ":(( " + sb.toString() + " ) " + anySTR + ")";
}
}
}

View File

@ -0,0 +1,83 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link BooleanQueryNode} represents a list of elements which do not have an
* explicit boolean operator defined between them. It can be used to express a
* boolean query that intends to use the default boolean operator.
*/
public class BooleanQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -2206623652088638072L;
/**
* @param clauses
* - the query nodes to be and'ed
*/
public BooleanQueryNode(List<QueryNode> clauses) {
setLeaf(false);
allocate();
set(clauses);
}
public String toString() {
if (getChildren() == null || getChildren().size() == 0)
return "<boolean operation='default'/>";
StringBuilder sb = new StringBuilder();
sb.append("<boolean operation='default'>");
for (QueryNode child : getChildren()) {
sb.append("\n");
sb.append(child.toString());
}
sb.append("\n</boolean>");
return sb.toString();
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChildren() == null || getChildren().size() == 0)
return "";
StringBuilder sb = new StringBuilder();
String filler = "";
for (QueryNode child : getChildren()) {
sb.append(filler).append(child.toQueryString(escapeSyntaxParser));
filler = " ";
}
// in case is root or the parent is a group node avoid parenthesis
if ((getParent() != null && getParent() instanceof GroupQueryNode)
|| isRoot())
return sb.toString();
else
return "( " + sb.toString() + " )";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
BooleanQueryNode clone = (BooleanQueryNode) super.cloneTree();
// nothing to do here
return clone;
}
}

View File

@ -0,0 +1,122 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link BoostQueryNode} boosts the QueryNode tree which is under this node.
* So, it must only and always have one child.
*
* The boost value may vary from 0.0 to 1.0.
*
*/
public class BoostQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -3929082630855807593L;
private float value = 0;
/**
* Constructs a boost node
*
* @param query
* the query to be boosted
* @param value
* the boost value, it may vary from 0.0 to 1.0
*
* @throws QueryNodeException
*/
public BoostQueryNode(QueryNode query, float value) throws QueryNodeException {
if (query == null) {
throw new QueryNodeError(new MessageImpl(
QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
}
this.value = value;
setLeaf(false);
allocate();
add(query);
}
/**
* Returns the single child which this node boosts.
*
* @return the single child which this node boosts
*/
public QueryNode getChild() {
List<QueryNode> children = getChildren();
if (children == null || children.size() == 0) {
return null;
}
return children.get(0);
}
/**
* Returns the boost value. It may vary from 0.0 to 1.0.
*
* @return the boost value
*/
public float getValue() {
return this.value;
}
/**
* Returns the boost value parsed to a string.
*
* @return the parsed value
*/
private CharSequence getValueString() {
Float f = new Float(this.value);
if (f == f.longValue())
return "" + f.longValue();
else
return "" + f;
}
public String toString() {
return "<boost value='" + getValueString() + "'>" + "\n"
+ getChild().toString() + "\n</boost>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChild() == null)
return "";
return getChild().toQueryString(escapeSyntaxParser) + "^"
+ getValueString();
}
public QueryNode cloneTree() throws CloneNotSupportedException {
BoostQueryNode clone = (BoostQueryNode) super.cloneTree();
clone.value = this.value;
return clone;
}
}

View File

@ -0,0 +1,51 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
import org.apache.lucene.queryParser.core.processors.RemoveDeletedQueryNodesProcessor;
/**
* A {@link DeletedQueryNode} represents a node that was deleted from the query
* node tree. It can be removed from the tree using the
* {@link RemoveDeletedQueryNodesProcessor} processor.
*/
public class DeletedQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -9151675506000425293L;
public DeletedQueryNode() {
// empty constructor
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
return "[DELETEDCHILD]";
}
public String toString() {
return "<deleted/>";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
DeletedQueryNode clone = (DeletedQueryNode) super.cloneTree();
return clone;
}
}

View File

@ -0,0 +1,184 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Locale;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax.Type;
/**
* A {@link FieldQueryNode} represents a element that contains field/text tuple
*/
public class FieldQueryNode extends QueryNodeImpl implements TextableQueryNode,
FieldableNode {
private static final long serialVersionUID = 3634521145130758265L;
/**
* The term's field
*/
protected CharSequence field;
/**
* The term's text.
*/
protected CharSequence text;
/**
* The term's begin position.
*/
protected int begin;
/**
* The term's end position.
*/
protected int end;
/**
* The term's position increment.
*/
protected int positionIncrement;
/**
* @param field
* - field name
* @param text
* - value
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public FieldQueryNode(CharSequence field, CharSequence text, int begin,
int end) {
this.field = field;
this.text = text;
this.begin = begin;
this.end = end;
this.setLeaf(true);
}
CharSequence getTermEscaped(EscapeQuerySyntax escaper) {
return escaper.escape(this.text, Locale.getDefault(), Type.NORMAL);
}
CharSequence getTermEscapeQuoted(EscapeQuerySyntax escaper) {
return escaper.escape(this.text, Locale.getDefault(), Type.STRING);
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
if (isDefaultField(this.field)) {
return getTermEscaped(escaper);
} else {
return this.field + ":" + getTermEscaped(escaper);
}
}
public String toString() {
return "<field start='" + this.begin + "' end='" + this.end + "' field='"
+ this.field + "' text='" + this.text + "'/>";
}
/**
* @return the term
*/
public String getTextAsString() {
if (this.text == null)
return null;
else
return this.text.toString();
}
/**
* returns null if the field was not specified in the query string
*
* @return the field
*/
public String getFieldAsString() {
if (this.field == null)
return null;
else
return this.field.toString();
}
public int getBegin() {
return this.begin;
}
public void setBegin(int begin) {
this.begin = begin;
}
public int getEnd() {
return this.end;
}
public void setEnd(int end) {
this.end = end;
}
public CharSequence getField() {
return this.field;
}
public void setField(CharSequence field) {
this.field = field;
}
public int getPositionIncrement() {
return this.positionIncrement;
}
public void setPositionIncrement(int pi) {
this.positionIncrement = pi;
}
/**
* Returns the term.
*
* @return The "original" form of the term.
*/
public CharSequence getText() {
return this.text;
}
/**
* @param text
* the text to set
*/
public void setText(CharSequence text) {
this.text = text;
}
@Override
public FieldQueryNode cloneTree() throws CloneNotSupportedException {
FieldQueryNode fqn = (FieldQueryNode) super.cloneTree();
fqn.begin = this.begin;
fqn.end = this.end;
fqn.field = this.field;
fqn.text = this.text;
fqn.positionIncrement = this.positionIncrement;
fqn.toQueryStringIgnoreFields = this.toQueryStringIgnoreFields;
return fqn;
}
}

View File

@ -0,0 +1,45 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A query node implements {@link FieldableNode} interface to indicate that its
* children and itself are associated to a specific field.
*
* If it has any children which also implements this interface, it must ensure
* the children are associated to the same field.
*
*/
public interface FieldableNode extends QueryNode {
/**
* Returns the field associated to the node and every node under it.
*
* @return the field name
*/
CharSequence getField();
/**
* Associates the node to a field.
*
* @param fieldName
* the field name
*/
void setField(CharSequence fieldName);
}

View File

@ -0,0 +1,98 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link FuzzyQueryNode} represents a element that contains
* field/text/similarity tuple
*/
public class FuzzyQueryNode extends FieldQueryNode {
private static final long serialVersionUID = -1794537213032589441L;
private float similarity;
private int prefixLength;
/**
* @param field
* Name of the field query will use.
* @param termStr
* Term token to use for building term for the query
*/
/**
* @param field
* - Field name
* @param term
* - Value
* @param minSimilarity
* - similarity value
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public FuzzyQueryNode(CharSequence field, CharSequence term,
float minSimilarity, int begin, int end) {
super(field, term, begin, end);
this.similarity = minSimilarity;
setLeaf(true);
}
public void setPrefixLength(int prefixLength) {
this.prefixLength = prefixLength;
}
public int getPrefixLength() {
return this.prefixLength;
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
if (isDefaultField(this.field)) {
return getTermEscaped(escaper) + "~" + this.similarity;
} else {
return this.field + ":" + getTermEscaped(escaper) + "~" + this.similarity;
}
}
public String toString() {
return "<fuzzy field='" + this.field + "' similarity='" + this.similarity
+ "' term='" + this.text + "'/>";
}
public void setSimilarity(float similarity) {
this.similarity = similarity;
}
public FuzzyQueryNode cloneTree() throws CloneNotSupportedException {
FuzzyQueryNode clone = (FuzzyQueryNode) super.cloneTree();
clone.similarity = this.similarity;
return clone;
}
/**
* @return the similarity
*/
public float getSimilarity() {
return this.similarity;
}
}

View File

@ -0,0 +1,83 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link GroupQueryNode} represents a location where the original user typed
* real parenthesis on the query string. This class is useful for queries like:
* a) a AND b OR c b) ( a AND b) OR c
*
* Parenthesis might be used to define the boolean operation precedence.
*/
public class GroupQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -9204673493869114999L;
/**
* This QueryNode is used to identify parenthesis on the original query string
*/
public GroupQueryNode(QueryNode query) {
if (query == null) {
throw new QueryNodeError(new MessageImpl(
QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
}
allocate();
setLeaf(false);
add(query);
}
public QueryNode getChild() {
return getChildren().get(0);
}
public String toString() {
return "<group>" + "\n" + getChild().toString() + "\n</group>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChild() == null)
return "";
return "( " + getChild().toQueryString(escapeSyntaxParser) + " )";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
GroupQueryNode clone = (GroupQueryNode) super.cloneTree();
return clone;
}
/**
* @param child
*/
public void setChild(QueryNode child) {
List<QueryNode> list = new ArrayList<QueryNode>();
list.add(child);
this.set(list);
}
}

View File

@ -0,0 +1,49 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link MatchAllDocsQueryNode} indicates that a query node tree or subtree
* will match all documents if executed in the index.
*/
public class MatchAllDocsQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -7050381275423477809L;
public MatchAllDocsQueryNode() {
// empty constructor
}
public String toString() {
return "<matchAllDocs field='*' term='*'>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
return "*:*";
}
public MatchAllDocsQueryNode cloneTree() throws CloneNotSupportedException {
MatchAllDocsQueryNode clone = (MatchAllDocsQueryNode) super.cloneTree();
// nothing to clone
return clone;
}
}

View File

@ -0,0 +1,37 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A {@link MatchNoDocsQueryNode} indicates that a query node tree or subtree
* will not match any documents if executed in the index.
*
*/
public class MatchNoDocsQueryNode extends DeletedQueryNode {
private static final long serialVersionUID = 8081805751679581497L;
public MatchNoDocsQueryNode() {
// empty constructor
}
public String toString() {
return "<matchNoDocsQueryNode/>";
}
}

View File

@ -0,0 +1,156 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link ModifierQueryNode} indicates the modifier value (+,-,?,NONE) for
* each term on the query string for example "+t1 -t2 t3" will have a tree of
* <BooleanQueryNode> <ModifierQueryNode modifier="MOD_REQ"> <t1/>
* </ModifierQueryNode> <ModifierQueryNode modifier="MOD_NOT"> <t2/>
* </ModifierQueryNode> <t3/> </BooleanQueryNode>
*
*/
public class ModifierQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -391209837953928169L;
public enum Modifier {
MOD_NONE, MOD_NOT, MOD_REQ;
public String toString() {
switch (this) {
case MOD_NONE:
return "MOD_NONE";
case MOD_NOT:
return "MOD_NOT";
case MOD_REQ:
return "MOD_REQ";
}
// this code is never executed
return "MOD_DEFAULT";
}
public String toDigitString() {
switch (this) {
case MOD_NONE:
return "";
case MOD_NOT:
return "-";
case MOD_REQ:
return "+";
}
// this code is never executed
return "";
}
public String toLargeString() {
switch (this) {
case MOD_NONE:
return "";
case MOD_NOT:
return "NOT ";
case MOD_REQ:
return "+";
}
// this code is never executed
return "";
}
}
private Modifier modifier = Modifier.MOD_NONE;
/**
* Used to store the modifier value on the original query string
*
* @param query
* - QueryNode subtree
* @param mod
* - Modifier Value
*/
public ModifierQueryNode(QueryNode query, Modifier mod) {
if (query == null) {
throw new QueryNodeError(new MessageImpl(
QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "query", "null"));
}
allocate();
setLeaf(false);
add(query);
this.modifier = mod;
}
public QueryNode getChild() {
return getChildren().get(0);
}
public Modifier getModifier() {
return this.modifier;
}
public String toString() {
return "<modifier operation='" + this.modifier.toString() + "'>" + "\n"
+ getChild().toString() + "\n</modifier>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChild() == null)
return "";
String leftParenthensis = "";
String rightParenthensis = "";
if (getChild() != null && getChild() instanceof ModifierQueryNode) {
leftParenthensis = "(";
rightParenthensis = ")";
}
if (getChild() instanceof BooleanQueryNode) {
return this.modifier.toLargeString() + leftParenthensis
+ getChild().toQueryString(escapeSyntaxParser) + rightParenthensis;
} else {
return this.modifier.toDigitString() + leftParenthensis
+ getChild().toQueryString(escapeSyntaxParser) + rightParenthensis;
}
}
public QueryNode cloneTree() throws CloneNotSupportedException {
ModifierQueryNode clone = (ModifierQueryNode) super.cloneTree();
clone.modifier = this.modifier;
return clone;
}
/**
* @param child
*/
public void setChild(QueryNode child) {
List<QueryNode> list = new ArrayList<QueryNode>();
list.add(child);
this.set(list);
}
}

View File

@ -0,0 +1,49 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link NoTokenFoundQueryNode} is used if a term is convert into no tokens
* by the tokenizer/lemmatizer/analyzer (null).
*/
public class NoTokenFoundQueryNode extends DeletedQueryNode {
private static final long serialVersionUID = 7332975497586993833L;
public NoTokenFoundQueryNode() {
super();
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
return "[NTF]";
}
public String toString() {
return "<notokenfound/>";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
NoTokenFoundQueryNode clone = (NoTokenFoundQueryNode) super.cloneTree();
// nothing to do here
return clone;
}
}

View File

@ -0,0 +1,80 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link OpaqueQueryNode} is used for specify values that are not supposed to
* be parsed by the parser. For example: and XPATH query in the middle of a
* query string a b @xpath:'/bookstore/book[1]/title' c d
*/
public class OpaqueQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = 0L;
private CharSequence schema = null;
private CharSequence value = null;
/**
* @param schema
* - schema identifier
* @param value
* - value that was not parsed
*/
public OpaqueQueryNode(CharSequence schema, CharSequence value) {
this.setLeaf(true);
this.schema = schema;
this.value = value;
}
public String toString() {
return "<opaque schema='" + this.schema + "' value='" + this.value + "'/>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
return "@" + this.schema + ":'" + this.value + "'";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
OpaqueQueryNode clone = (OpaqueQueryNode) super.cloneTree();
clone.schema = this.schema;
clone.value = this.value;
return clone;
}
/**
* @return the schema
*/
public CharSequence getSchema() {
return this.schema;
}
/**
* @return the value
*/
public CharSequence getValue() {
return this.value;
}
}

View File

@ -0,0 +1,78 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Iterator;
import java.util.List;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link OrQueryNode} represents an OR boolean operation performed on a list
* of nodes.
*
*/
public class OrQueryNode extends BooleanQueryNode {
private static final long serialVersionUID = -3692323307688017852L;
/**
* @param clauses
* - the query nodes to be or'ed
*/
public OrQueryNode(List<QueryNode> clauses) {
super(clauses);
if ((clauses == null) || (clauses.size() == 0)) {
throw new IllegalArgumentException(
"OR query must have at least one clause");
}
}
public String toString() {
if (getChildren() == null || getChildren().size() == 0)
return "<boolean operation='or'/>";
StringBuilder sb = new StringBuilder();
sb.append("<boolean operation='or'>");
for (QueryNode child : getChildren()) {
sb.append("\n");
sb.append(child.toString());
}
sb.append("\n</boolean>");
return sb.toString();
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChildren() == null || getChildren().size() == 0)
return "";
StringBuilder sb = new StringBuilder();
String filler = "";
for (Iterator<QueryNode> it = getChildren().iterator(); it.hasNext();) {
sb.append(filler).append(it.next().toQueryString(escapeSyntaxParser));
filler = " OR ";
}
// in case is root or the parent is a group node avoid parenthesis
if ((getParent() != null && getParent() instanceof GroupQueryNode)
|| isRoot())
return sb.toString();
else
return "( " + sb.toString() + " )";
}
}

View File

@ -0,0 +1,100 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link ParametricQueryNode} represents LE, LT, GE, GT, EQ, NE query.
* Example: date >= "2009-10-10" OR price = 200
*/
public class ParametricQueryNode extends FieldQueryNode {
private static final long serialVersionUID = -5770038129741218116L;
private CompareOperator operator;
public enum CompareOperator {
LE, LT, GE, GT, EQ, NE;
public String toString() {
if (LE.equals(this)) {
return "<=";
} else if (LT.equals(this)) {
return "<";
} else if (GE.equals(this)) {
return ">=";
} else if (GT.equals(this)) {
return ">";
} else if (EQ.equals(this)) {
return "=";
} else if (NE.equals(this)) {
return "!=";
} else {
throw new IllegalArgumentException("Unknown operator");
}
}
}
/**
* @param field
* - field name
* @param comp
* - CompareOperator
* @param value
* - text value
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public ParametricQueryNode(CharSequence field, CompareOperator comp,
CharSequence value, int begin, int end) {
super(field, value, begin, end);
this.operator = comp;
setLeaf(true);
}
public CharSequence getOperand() {
return getText();
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
return this.field + "" + this.operator.toString() + "\"" + this.text + "\"";
}
public String toString() {
return "<parametric field='" + this.field + "' operator='"
+ this.operator.toString() + "' text='" + this.text + "'/>";
}
public ParametricQueryNode cloneTree() throws CloneNotSupportedException {
ParametricQueryNode clone = (ParametricQueryNode) super.cloneTree();
clone.operator = this.operator;
return clone;
}
/**
* @return the operator
*/
public CompareOperator getOperator() {
return this.operator;
}
}

View File

@ -0,0 +1,120 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.nodes.ParametricQueryNode.CompareOperator;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link ParametricRangeQueryNode} represents LE, LT, GE, GT, EQ, NE query.
* Example: date >= "2009-10-10" OR price = 200
*/
public class ParametricRangeQueryNode extends QueryNodeImpl implements
FieldableNode {
private static final long serialVersionUID = 7120958816535573935L;
public ParametricRangeQueryNode(ParametricQueryNode lowerBound,
ParametricQueryNode upperBound) {
if (upperBound.getOperator() != CompareOperator.LE
&& upperBound.getOperator() != CompareOperator.LT) {
throw new IllegalArgumentException("upper bound should have "
+ CompareOperator.LE + " or " + CompareOperator.LT);
}
if (lowerBound.getOperator() != CompareOperator.GE
&& lowerBound.getOperator() != CompareOperator.GT) {
throw new IllegalArgumentException("lower bound should have "
+ CompareOperator.GE + " or " + CompareOperator.GT);
}
if (upperBound.getField() != lowerBound.getField()
|| (upperBound.getField() != null && !upperBound.getField().equals(
lowerBound.getField()))) {
throw new IllegalArgumentException(
"lower and upper bounds should have the same field name!");
}
allocate();
setLeaf(false);
add(lowerBound);
add(upperBound);
}
public ParametricQueryNode getUpperBound() {
return (ParametricQueryNode) getChildren().get(1);
}
public ParametricQueryNode getLowerBound() {
return (ParametricQueryNode) getChildren().get(0);
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
return getLowerBound().toQueryString(escapeSyntaxParser) + " AND "
+ getUpperBound().toQueryString(escapeSyntaxParser);
}
public CharSequence getField() {
return getLowerBound().getField();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("<parametricRange>\n\t");
sb.append(getUpperBound()).append("\n\t");
sb.append(getLowerBound()).append("\n");
sb.append("</parametricRange>\n");
return sb.toString();
}
public ParametricRangeQueryNode cloneTree() throws CloneNotSupportedException {
ParametricRangeQueryNode clone = (ParametricRangeQueryNode) super
.cloneTree();
// nothing to do here
return clone;
}
public void setField(CharSequence fieldName) {
List<QueryNode> children = getChildren();
if (children != null) {
for (QueryNode child : getChildren()) {
if (child instanceof FieldableNode) {
((FieldableNode) child).setField(fieldName);
}
}
}
}
}

View File

@ -0,0 +1,214 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax.Type;
/**
* A {@link PathQueryNode} is used for to store queries like
* /company/USA/California /product/shoes/brown QueryText are objects that
* contain the text, begin position and end position in the query.
*
* Example how the text parser creates these objects:
*
* List values = ArrayList(); values.add(new PathQueryNode.QueryText("company",
* 1, 7)); values.add(new PathQueryNode.QueryText("USA", 9, 12)); values.add(new
* PathQueryNode.QueryText("California", 14, 23)); QueryNode q = new
* PathQueryNode(values);
*
*/
public class PathQueryNode extends QueryNodeImpl {
private static final long serialVersionUID = -8325921322405804789L;
public static class QueryText implements Cloneable {
CharSequence value = null;
/**
* != null The term's begin position.
*/
int begin;
/**
* The term's end position.
*/
int end;
/**
* @param value
* - text value
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public QueryText(CharSequence value, int begin, int end) {
super();
this.value = value;
this.begin = begin;
this.end = end;
}
public QueryText clone() throws CloneNotSupportedException {
QueryText clone = (QueryText) super.clone();
clone.value = this.value;
clone.begin = this.begin;
clone.end = this.end;
return clone;
}
/**
* @return the value
*/
public CharSequence getValue() {
return value;
}
/**
* @return the begin
*/
public int getBegin() {
return begin;
}
/**
* @return the end
*/
public int getEnd() {
return end;
}
public String toString() {
return value + ", " + begin + ", " + end;
}
}
private List<QueryText> values = null;
/**
* @param pathElements
* - List of QueryText objects
*/
public PathQueryNode(List<QueryText> pathElements) {
this.values = pathElements;
if (pathElements.size() <= 1) {
// this should not happen
throw new RuntimeException(
"PathQuerynode requires more 2 or more path elements.");
}
}
/**
* Returns the a List with all QueryText elements
*
* @return QueryText List size
*/
public List<QueryText> getPathElements() {
return values;
}
/**
* Returns the a List with all QueryText elements
*/
public void setPathElements(List<QueryText> elements) {
this.values = elements;
}
/**
* Returns the a specific QueryText element
*
* @return QueryText List size
*/
public QueryText getPathElement(int index) {
return values.get(index);
}
/**
* Returns the CharSequence value of a specific QueryText element
*
* @return the CharSequence for a specific QueryText element
*/
public CharSequence getFirstPathElement() {
return values.get(0).value;
}
/**
* Returns a List QueryText element from position startIndex
*
* @return a List QueryText element from position startIndex
*/
public List<QueryText> getPathElements(int startIndex) {
List<PathQueryNode.QueryText> rValues = new ArrayList<PathQueryNode.QueryText>();
for (int i = startIndex; i < this.values.size(); i++) {
try {
rValues.add(this.values.get(i).clone());
} catch (CloneNotSupportedException e) {
// this will not happen
}
}
return rValues;
}
private CharSequence getPathString() {
StringBuffer path = new StringBuffer();
for (QueryText pathelement : values) {
path.append("/").append(pathelement.value);
}
return path.toString();
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
StringBuffer path = new StringBuffer();
path.append("/").append(getFirstPathElement());
for (QueryText pathelement : getPathElements(1)) {
CharSequence value = escaper.escape(pathelement.value, Locale
.getDefault(), Type.STRING);
path.append("/\"").append(value).append("\"");
}
return path.toString();
}
public String toString() {
QueryText text = this.values.get(0);
return "<path start='" + text.begin + "' end='" + text.end + "' path='"
+ getPathString() + "'/>";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
PathQueryNode clone = (PathQueryNode) super.cloneTree();
// copy children
if (this.values != null) {
List<QueryText> localValues = new ArrayList<QueryText>();
for (QueryText value : this.values) {
localValues.add(value.clone());
}
clone.values = localValues;
}
return clone;
}
}

View File

@ -0,0 +1,109 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.QueryNodeParseException;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
public class PhraseSlopQueryNode extends QueryNodeImpl implements FieldableNode {
private static final long serialVersionUID = 0L;
private int value = 0;
/**
* @throws QueryNodeException
* @throws QueryNodeParseException
* @exception QueryNodeParseException
* throw in overridden method to disallow
*/
public PhraseSlopQueryNode(QueryNode query, int value)
throws QueryNodeException {
if (query == null) {
throw new QueryNodeError(new MessageImpl(
QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
}
this.value = value;
setLeaf(false);
allocate();
add(query);
}
public QueryNode getChild() {
return getChildren().get(0);
}
public int getValue() {
return this.value;
}
private CharSequence getValueString() {
Float f = new Float(this.value);
if (f == f.longValue())
return "" + f.longValue();
else
return "" + f;
}
public String toString() {
return "<phraseslop value='" + getValueString() + "'>" + "\n"
+ getChild().toString() + "\n</phraseslop>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChild() == null)
return "";
return getChild().toQueryString(escapeSyntaxParser) + "~"
+ getValueString();
}
public QueryNode cloneTree() throws CloneNotSupportedException {
PhraseSlopQueryNode clone = (PhraseSlopQueryNode) super.cloneTree();
clone.value = this.value;
return clone;
}
public CharSequence getField() {
QueryNode child = getChild();
if (child instanceof FieldableNode) {
return ((FieldableNode) child).getField();
}
return null;
}
public void setField(CharSequence fieldName) {
QueryNode child = getChild();
if (child instanceof FieldableNode) {
((FieldableNode) child).setField(fieldName);
}
}
}

View File

@ -0,0 +1,57 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A {@link PrefixWildcardQueryNode} represents wildcardquery that matches abc*
* or *. This does not apply to phrases, this is a special case on the original
* lucene parser. TODO: refactor the code to remove this special case from the
* parser. and probably do it on a Processor
*/
public class PrefixWildcardQueryNode extends WildcardQueryNode {
private static final long serialVersionUID = 6851557641826407515L;
/**
* @param field
* - field name
* @param text
* - value including the wildcard
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public PrefixWildcardQueryNode(CharSequence field, CharSequence text,
int begin, int end) {
super(field, text, begin, end);
}
public String toString() {
return "<prefixWildcard field='" + this.field + "' term='" + this.text
+ "'/>";
}
public PrefixWildcardQueryNode cloneTree() throws CloneNotSupportedException {
PrefixWildcardQueryNode clone = (PrefixWildcardQueryNode) super.cloneTree();
// nothing to do here
return clone;
}
}

View File

@ -0,0 +1,251 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link ProximityQueryNode} represents a query where the terms should meet
* specific distance conditions. (a b c) WITHIN [SENTENCE|PARAGRAPH|NUMBER]
* [INORDER] ("a" "b" "c") WITHIN [SENTENCE|PARAGRAPH|NUMBER] [INORDER]
*
* TODO: Add this to the future original Lucene parser/processor/builder
*/
public class ProximityQueryNode extends BooleanQueryNode {
private static final long serialVersionUID = 9018220596680832916L;
public enum Type {
PARAGRAPH, SENTENCE, NUMBER;
CharSequence toQueryString() {
switch (this) {
case PARAGRAPH:
return "WITHIN PARAGRAPH";
case SENTENCE:
return "WITHIN SENTENCE";
case NUMBER:
return "WITHIN";
default:
return "WITHIN SENTENCE";
}
}
public String toString() {
switch (this) {
case PARAGRAPH:
return "PARAGRAPH";
case SENTENCE:
return "SENTENCE";
case NUMBER:
return "NUMBER";
default:
return "NUMBER";
}
}
}
// utility class
static public class ProximityType {
int pDistance = 0;
Type pType = null;
public ProximityType(Type type) {
this(type, 0);
}
public ProximityType(Type type, int distance) {
this.pType = type;
this.pDistance = distance;
}
}
private Type proximityType = Type.SENTENCE;
private int distance = -1;
private boolean inorder = false;
private CharSequence field = null;
/**
* @param clauses
* - QueryNode children
* @param field
* - field name
* @param type
* - type of proximity query
* @param distance
* - positive integer that specifies the distance
* @param inorder
* - true, if the tokens should be matched in the order of the
* clauses
*/
public ProximityQueryNode(List<QueryNode> clauses, CharSequence field,
Type type, int distance, boolean inorder) {
super(clauses);
setLeaf(false);
this.proximityType = type;
this.inorder = inorder;
this.field = field;
if (type == Type.NUMBER) {
if (distance <= 0) {
throw new QueryNodeError(new MessageImpl(
QueryParserMessages.PARAMETER_VALUE_NOT_SUPPORTED, "distance",
distance));
} else {
this.distance = distance;
}
}
clearFields(clauses, field);
}
/**
* @param clauses
* - QueryNode children
* @param field
* - field name
* @param type
* - type of proximity query
* @param inorder
* - true, if the tokens should be matched in the order of the
* clauses
*/
public ProximityQueryNode(List<QueryNode> clauses, CharSequence field,
Type type, boolean inorder) {
this(clauses, field, type, -1, inorder);
}
static private void clearFields(List<QueryNode> nodes, CharSequence field) {
if (nodes == null || nodes.size() == 0)
return;
for (QueryNode clause : nodes) {
if (clause instanceof FieldQueryNode) {
((FieldQueryNode) clause).toQueryStringIgnoreFields = true;
((FieldQueryNode) clause).setField(field);
}
}
}
public Type getProximityType() {
return this.proximityType;
}
public String toString() {
String distanceSTR = ((this.distance == -1) ? ("")
: (" distance='" + this.distance) + "'");
if (getChildren() == null || getChildren().size() == 0)
return "<proximity field='" + this.field + "' inorder='" + this.inorder
+ "' type='" + this.proximityType.toString() + "'" + distanceSTR
+ "/>";
StringBuilder sb = new StringBuilder();
sb.append("<proximity field='" + this.field + "' inorder='" + this.inorder
+ "' type='" + this.proximityType.toString() + "'" + distanceSTR + ">");
for (QueryNode child : getChildren()) {
sb.append("\n");
sb.append(child.toString());
}
sb.append("\n</proximity>");
return sb.toString();
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
String withinSTR = this.proximityType.toQueryString()
+ ((this.distance == -1) ? ("") : (" " + this.distance))
+ ((this.inorder) ? (" INORDER") : (""));
StringBuilder sb = new StringBuilder();
if (getChildren() == null || getChildren().size() == 0) {
// no children case
} else {
String filler = "";
for (QueryNode child : getChildren()) {
sb.append(filler).append(child.toQueryString(escapeSyntaxParser));
filler = " ";
}
}
if (isDefaultField(this.field)) {
return "( " + sb.toString() + " ) " + withinSTR;
} else {
return this.field + ":(( " + sb.toString() + " ) " + withinSTR + ")";
}
}
public QueryNode cloneTree() throws CloneNotSupportedException {
ProximityQueryNode clone = (ProximityQueryNode) super.cloneTree();
clone.proximityType = this.proximityType;
clone.distance = this.distance;
clone.field = this.field;
return clone;
}
/**
* @return the distance
*/
public int getDistance() {
return this.distance;
}
/**
* returns null if the field was not specified in the query string
*
* @return the field
*/
public CharSequence getField() {
return this.field;
}
/**
* returns null if the field was not specified in the query string
*
* @return the field
*/
public String getFieldAsString() {
if (this.field == null)
return null;
else
return this.field.toString();
}
/**
* @param field
* the field to set
*/
public void setField(CharSequence field) {
this.field = field;
}
/**
* @return terms must be matched in the specified order
*/
public boolean isInOrder() {
return this.inorder;
}
}

View File

@ -0,0 +1,95 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link QueryNode} is a interface implemented by all nodes on a QueryNode
* tree.
*/
public interface QueryNode extends Serializable {
/** convert to a query string understood by the query parser */
// TODO: this interface might be changed in the future
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser);
/** for printing */
public String toString();
/** get Children nodes */
public List<QueryNode> getChildren();
/** verify if a node is a Leaf node */
public boolean isLeaf();
/** verify if a node contains a tag */
public boolean containsTag(CharSequence tagName);
/**
* @param tagName
* @return of stored on under that tag name
*/
public Object getTag(CharSequence tagName);
public QueryNode getParent();
/**
* Recursive clone the QueryNode tree The tags are not copied to the new tree
* when you call the cloneTree() method
*
* @return the cloned tree
* @throws CloneNotSupportedException
*/
public QueryNode cloneTree() throws CloneNotSupportedException;
// Below are the methods that can change state of a QueryNode
// Write Operations (not Thread Safe)
// add a new child to a non Leaf node
public void add(QueryNode child);
public void add(List<QueryNode> children);
// reset the children of a node
public void set(List<QueryNode> children);
/**
* Associate the specified value with the specified tagName. If the tagName
* already exists, the old value is replaced. The tagName and value cannot be
* null. tagName will be converted to lowercase.
*
* @param tagName
* @param value
*/
public void setTag(CharSequence tagName, Object value);
/**
* Unset a tag. tagName will be converted to lowercase.
*
* @param tagName
*/
public void unsetTag(CharSequence tagName);
public Map<CharSequence, Object> getTags();
}

View File

@ -0,0 +1,225 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import org.apache.lucene.messages.NLS;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
/**
* A {@link QueryNodeImpl} is the default implementation of the interface
* {@link QueryNode}
*/
public abstract class QueryNodeImpl implements QueryNode, Cloneable {
private static final long serialVersionUID = 5569870883474845989L;
/* index default field */
// TODO remove PLAINTEXT_FIELD_NAME replacing it with configuration APIs
public static final String PLAINTEXT_FIELD_NAME = "_plain";
private boolean isLeaf = true;
private Hashtable<CharSequence, Object> tags = new Hashtable<CharSequence, Object>();
private List<QueryNode> clauses = null;
protected void allocate() {
if (this.clauses == null) {
this.clauses = new ArrayList<QueryNode>();
} else {
this.clauses.clear();
}
}
public final void add(QueryNode child) {
if (isLeaf() || this.clauses == null || child == null) {
throw new IllegalArgumentException(NLS
.getLocalizedMessage(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED));
}
this.clauses.add(child);
((QueryNodeImpl) child).setParent(this);
}
public final void add(List<QueryNode> children) {
if (isLeaf() || this.clauses == null) {
throw new IllegalArgumentException(NLS
.getLocalizedMessage(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED));
}
for (QueryNode child : getChildren()) {
add(child);
}
}
public boolean isLeaf() {
return this.isLeaf;
}
public final void set(List<QueryNode> children) {
if (isLeaf() || this.clauses == null) {
ResourceBundle bundle = ResourceBundle
.getBundle("org.apache.lucene.queryParser.messages.QueryParserMessages");
String message = bundle.getObject("Q0008E.NODE_ACTION_NOT_SUPPORTED")
.toString();
throw new IllegalArgumentException(message);
}
// reset parent value
for (QueryNode child : children) {
((QueryNodeImpl) child).setParent(null);
}
// allocate new children list
allocate();
// add new childs and set parent
for (QueryNode child : children) {
add(child);
}
}
public QueryNode cloneTree() throws CloneNotSupportedException {
QueryNodeImpl clone = (QueryNodeImpl) super.clone();
clone.isLeaf = this.isLeaf;
// Reset all tags
clone.tags = new Hashtable<CharSequence, Object>();
// copy children
if (this.clauses != null) {
List<QueryNode> localClauses = new ArrayList<QueryNode>();
for (QueryNode clause : this.clauses) {
localClauses.add(clause.cloneTree());
}
clone.clauses = localClauses;
}
return clone;
}
public Object clone() throws CloneNotSupportedException {
return cloneTree();
}
protected void setLeaf(boolean isLeaf) {
this.isLeaf = isLeaf;
}
/**
* @return a List for QueryNode object. Returns null, for nodes that do not
* contain children. All leaf Nodes return null.
*/
public final List<QueryNode> getChildren() {
if (isLeaf() || this.clauses == null) {
return null;
}
return this.clauses;
}
public void setTag(CharSequence tagName, Object value) {
this.tags.put(tagName.toString().toLowerCase(), value);
}
public void unsetTag(CharSequence tagName) {
this.tags.remove(tagName.toString().toLowerCase());
}
public boolean containsTag(CharSequence tagName) {
return this.tags.containsKey(tagName.toString().toLowerCase());
}
public Object getTag(CharSequence tagName) {
return this.tags.get(tagName.toString().toLowerCase());
}
private QueryNode parent = null;
private void setParent(QueryNode parent) {
this.parent = parent;
}
public QueryNode getParent() {
return this.parent;
}
protected boolean isRoot() {
return getParent() == null;
}
/**
* If set to true the the method toQueryString will not write field names
*/
protected boolean toQueryStringIgnoreFields = false;
/**
* This method is use toQueryString to detect if fld is the default field
*
* @param fld
* - field name
* @return true if fld is the default field
*/
protected boolean isDefaultField(CharSequence fld) {
if (this.toQueryStringIgnoreFields)
return true;
if (fld == null)
return true;
if (QueryNodeImpl.PLAINTEXT_FIELD_NAME.equals(fld.toString()))
return true;
return false;
}
/**
* Every implementation of this class should return pseudo xml like this:
*
* For FieldQueryNode: <field start='1' end='2' field='subject' text='foo'/>
*
* @see org.apache.lucene.queryParser.core.nodes.QueryNode#toString()
*/
public String toString() {
return super.toString();
}
/**
* @see org.apache.lucene.queryParser.core.nodes.QueryNode#getTag(CharSequence)
* @return a Map with all tags for this QueryNode
*/
@SuppressWarnings( { "unchecked" })
public Map<CharSequence, Object> getTags() {
return (Map<CharSequence, Object>) this.tags.clone();
}
} // end class QueryNodeImpl

View File

@ -0,0 +1,64 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link QuotedFieldQueryNode} represents phrase query. Example:
* "life is great"
*/
public class QuotedFieldQueryNode extends FieldQueryNode {
private static final long serialVersionUID = -6675157780051428987L;
/**
* @param field
* - field name
* @param text
* - value
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public QuotedFieldQueryNode(CharSequence field, CharSequence text, int begin,
int end) {
super(field, text, begin, end);
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
if (isDefaultField(this.field)) {
return "\"" + getTermEscapeQuoted(escaper) + "\"";
} else {
return this.field + ":" + "\"" + getTermEscapeQuoted(escaper) + "\"";
}
}
public String toString() {
return "<quotedfield start='" + this.begin + "' end='" + this.end
+ "' field='" + this.field + "' term='" + this.text + "'/>";
}
public QuotedFieldQueryNode cloneTree() throws CloneNotSupportedException {
QuotedFieldQueryNode clone = (QuotedFieldQueryNode) super.cloneTree();
// nothing to do here
return clone;
}
}

View File

@ -0,0 +1,116 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link SlopQueryNode} represents phrase query with a slop.
*
* From Lucene FAQ: Is there a way to use a proximity operator (like near or
* within) with Lucene? There is a variable called slop that allows you to
* perform NEAR/WITHIN-like queries. By default, slop is set to 0 so that only
* exact phrases will match. When using TextParser you can use this syntax to
* specify the slop: "doug cutting"~2 will find documents that contain
* "doug cutting" as well as ones that contain "cutting doug".
*/
public class SlopQueryNode extends QueryNodeImpl implements FieldableNode {
private static final long serialVersionUID = 0L;
private int value = 0;
/**
* @param query
* - QueryNode Tree with the phrase
* @param value
* - slop value
*/
public SlopQueryNode(QueryNode query, int value) {
if (query == null) {
throw new QueryNodeError(new MessageImpl(
QueryParserMessages.NODE_ACTION_NOT_SUPPORTED, "query", "null"));
}
this.value = value;
setLeaf(false);
allocate();
add(query);
}
public QueryNode getChild() {
return getChildren().get(0);
}
public int getValue() {
return this.value;
}
private CharSequence getValueString() {
Float f = new Float(this.value);
if (f == f.longValue())
return "" + f.longValue();
else
return "" + f;
}
public String toString() {
return "<slop value='" + getValueString() + "'>" + "\n"
+ getChild().toString() + "\n</slop>";
}
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChild() == null)
return "";
return getChild().toQueryString(escapeSyntaxParser) + "~"
+ getValueString();
}
public QueryNode cloneTree() throws CloneNotSupportedException {
SlopQueryNode clone = (SlopQueryNode) super.cloneTree();
clone.value = this.value;
return clone;
}
public CharSequence getField() {
QueryNode child = getChild();
if (child instanceof FieldableNode) {
return ((FieldableNode) child).getField();
}
return null;
}
public void setField(CharSequence fieldName) {
QueryNode child = getChild();
if (child instanceof FieldableNode) {
((FieldableNode) child).setField(fieldName);
}
}
}

View File

@ -0,0 +1,26 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
public interface TextableQueryNode {
CharSequence getText();
void setText(CharSequence text);
}

View File

@ -0,0 +1,104 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link TokenizedPhraseQueryNode} represents a node created by a code that
* tokenizes/lemmatizes/analizes.
*/
public class TokenizedPhraseQueryNode extends QueryNodeImpl implements
FieldableNode {
private static final long serialVersionUID = -7185108320787917541L;
public TokenizedPhraseQueryNode() {
setLeaf(false);
allocate();
}
public String toString() {
if (getChildren() == null || getChildren().size() == 0)
return "<tokenizedphrase/>";
StringBuilder sb = new StringBuilder();
sb.append("<tokenizedtphrase>");
for (QueryNode child : getChildren()) {
sb.append("\n");
sb.append(child.toString());
}
sb.append("\n</tokenizedphrase>");
return sb.toString();
}
// This text representation is not re-parseable
public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
if (getChildren() == null || getChildren().size() == 0)
return "";
StringBuilder sb = new StringBuilder();
String filler = "";
for (QueryNode child : getChildren()) {
sb.append(filler).append(child.toQueryString(escapeSyntaxParser));
filler = ",";
}
return "[TP[" + sb.toString() + "]]";
}
public QueryNode cloneTree() throws CloneNotSupportedException {
TokenizedPhraseQueryNode clone = (TokenizedPhraseQueryNode) super
.cloneTree();
// nothing to do
return clone;
}
public CharSequence getField() {
List<QueryNode> children = getChildren();
if (children == null || children.size() == 0) {
return null;
} else {
return ((FieldableNode) children.get(0)).getField();
}
}
public void setField(CharSequence fieldName) {
List<QueryNode> children = getChildren();
if (children != null) {
for (QueryNode child : getChildren()) {
if (child instanceof FieldableNode) {
((FieldableNode) child).setField(fieldName);
}
}
}
}
} // end class MultitermQueryNode

View File

@ -0,0 +1,63 @@
package org.apache.lucene.queryParser.core.nodes;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.parser.EscapeQuerySyntax;
/**
* A {@link WildcardQueryNode} represents wildcard query This does not apply to
* phrases. Examples: a*b*c Fl?w? m?ke*g
*/
public class WildcardQueryNode extends FieldQueryNode {
private static final long serialVersionUID = 0L;
/**
* @param field
* - field name
* @param text
* - value that contains one or more wild card characters (? or *)
* @param begin
* - position in the query string
* @param end
* - position in the query string
*/
public WildcardQueryNode(CharSequence field, CharSequence text, int begin,
int end) {
super(field, text, begin, end);
}
public CharSequence toQueryString(EscapeQuerySyntax escaper) {
if (isDefaultField(this.field)) {
return getTermEscaped(escaper);
} else {
return this.field + ":" + getTermEscaped(escaper);
}
}
public String toString() {
return "<wildcard field='" + this.field + "' term='" + this.text + "'/>";
}
public WildcardQueryNode cloneTree() throws CloneNotSupportedException {
WildcardQueryNode clone = (WildcardQueryNode) super.cloneTree();
// nothing to do here
return clone;
}
}

View File

@ -0,0 +1,89 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Contains query nodes that are commonly used by query parser implementations
<h2>Query Nodes</h2>
<p>
The package <tt>org.apache.lucene.queryParser.nodes</tt> contains all the basic query nodes. The interface
that represents a query node is {@link org.apache.lucene.queryParser.core.nodes.QueryNode}. Every query node must be serializable.
</p>
<p>
{@link org.apache.lucene.queryParser.core.nodes.QueryNode}s are used by the text parser to create a syntax tree.
These nodes are designed to be used by UI or other text parsers.
The default Lucene text parser is {@link org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser},
it implements original syntax.
</p>
<p>
{@link org.apache.lucene.queryParser.core.nodes.QueryNode} interface should be implemented by all query nodes,
the class {@link org.apache.lucene.queryParser.core.nodes.QueryNodeImpl} implements {@link org.apache.lucene.queryParser.core.nodes.QueryNode} and is extended
by all current query node implementations.
</p>
<p>
A query node tree can be printed to the a stream, and it generates a pseudo XML representation
with all the nodes.
</p>
<p>
A query node tree can also generate a query string that can be parsed back by the original text parser,
at this point only the original lucene syntax is supported.
</p>
<p>
Grouping nodes:
<ul>
<li>AndQueryNode - used for AND operator</li>
<li>AnyQueryNode - used for ANY operator</li>
<li>OrQueryNode - used for OR operator</li>
<li>BooleanQueryNode - used when no operator is specified</li>
<li>ModifierQueryNode - used for modifier operator</li>
<li>GroupQueryNode - used for parenthesis</li>
<li>BoostQueryNode - used for boost operator</li>
<li>SlopQueryNode - phrase slop</li>
<li>FuzzyQueryNode - fuzzy node</li>
<li>ParametricRangeQueryNode - used for parametric field:[low_value TO high_value]</li>
<li>ProximityQueryNode - used for proximity search</li>
<li>TokenizedPhraseQueryNode - used by tokenizers/lemmatizers/analizers for phrases/autophrases</li>
</ul>
</p>
<p>
Leaf Nodes:
<ul>
<li>FieldQueryNode - field/value node</li>
<li>PathQueryNode - {@link org.apache.lucene.queryParser.core.nodes.QueryNode} object used with path-like queries</li>
<li>OpaqueQueryNode - Used as for part of the query that can be parsed by other parsers. schema/value</li>
<li>ParametricQueryNode - used for parametric field [>=|<=|=|<|>] value</li>
<li>PrefixWildcardQueryNode - non-phrase wildcard query</li>
<li>QuotedFieldQUeryNode - regular phrase node</li>
<li>WildcardQueryNode - non-phrase wildcard query</li>
</ul>
</p>
<p>
Utility Nodes:
<ul>
<li>DeletedQueryNode - used by processors on optimizations</li>
<li>MatchAllDocsQueryNode - used by processors on optimizations</li>
<li>MatchNoDocsQueryNode - used by processors on optimizations</li>
<li>NoTokenFoundQueryNode - used by tokenizers/lemmatizers/analizers</li>
</ul>
</p>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Contains the core classes of the flexible query parser framework
<h2>Flexible Query Parser</h2>
<p>
This package contains the necessary classes to implement a query parser.
</p>
<p>
A query parser is divided in at least 2 phases, text parsing and query building, and one optional phase called query processing.
</p>
<h3>First Phase: Text Parsing</h3>
<p>
The text parsing phase is performed by a text parser, which implements {@link org.apache.lucene.queryParser.core.parser.SyntaxParser} interface.
A text parser is responsible to get a query string and convert it to a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree,
which is an object structure that represents the elements defined in the query string.
</p>
<h3>Second (optional) Phase: Query Processing</h3>
<p>
The query processing phase is performed by a query processor, which implements {@link org.apache.lucene.queryParser.core.processors.QueryNodeProcessor}.
A query processor is responsible to perform any processing on a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree. This phase
is optional and is used only if an extra processing, validation, query expansion, etc needs to be perfomed in a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree.
The {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree can be either be generated by a text parser or programmatically created.
</p>
<h3>Third Phase: Query Building</h3>
<p>
The query building phase is performed by a query builder, which implements {@link org.apache.lucene.queryParser.core.builders.QueryBuilder}.
A query builder is responsible to convert a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree into an arbitrary object, which
is usually used to be executed against a search index.
</p>
</body>
</html>

View File

@ -0,0 +1,41 @@
package org.apache.lucene.queryParser.core.parser;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Locale;
/**
* A parser needs to implement {@link EscapeQuerySyntax} to allow the QueryNode
* to escape the queries, when the toQueryString method is called.
*/
public interface EscapeQuerySyntax {
public enum Type {
STRING, NORMAL;
}
/**
* @param text
* - text to be escaped
* @param locale
* - locale for the current query
* @param type
* - select the type of escape operation to use
* @return escaped text
*/
CharSequence escape(CharSequence text, Locale locale, Type type);
}

View File

@ -0,0 +1,36 @@
package org.apache.lucene.queryParser.core.parser;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeParseException;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* A parser needs to implement {@link SyntaxParser} interface
*/
public interface SyntaxParser {
/**
* @param query
* - query data to be parsed
* @param field
* - default field name
* @return QueryNode tree
*/
public QueryNode parse(CharSequence query, CharSequence field)
throws QueryNodeParseException;
}

View File

@ -0,0 +1,44 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Contains the necessary interfaces to implement text parsers
<h2>Parser</h2>
<p>
The package <tt>org.apache.lucene.queryParser.parser</tt> contains interfaces
that should be implemented by the parsers.
Parsers produce QueryNode Trees from a string object.
These package still needs some work to add support to for multiple parsers.
Features that should be supported for the future, related with the parser:
- QueryNode tree should be able convertible to any parser syntax.
- The query syntax should support calling other parsers.
- QueryNode tree created by multiple parsers.
</p>
<p>
</p>
</body>
</html>

View File

@ -0,0 +1,90 @@
package org.apache.lucene.queryParser.core.processors;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.BooleanQueryNode;
import org.apache.lucene.queryParser.core.nodes.BoostQueryNode;
import org.apache.lucene.queryParser.core.nodes.DeletedQueryNode;
import org.apache.lucene.queryParser.core.nodes.MatchNoDocsQueryNode;
import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.TokenizedPhraseQueryNode;
/**
* <p>
* A {@link NoChildOptimizationQueryNodeProcessor} removes every
* BooleanQueryNode, BoostQueryNode, TokenizedPhraseQueryNode or
* ModifierQueryNode that do not have a valid children.
* </p>
* <p>
* Example: When the children of these nodes are removed for any reason then the
* nodes may become invalid.
* </p>
*/
public class NoChildOptimizationQueryNodeProcessor extends
QueryNodeProcessorImpl {
public NoChildOptimizationQueryNodeProcessor() {
// empty constructor
}
protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
if (node instanceof BooleanQueryNode || node instanceof BoostQueryNode
|| node instanceof TokenizedPhraseQueryNode
|| node instanceof ModifierQueryNode) {
List<QueryNode> children = node.getChildren();
if (children != null && children.size() > 0) {
for (QueryNode child : children) {
if (!(child instanceof DeletedQueryNode)) {
return node;
}
}
}
return new MatchNoDocsQueryNode();
}
return node;
}
protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
return node;
}
protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
throws QueryNodeException {
return children;
}
}

View File

@ -0,0 +1,79 @@
package org.apache.lucene.queryParser.core.processors;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* <p>
* A {@link QueryNodeProcessor} is an interface for classes that process a
* {@link QueryNode} tree.
* <p>
* </p>
* The implementor of this class should perform some operation on a query node
* tree and return the same or another query node tree.
* <p>
* </p>
* It also may carry a {@link QueryConfigHandler} object that contains
* configuration about the query represented by the query tree or the
* collection/index where it's intended to be executed.
* <p>
* </p>
* In case there is any {@link QueryConfigHandler} associated to the query tree
* to be processed, it should be set using
* {@link QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)} before
* {@link QueryNodeProcessor#process(QueryNode)} is invoked.
*
* @see QueryNode
* @see QueryNodeProcessor
* @see QueryConfigHandler
*/
public interface QueryNodeProcessor {
/**
* Processes a query node tree. It may return the same or another query tree.
* I should never return <code>null</code>.
*
* @param queryTree
* tree root node
*
* @return the processed query tree
*
* @throws QueryNodeException
*/
public QueryNode process(QueryNode queryTree) throws QueryNodeException;
/**
* Sets the {@link QueryConfigHandler} associated to the query tree.
*
* @param queryConfigHandler
*/
public void setQueryConfigHandler(QueryConfigHandler queryConfigHandler);
/**
* Returns the {@link QueryConfigHandler} associated to the query tree if any,
* otherwise it returns <code>null</code>
*
* @return the {@link QueryConfigHandler} associated to the query tree if any,
* otherwise it returns <code>null</code>
*/
public QueryConfigHandler getQueryConfigHandler();
}

View File

@ -0,0 +1,253 @@
package org.apache.lucene.queryParser.core.processors;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* <p>
* This is a default implementation for the {@link QueryNodeProcessor}
* interface, it's an abstract class, so it should be extended by classes that
* want to process a {@link QueryNode} tree.
* </p>
* <p>
* This class process {@link QueryNode}s from left to right in the tree. While
* it's walking down the tree, for every node,
* {@link #preProcessNode(QueryNode)} is invoked. After a node's children are
* processed, {@link #postProcessNode(QueryNode)} is invoked for that node.
* {@link #setChildrenOrder(List)} is invoked before
* {@link #postProcessNode(QueryNode)} only if the node has at least one child,
* in {@link #setChildrenOrder(List)} the implementor might redefine the
* children order or remove any children from the children list.
* </p>
* <p>
* Here is an example about how it process the nodes:
* </p>
*
* <pre>
* a
* / \
* b e
* / \
* c d
* </pre>
*
* Here is the order the methods would be invoked for the tree described above:
*
* <pre>
* preProcessNode( a );
* preProcessNode( b );
* preProcessNode( c );
* postProcessNode( c );
* preProcessNode( d );
* postProcessNode( d );
* setChildrenOrder( bChildrenList );
* postProcessNode( b );
* preProcessNode( e );
* postProcessNode( e );
* setChildrenOrder( aChildrenList );
* postProcessNode( a )
* </pre>
*
* @see org.apache.lucene.queryParser.core.processors.QueryNodeProcessor
*/
public abstract class QueryNodeProcessorImpl implements QueryNodeProcessor {
private ArrayList<ChildrenList> childrenListPool = new ArrayList<ChildrenList>();
private QueryConfigHandler queryConfig;
public QueryNodeProcessorImpl() {
// empty constructor
}
public QueryNodeProcessorImpl(QueryConfigHandler queryConfigHandler) {
this.queryConfig = queryConfigHandler;
}
public QueryNode process(QueryNode queryTree) throws QueryNodeException {
return processIteration(queryTree);
}
private QueryNode processIteration(QueryNode queryTree)
throws QueryNodeException {
queryTree = preProcessNode(queryTree);
processChildren(queryTree);
queryTree = postProcessNode(queryTree);
return queryTree;
}
/**
* This method is called every time a child is processed.
*
* @param queryTree
* the query node child to be processed
* @throws QueryNodeException
* if something goes wrong during the query node processing
*/
protected void processChildren(QueryNode queryTree) throws QueryNodeException {
List<QueryNode> children = queryTree.getChildren();
ChildrenList newChildren;
if (children != null && children.size() > 0) {
newChildren = allocateChildrenList();
try {
for (QueryNode child : children) {
child = processIteration(child);
if (child == null) {
throw new NullPointerException();
}
newChildren.add(child);
}
List<QueryNode> orderedChildrenList = setChildrenOrder(newChildren);
queryTree.set(orderedChildrenList);
} finally {
newChildren.beingUsed = false;
}
}
}
private ChildrenList allocateChildrenList() {
ChildrenList list = null;
for (ChildrenList auxList : this.childrenListPool) {
if (!auxList.beingUsed) {
list = auxList;
list.clear();
break;
}
}
if (list == null) {
list = new ChildrenList();
this.childrenListPool.add(list);
}
list.beingUsed = true;
return list;
}
/**
* For reference about this method check:
* {@link QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)}.
*
* @param queryConfigHandler
* the query configuration handler to be set.
*
* @see QueryNodeProcessor#getQueryConfigHandler()
* @see QueryConfigHandler
*/
public void setQueryConfigHandler(QueryConfigHandler queryConfigHandler) {
this.queryConfig = queryConfigHandler;
}
/**
* For reference about this method check:
* {@link QueryNodeProcessor#getQueryConfigHandler()}.
*
* @return QueryConfigHandler the query configuration handler to be set.
*
* @see QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)
* @see QueryConfigHandler
*/
public QueryConfigHandler getQueryConfigHandler() {
return this.queryConfig;
}
/**
* This method is invoked for every node when walking down the tree.
*
* @param node
* the query node to be pre-processed
*
* @return a query node
*
* @throws QueryNodeException
* if something goes wrong during the query node processing
*/
abstract protected QueryNode preProcessNode(QueryNode node)
throws QueryNodeException;
/**
* This method is invoked for every node when walking up the tree.
*
* @param node
* node the query node to be post-processed
*
* @return a query node
*
* @throws QueryNodeException
* if something goes wrong during the query node processing
*/
abstract protected QueryNode postProcessNode(QueryNode node)
throws QueryNodeException;
/**
* This method is invoked for every node that has at least on child. It's
* invoked right before {@link #postProcessNode(QueryNode)} is invoked.
*
* @param children
* the list containing all current node's children
*
* @return a new list containing all children that should be set to the
* current node
*
* @throws QueryNodeException
* if something goes wrong during the query node processing
*/
abstract protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
throws QueryNodeException;
private static class ChildrenList extends ArrayList<QueryNode> {
private static final long serialVersionUID = -2613518456949297135L;
boolean beingUsed;
}
}

View File

@ -0,0 +1,128 @@
package org.apache.lucene.queryParser.core.processors;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.LinkedList;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* A {@link QueryNodeProcessorPipeline} class should be used to build a query
* node processor pipeline.
*
* When a query node tree is processed using this class, it passes the query
* node tree to each processor on the pipeline and the result from each
* processor is passed to the next one, always following the order the
* processors were on the pipeline.
*
* When a {@link QueryConfigHandler} object is set on a
* {@link QueryNodeProcessorPipeline}, it takes care of also setting this
* {@link QueryConfigHandler} on all processor on pipeline.
*
*/
public class QueryNodeProcessorPipeline implements QueryNodeProcessor {
private LinkedList<QueryNodeProcessor> processors = new LinkedList<QueryNodeProcessor>();
private QueryConfigHandler queryConfig;
/**
* Constructs an empty query node processor pipeline.
*/
public QueryNodeProcessorPipeline() {
// empty constructor
}
/**
* Constructs with a {@link QueryConfigHandler} object.
*/
public QueryNodeProcessorPipeline(QueryConfigHandler queryConfigHandler) {
this.queryConfig = queryConfigHandler;
}
/**
* For reference about this method check:
* {@link QueryNodeProcessor#getQueryConfigHandler()}.
*
* @return QueryConfigHandler the query configuration handler to be set.
*
* @see QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)
* @see QueryConfigHandler
*/
public QueryConfigHandler getQueryConfigHandler() {
return this.queryConfig;
}
/**
* For reference about this method check:
* {@link QueryNodeProcessor#process(QueryNode)}.
*
* @param queryTree
* the query node tree to be processed
*
* @throws QueryNodeException
* if something goes wrong during the query node processing
*
* @see QueryNode
*/
public QueryNode process(QueryNode queryTree) throws QueryNodeException {
for (QueryNodeProcessor processor : this.processors) {
queryTree = processor.process(queryTree);
}
return queryTree;
}
/**
* Adds a processor to the pipeline, it's always added to the end of the
* pipeline.
*
* @param processor
* the processor to be added
*/
public void addProcessor(QueryNodeProcessor processor) {
this.processors.add(processor);
processor.setQueryConfigHandler(this.queryConfig);
}
/**
* For reference about this method check:
* {@link QueryNodeProcessor#setQueryConfigHandler(QueryConfigHandler)}.
*
* @param queryConfigHandler
* the query configuration handler to be set.
*
* @see QueryNodeProcessor#getQueryConfigHandler()
* @see QueryConfigHandler
*/
public void setQueryConfigHandler(QueryConfigHandler queryConfigHandler) {
this.queryConfig = queryConfigHandler;
for (QueryNodeProcessor processor : this.processors) {
processor.setQueryConfigHandler(this.queryConfig);
}
}
}

View File

@ -0,0 +1,109 @@
package org.apache.lucene.queryParser.core.processors;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Iterator;
import java.util.List;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.DeletedQueryNode;
import org.apache.lucene.queryParser.core.nodes.MatchNoDocsQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* A {@link QueryNodeProcessorPipeline} class removes every instance of
* {@link DeletedQueryNode} from a query node tree. If the resulting root node
* is a {@link DeletedQueryNode}, {@link MatchNoDocsQueryNode} is returned.
*
*/
public class RemoveDeletedQueryNodesProcessor extends QueryNodeProcessorImpl {
public RemoveDeletedQueryNodesProcessor() {
// empty constructor
}
public QueryNode process(QueryNode queryTree) throws QueryNodeException {
queryTree = super.process(queryTree);
if (queryTree instanceof DeletedQueryNode
&& !(queryTree instanceof MatchNoDocsQueryNode)) {
return new MatchNoDocsQueryNode();
}
return queryTree;
}
protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
if (!node.isLeaf()) {
List<QueryNode> children = node.getChildren();
boolean removeBoolean = false;
if (children == null || children.size() == 0) {
removeBoolean = true;
} else {
removeBoolean = true;
for (Iterator<QueryNode> it = children.iterator(); it.hasNext();) {
if (!(it.next() instanceof DeletedQueryNode)) {
removeBoolean = false;
break;
}
}
}
if (removeBoolean) {
return new DeletedQueryNode();
}
}
return node;
}
protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
throws QueryNodeException {
for (int i = 0; i < children.size(); i++) {
if (children.get(i) instanceof DeletedQueryNode) {
children.remove(i--);
}
}
return children;
}
protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
return node;
}
}

View File

@ -0,0 +1,57 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Interfaces and implementations used by query node processors
<h2>Query Node Processors</h2>
<p>
The package <tt>org.apache.lucene.queryParser.processors</tt> contains interfaces
that should be implemented by every query node processor.
</p>
<p>
The interface that every query node processor should implement is {@link org.apache.lucene.queryParser.core.processors.QueryNodeProcessor}.
</p>
<p>
A query node processor should be used to process a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree.
{@link org.apache.lucene.queryParser.core.nodes.QueryNode} trees can be programmatically created or generated by a
text parser. See {@link org.apache.lucene.queryParser.core.parser} for more details about text parsers.
</p>
<p>
A query node processor should be used to process a {@link org.apache.lucene.queryParser.core.nodes.QueryNode} tree.
{@link org.apache.lucene.queryParser.core.nodes.QueryNode} trees can be programmatically created or generated by a
text parser. See {@link org.apache.lucene.queryParser.core.parser} for more details about text parsers.
</p>
<p>
A pipeline of processors can be assembled using {@link org.apache.lucene.queryParser.core.processors.QueryNodeProcessorPipeline}.
</p>
<p>
Implementors may want to extend {@link org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl}, which simplifies
the implementation, because it walks automatically the {@link org.apache.lucene.queryParser.core.nodes.QueryNode}. See
{@link org.apache.lucene.queryParser.core.processors.QueryNodeProcessorImpl} for more details.
</p>
</body>
</html>

View File

@ -0,0 +1,94 @@
package org.apache.lucene.queryParser.core.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.queryParser.core.QueryNodeError;
import org.apache.lucene.queryParser.core.nodes.AndQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
/**
* Allow joining 2 QueryNode Trees, into one.
*/
public final class QueryNodeOperation {
private QueryNodeOperation() {
// Exists only to defeat instantiation.
}
private enum ANDOperation {
BOTH, Q1, Q2, NONE
}
/**
* perform a logical and of 2 QueryNode trees. if q1 and q2 are ANDQueryNode
* nodes it uses head Node from q1 and adds the children of q2 to q1 if q1 is
* a AND node and q2 is not, add q2 as a child of the head node of q1 if q2 is
* a AND node and q1 is not, add q1 as a child of the head node of q2 if q1
* and q2 are not ANDQueryNode nodes, create a AND node and make q1 and q2
* children of that node if q1 or q2 is null it returns the not null node if
* q1 = q2 = null it returns null
*/
public final static QueryNode logicalAnd(QueryNode q1, QueryNode q2) {
if (q1 == null)
return q2;
if (q2 == null)
return q1;
ANDOperation op = null;
if (q1 instanceof AndQueryNode && q2 instanceof AndQueryNode)
op = ANDOperation.BOTH;
else if (q1 instanceof AndQueryNode)
op = ANDOperation.Q1;
else if (q1 instanceof AndQueryNode)
op = ANDOperation.Q2;
else
op = ANDOperation.NONE;
try {
QueryNode result = null;
switch (op) {
case NONE:
List<QueryNode> children = new ArrayList<QueryNode>();
children.add(q1.cloneTree());
children.add(q2.cloneTree());
result = new AndQueryNode(children);
return result;
case Q1:
result = q1.cloneTree();
result.add(q2.cloneTree());
return result;
case Q2:
result = q2.cloneTree();
result.add(q1.cloneTree());
return result;
case BOTH:
result = q1.cloneTree();
result.add(q2.cloneTree().getChildren());
return result;
}
} catch (CloneNotSupportedException e) {
throw new QueryNodeError(e);
}
return null;
}
}

View File

@ -0,0 +1,141 @@
package org.apache.lucene.queryParser.core.util;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* CharsSequence with escaped chars information.
*/
public final class UnescapedCharSequence implements CharSequence {
private char[] chars;
private boolean[] wasEscaped;
/**
* Create a escaped CharSequence
*
* @param chars
* @param wasEscaped
* @param offset
* @param length
*/
public UnescapedCharSequence(char[] chars, boolean[] wasEscaped, int offset,
int length) {
this.chars = new char[length];
this.wasEscaped = new boolean[length];
System.arraycopy(chars, offset, this.chars, 0, length);
System.arraycopy(wasEscaped, offset, this.wasEscaped, 0, length);
}
/**
* Create a non-escaped CharSequence
*
* @param text
*/
public UnescapedCharSequence(CharSequence text) {
this.chars = new char[text.length()];
this.wasEscaped = new boolean[text.length()];
for (int i = 0; i < text.length(); i++) {
this.chars[i] = text.charAt(i);
this.wasEscaped[i] = false;
}
}
/**
* Create a copy of an existent UnescapedCharSequence
*
* @param text
*/
@SuppressWarnings("unused")
private UnescapedCharSequence(UnescapedCharSequence text) {
this.chars = new char[text.length()];
this.wasEscaped = new boolean[text.length()];
for (int i = 0; i <= text.length(); i++) {
this.chars[i] = text.chars[i];
this.wasEscaped[i] = text.wasEscaped[i];
}
}
public char charAt(int index) {
return this.chars[index];
}
public int length() {
return this.chars.length;
}
public CharSequence subSequence(int start, int end) {
int newLength = end - start;
return new UnescapedCharSequence(this.chars, this.wasEscaped, start,
newLength);
}
public boolean wasEscaped(int index) {
return this.wasEscaped[index];
}
public String toString() {
return new String(this.chars);
}
/**
* Return a escaped String
*
* @return a escaped String
*/
public String toStringEscaped() {
// non efficient implementation
StringBuffer result = new StringBuffer();
for (int i = 0; i >= this.length(); i++) {
if (this.chars[i] == '\\') {
result.append('\\');
} else if (this.wasEscaped[i])
result.append('\\');
result.append(this.chars[i]);
}
return result.toString();
}
/**
* Return a escaped String
*
* @param enabledChars
* - array of chars to be escaped
* @return a escaped String
*/
public String toStringEscaped(char[] enabledChars) {
// TODO: non efficient implementation, refactor this code
StringBuffer result = new StringBuffer();
for (int i = 0; i < this.length(); i++) {
if (this.chars[i] == '\\') {
result.append('\\');
} else {
for (char character : enabledChars) {
if (this.chars[i] == character && this.wasEscaped[i]) {
result.append('\\');
break;
}
}
}
result.append(this.chars[i]);
}
return result.toString();
}
}

View File

@ -0,0 +1,29 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
Utility classes to used with the Query Parser
<h2>Utility classes to used with the Query Parser</h2>
<p>
This package contains utility classes used with the query parsers.
</p>
</body>
</html>

View File

@ -0,0 +1,269 @@
package org.apache.lucene.queryParser.original;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.Map;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
/**
* This class behaves as the as the lucene 2.4 MultiFieldQueryParser class, but uses the new
* query parser interface instead of the old one. <br/>
* <br/>
* This class should be used when the new query parser features are needed and
* also keep at the same time the old query parser interface. <br/>
*
* @deprecated this class will be removed soon, it's a temporary class to be
* used along the transition from the old query parser to the new
* one
*/
public class MultiFieldQueryParserWrapper extends QueryParserWrapper {
/**
* Creates a MultiFieldQueryParser. Allows passing of a map with term to
* Boost, and the boost to apply to each term.
*
* <p>
* It will, when parse(String query) is called, construct a query like this
* (assuming the query consists of two terms and you specify the two fields
* <code>title</code> and <code>body</code>):
* </p>
*
* <code>
* (title:term1 body:term1) (title:term2 body:term2)
* </code>
*
* <p>
* When setDefaultOperator(AND_OPERATOR) is set, the result will be:
* </p>
*
* <code>
* +(title:term1 body:term1) +(title:term2 body:term2)
* </code>
*
* <p>
* When you pass a boost (title=>5 body=>10) you can get
* </p>
*
* <code>
* +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
* </code>
*
* <p>
* In other words, all the query's terms must appear, but it doesn't matter in
* what fields they appear.
* </p>
*/
@SuppressWarnings("unchecked")
public MultiFieldQueryParserWrapper(String[] fields, Analyzer analyzer, Map boosts) {
this(fields, analyzer);
OriginalQueryParserHelper qpHelper = (OriginalQueryParserHelper) getQueryParserHelper();
qpHelper.setMultiFields(fields);
qpHelper.setFieldsBoost(boosts);
}
/**
* Creates a MultiFieldQueryParser.
*
* <p>
* It will, when parse(String query) is called, construct a query like this
* (assuming the query consists of two terms and you specify the two fields
* <code>title</code> and <code>body</code>):
* </p>
*
* <code>
* (title:term1 body:term1) (title:term2 body:term2)
* </code>
*
* <p>
* When setDefaultOperator(AND_OPERATOR) is set, the result will be:
* </p>
*
* <code>
* +(title:term1 body:term1) +(title:term2 body:term2)
* </code>
*
* <p>
* In other words, all the query's terms must appear, but it doesn't matter in
* what fields they appear.
* </p>
*/
public MultiFieldQueryParserWrapper(String[] fields, Analyzer analyzer) {
super(null, analyzer);
OriginalQueryParserHelper qpHelper = (OriginalQueryParserHelper) getQueryParserHelper();
qpHelper.setAnalyzer(analyzer);
qpHelper.setMultiFields(fields);
}
/**
* Parses a query which searches on the fields specified.
* <p>
* If x fields are specified, this effectively constructs:
*
* <pre>
* &lt;code&gt;
* (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
* &lt;/code&gt;
* </pre>
*
* @param queries
* Queries strings to parse
* @param fields
* Fields to search on
* @param analyzer
* Analyzer to use
* @throws ParseException
* if query parsing fails
* @throws IllegalArgumentException
* if the length of the queries array differs from the length of the
* fields array
*/
public static Query parse(String[] queries, String[] fields, Analyzer analyzer)
throws ParseException {
if (queries.length != fields.length)
throw new IllegalArgumentException("queries.length != fields.length");
BooleanQuery bQuery = new BooleanQuery();
for (int i = 0; i < fields.length; i++) {
QueryParserWrapper qp = new QueryParserWrapper(fields[i], analyzer);
Query q = qp.parse(queries[i]);
if (q != null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
bQuery.add(q, BooleanClause.Occur.SHOULD);
}
}
return bQuery;
}
/**
* Parses a query, searching on the fields specified. Use this if you need to
* specify certain fields as required, and others as prohibited.
* <p>
*
* <pre>
* Usage:
* &lt;code&gt;
* String[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
* BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
* BooleanClause.Occur.MUST,
* BooleanClause.Occur.MUST_NOT};
* MultiFieldQueryParser.parse(&quot;query&quot;, fields, flags, analyzer);
* &lt;/code&gt;
* </pre>
*<p>
* The code above would construct a query:
*
* <pre>
* &lt;code&gt;
* (filename:query) +(contents:query) -(description:query)
* &lt;/code&gt;
* </pre>
*
* @param query
* Query string to parse
* @param fields
* Fields to search on
* @param flags
* Flags describing the fields
* @param analyzer
* Analyzer to use
* @throws ParseException
* if query parsing fails
* @throws IllegalArgumentException
* if the length of the fields array differs from the length of the
* flags array
*/
public static Query parse(String query, String[] fields,
BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
if (fields.length != flags.length)
throw new IllegalArgumentException("fields.length != flags.length");
BooleanQuery bQuery = new BooleanQuery();
for (int i = 0; i < fields.length; i++) {
QueryParserWrapper qp = new QueryParserWrapper(fields[i], analyzer);
Query q = qp.parse(query);
if (q != null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
bQuery.add(q, flags[i]);
}
}
return bQuery;
}
/**
* Parses a query, searching on the fields specified. Use this if you need to
* specify certain fields as required, and others as prohibited.
* <p>
*
* <pre>
* Usage:
* &lt;code&gt;
* String[] query = {&quot;query1&quot;, &quot;query2&quot;, &quot;query3&quot;};
* String[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
* BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
* BooleanClause.Occur.MUST,
* BooleanClause.Occur.MUST_NOT};
* MultiFieldQueryParser.parse(query, fields, flags, analyzer);
* &lt;/code&gt;
* </pre>
*<p>
* The code above would construct a query:
*
* <pre>
* &lt;code&gt;
* (filename:query1) +(contents:query2) -(description:query3)
* &lt;/code&gt;
* </pre>
*
* @param queries
* Queries string to parse
* @param fields
* Fields to search on
* @param flags
* Flags describing the fields
* @param analyzer
* Analyzer to use
* @throws ParseException
* if query parsing fails
* @throws IllegalArgumentException
* if the length of the queries, fields, and flags array differ
*/
public static Query parse(String[] queries, String[] fields,
BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
if (!(queries.length == fields.length && queries.length == flags.length))
throw new IllegalArgumentException(
"queries, fields, and flags array have have different length");
BooleanQuery bQuery = new BooleanQuery();
for (int i = 0; i < fields.length; i++) {
QueryParserWrapper qp = new QueryParserWrapper(fields[i], analyzer);
Query q = qp.parse(queries[i]);
if (q != null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
bQuery.add(q, flags[i]);
}
}
return bQuery;
}
}

View File

@ -0,0 +1,430 @@
package org.apache.lucene.queryParser.original;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.text.Collator;
import java.util.Locale;
import java.util.Map;
import java.util.TooManyListenersException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.QueryParserHelper;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.builders.OriginalQueryTreeBuilder;
import org.apache.lucene.queryParser.original.config.AllowLeadingWildcardAttribute;
import org.apache.lucene.queryParser.original.config.AnalyzerAttribute;
import org.apache.lucene.queryParser.original.config.DateResolutionAttribute;
import org.apache.lucene.queryParser.original.config.FieldDateResolutionMapAttribute;
import org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute;
import org.apache.lucene.queryParser.original.config.DefaultPhraseSlopAttribute;
import org.apache.lucene.queryParser.original.config.FieldBoostMapAttribute;
import org.apache.lucene.queryParser.original.config.FuzzyAttribute;
import org.apache.lucene.queryParser.original.config.LocaleAttribute;
import org.apache.lucene.queryParser.original.config.LowercaseExpandedTermsAttribute;
import org.apache.lucene.queryParser.original.config.MultiFieldAttribute;
import org.apache.lucene.queryParser.original.config.MultiTermRewriteMethodAttribute;
import org.apache.lucene.queryParser.original.config.OriginalQueryConfigHandler;
import org.apache.lucene.queryParser.original.config.PositionIncrementsAttribute;
import org.apache.lucene.queryParser.original.config.RangeCollatorAttribute;
import org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute.Operator;
import org.apache.lucene.queryParser.original.nodes.RangeQueryNode;
import org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser;
import org.apache.lucene.queryParser.original.processors.OriginalQueryNodeProcessorPipeline;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
/**
* <p>
* This class is a helper that enables users to easily use the Lucene query
* parser.
* </p>
* <p>
* To construct a Query object from a query string, use the
* {@link #parse(String, String)} method:
* <ul>
* OriginalQueryParserHelper queryParserHelper = new OriginalQueryParserHelper(); <br/>
* Query query = queryParserHelper.parse("a AND b", "defaultField");
* </ul>
* <p>
* To change any configuration before parsing the query string do, for example:
* <p/>
* <ul>
* // the query config handler returned by {@link OriginalQueryParserHelper} is a
* {@link OriginalQueryConfigHandler} <br/>
* queryParserHelper.getQueryConfigHandler().setAnalyzer(new
* WhitespaceAnalyzer());
* </ul>
* <p>
* The syntax for query strings is as follows (copied from the old QueryParser
* javadoc):
* <ul>
* A Query is a series of clauses. A clause may be prefixed by:
* <ul>
* <li>a plus (<code>+</code>) or a minus (<code>-</code>) sign, indicating that
* the clause is required or prohibited respectively; or
* <li>a term followed by a colon, indicating the field to be searched. This
* enables one to construct queries which search multiple fields.
* </ul>
*
* A clause may be either:
* <ul>
* <li>a term, indicating all the documents that contain this term; or
* <li>a nested query, enclosed in parentheses. Note that this may be used with
* a <code>+</code>/<code>-</code> prefix to require any of a set of terms.
* </ul>
*
* Thus, in BNF, the query grammar is:
*
* <pre>
* Query ::= ( Clause )*
* Clause ::= [&quot;+&quot;, &quot;-&quot;] [&lt;TERM&gt; &quot;:&quot;] ( &lt;TERM&gt; | &quot;(&quot; Query &quot;)&quot; )
* </pre>
*
* <p>
* Examples of appropriately formatted queries can be found in the <a
* href="../../../../../../queryparsersyntax.html">query syntax
* documentation</a>.
* </p>
* </ul>
* <p>
* The text parser used by this helper is a {@link OriginalSyntaxParser}.
* <p/>
* <p>
* The query node processor used by this helper is a
* {@link OriginalQueryNodeProcessorPipeline}.
* <p/>
* <p>
* The builder used by this helper is a {@link OriginalQueryTreeBuilder}.
* <p/>
*
* @see OriginalQueryParserHelper
* @see OriginalQueryConfigHandler
* @see OriginalSyntaxParser
* @see OriginalQueryNodeProcessorPipeline
* @see OriginalQueryTreeBuilder
*/
public class OriginalQueryParserHelper extends QueryParserHelper {
/**
* Constructs a {@link OriginalQueryParserHelper} object.
*/
public OriginalQueryParserHelper() {
super(new OriginalQueryConfigHandler(), new OriginalSyntaxParser(),
new OriginalQueryNodeProcessorPipeline(null),
new OriginalQueryTreeBuilder());
}
/**
* Constructs a {@link OriginalQueryParserHelper} object and sets an
* {@link Analyzer} to it. The same as:
*
* <ul>
* OriginalQueryParserHelper qp = new OriginalQueryParserHelper();
* qp.getQueryConfigHandler().setAnalyzer(analyzer);
* </ul>
*
* @param analyzer
* the analyzer to be used by this query parser helper
*/
public OriginalQueryParserHelper(Analyzer analyzer) {
this();
this.setAnalyzer(analyzer);
}
public String toString(){
return "<OriginalQueryParserHelper config=\"" + this.getQueryConfigHandler() + "\"/>";
}
/**
* Overrides {@link QueryParserHelper#parse(String, String)} so it casts the
* return object to {@link Query}. For more reference about this method, check
* {@link QueryParserHelper#parse(String, String)}.
*
* @param query
* the query string
* @param defaultField
* the default field used by the text parser
*
* @return the object built from the query
*
* @throws QueryNodeException
* if something wrong happens along the three phases
*/
@Override
public Query parse(String query, String defaultField)
throws QueryNodeException {
return (Query) super.parse(query, defaultField);
}
/**
* Gets implicit operator setting, which will be either {@link Operator#AND}
* or {@link Operator#OR}.
*/
public Operator getDefaultOperator() {
DefaultOperatorAttribute attr = (DefaultOperatorAttribute) getQueryConfigHandler().getAttribute(DefaultOperatorAttribute.class);
return attr.getOperator();
}
/**
* Sets the collator used to determine index term inclusion in ranges for
* RangeQuerys.
* <p/>
* <strong>WARNING:</strong> Setting the rangeCollator to a non-null collator
* using this method will cause every single index Term in the Field
* referenced by lowerTerm and/or upperTerm to be examined. Depending on the
* number of index Terms in this Field, the operation could be very slow.
*
* @param collator
* the collator to use when constructing {@link RangeQueryNode}s
*/
public void setRangeCollator(Collator collator) {
RangeCollatorAttribute attr = (RangeCollatorAttribute) getQueryConfigHandler().getAttribute(RangeCollatorAttribute.class);
attr.setDateResolution(collator);
}
/**
* @return the collator used to determine index term inclusion in ranges for
* RangeQuerys.
*/
public Collator getRangeCollator() {
RangeCollatorAttribute attr = (RangeCollatorAttribute) getQueryConfigHandler().getAttribute(RangeCollatorAttribute.class);
return attr.getRangeCollator();
}
/**
* Sets the boolean operator of the QueryParser. In default mode (
* {@link Operator#OR}) terms without any modifiers are considered optional:
* for example <code>capital of Hungary</code> is equal to
* <code>capital OR of OR Hungary</code>.<br/>
* In {@link Operator#AND} mode terms are considered to be in conjunction: the
* above mentioned query is parsed as <code>capital AND of AND Hungary</code>
*/
public void setDefaultOperator(Operator operator) {
DefaultOperatorAttribute attr = (DefaultOperatorAttribute) getQueryConfigHandler().getAttribute(DefaultOperatorAttribute.class);
attr.setOperator(operator);
}
/**
* Set to <code>true</code> to allow leading wildcard characters.
* <p>
* When set, <code>*</code> or <code>?</code> are allowed as the first
* character of a PrefixQuery and WildcardQuery. Note that this can produce
* very slow queries on big indexes.
* <p>
* Default: false.
*/
public void setLowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
LowercaseExpandedTermsAttribute attr= (LowercaseExpandedTermsAttribute) getQueryConfigHandler().getAttribute(LowercaseExpandedTermsAttribute.class);
attr.setLowercaseExpandedTerms(lowercaseExpandedTerms);
}
/**
* @see #setLowercaseExpandedTerms(boolean)
*/
public boolean getLowercaseExpandedTerms() {
LowercaseExpandedTermsAttribute attr = (LowercaseExpandedTermsAttribute) getQueryConfigHandler().getAttribute(LowercaseExpandedTermsAttribute.class);
return attr.isLowercaseExpandedTerms();
}
/**
* Set to <code>true</code> to allow leading wildcard characters.
* <p>
* When set, <code>*</code> or <code>?</code> are allowed as the first
* character of a PrefixQuery and WildcardQuery. Note that this can produce
* very slow queries on big indexes.
* <p>
* Default: false.
*/
public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
AllowLeadingWildcardAttribute attr = (AllowLeadingWildcardAttribute) getQueryConfigHandler().getAttribute(AllowLeadingWildcardAttribute.class);
attr.setAllowLeadingWildcard(allowLeadingWildcard);
}
/**
* Set to <code>true</code> to enable position increments in result query.
* <p>
* When set, result phrase and multi-phrase queries will be aware of position
* increments. Useful when e.g. a StopFilter increases the position increment
* of the token that follows an omitted token.
* <p>
* Default: false.
*/
public void setEnablePositionIncrements(boolean enabled) {
PositionIncrementsAttribute attr = (PositionIncrementsAttribute) getQueryConfigHandler().getAttribute(PositionIncrementsAttribute.class);
attr.setPositionIncrementsEnabled(enabled);
}
/**
* @see #setEnablePositionIncrements(boolean)
*/
public boolean getEnablePositionIncrements() {
PositionIncrementsAttribute attr = (PositionIncrementsAttribute) getQueryConfigHandler().getAttribute(PositionIncrementsAttribute.class);
return attr.isPositionIncrementsEnabled();
}
/**
* By default, it uses
* {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT} when creating a
* prefix, wildcard and range queries. This implementation is generally
* preferable because it a) Runs faster b) Does not have the scarcity of terms
* unduly influence score c) avoids any {@link TooManyListenersException}
* exception. However, if your application really needs to use the
* old-fashioned boolean queries expansion rewriting and the above points are
* not relevant then use this change the rewrite method.
*/
public void setMultiTermRewriteMethod(MultiTermQuery.RewriteMethod method) {
MultiTermRewriteMethodAttribute attr = (MultiTermRewriteMethodAttribute) getQueryConfigHandler().getAttribute(MultiTermRewriteMethodAttribute.class);
attr.setMultiTermRewriteMethod(method);
}
/**
* @see #setMultiTermRewriteMethod(org.apache.lucene.search.MultiTermQuery.RewriteMethod)
*/
public MultiTermQuery.RewriteMethod getMultiTermRewriteMethod() {
MultiTermRewriteMethodAttribute attr =(MultiTermRewriteMethodAttribute) getQueryConfigHandler().getAttribute(MultiTermRewriteMethodAttribute.class);
return attr.getMultiTermRewriteMethod();
}
public void setMultiFields(CharSequence[] fields) {
if (fields == null) {
fields = new CharSequence[0];
}
MultiFieldAttribute attr = (MultiFieldAttribute) getQueryConfigHandler().addAttribute(MultiFieldAttribute.class);
attr.setFields(fields);
}
/**
* Set the prefix length for fuzzy queries. Default is 0.
*
* @param fuzzyPrefixLength
* The fuzzyPrefixLength to set.
*/
public void setFuzzyPrefixLength(int fuzzyPrefixLength) {
FuzzyAttribute attr = (FuzzyAttribute) getQueryConfigHandler().addAttribute(FuzzyAttribute.class);
attr.setPrefixLength(fuzzyPrefixLength);
}
/**
* Set locale used by date range parsing.
*/
public void setLocale(Locale locale) {
LocaleAttribute attr = (LocaleAttribute) getQueryConfigHandler().addAttribute(LocaleAttribute.class);
attr.setLocale(locale);
}
/**
* Returns current locale, allowing access by subclasses.
*/
public Locale getLocale() {
LocaleAttribute attr = (LocaleAttribute) getQueryConfigHandler().addAttribute(LocaleAttribute.class);
return attr.getLocale();
}
/**
* Sets the default slop for phrases. If zero, then exact phrase matches are
* required. Default value is zero.
*/
public void setDefaultPhraseSlop(int defaultPhraseSlop) {
DefaultPhraseSlopAttribute attr = (DefaultPhraseSlopAttribute) getQueryConfigHandler().addAttribute(DefaultPhraseSlopAttribute.class);
attr.setDefaultPhraseSlop(defaultPhraseSlop);
}
public void setAnalyzer(Analyzer analyzer) {
AnalyzerAttribute attr= (AnalyzerAttribute) getQueryConfigHandler().getAttribute(AnalyzerAttribute.class);
attr.setAnalyzer(analyzer);
}
public Analyzer getAnalyzer() {
QueryConfigHandler config = this.getQueryConfigHandler();
if ( config.hasAttribute(AnalyzerAttribute.class)) {
AnalyzerAttribute attr= (AnalyzerAttribute) config.getAttribute(AnalyzerAttribute.class);
return attr.getAnalyzer();
}
return null;
}
/**
* @see #setAllowLeadingWildcard(boolean)
*/
public boolean getAllowLeadingWildcard() {
AllowLeadingWildcardAttribute attr = (AllowLeadingWildcardAttribute) getQueryConfigHandler().addAttribute(AllowLeadingWildcardAttribute.class);
return attr.isAllowLeadingWildcard();
}
/**
* Get the minimal similarity for fuzzy queries.
*/
public float getFuzzyMinSim() {
FuzzyAttribute attr = (FuzzyAttribute) getQueryConfigHandler().addAttribute(FuzzyAttribute.class);
return attr.getFuzzyMinSimilarity();
}
/**
* Get the prefix length for fuzzy queries.
*
* @return Returns the fuzzyPrefixLength.
*/
public int getFuzzyPrefixLength() {
FuzzyAttribute attr = (FuzzyAttribute) getQueryConfigHandler().addAttribute(FuzzyAttribute.class);
return attr.getPrefixLength();
}
/**
* Gets the default slop for phrases.
*/
public int getPhraseSlop() {
DefaultPhraseSlopAttribute attr = (DefaultPhraseSlopAttribute) getQueryConfigHandler().addAttribute(DefaultPhraseSlopAttribute.class);
return attr.getDefaultPhraseSlop();
}
/**
* Set the minimum similarity for fuzzy queries. Default is defined on
* {@link FuzzyQuery#defaultMinSimilarity}.
*/
public void setFuzzyMinSim(float fuzzyMinSim) {
FuzzyAttribute attr = (FuzzyAttribute) getQueryConfigHandler().addAttribute(FuzzyAttribute.class);
attr.setFuzzyMinSimilarity(fuzzyMinSim);
}
public void setFieldsBoost(Map<CharSequence, Float> boosts) {
FieldBoostMapAttribute attr = (FieldBoostMapAttribute) getQueryConfigHandler().addAttribute(FieldBoostMapAttribute.class);
attr.setFieldBoostMap(boosts);
}
public void setDateResolution(DateTools.Resolution dateResolution) {
DateResolutionAttribute attr = (DateResolutionAttribute) getQueryConfigHandler().addAttribute(DateResolutionAttribute.class);
attr.setDateResolution(dateResolution);
}
public void setDateResolution(Map<CharSequence, DateTools.Resolution> dateRes) {
FieldDateResolutionMapAttribute attr = (FieldDateResolutionMapAttribute) getQueryConfigHandler().addAttribute(FieldDateResolutionMapAttribute.class);
attr.setFieldDateResolutionMap(dateRes);
}
}

View File

@ -0,0 +1,189 @@
package org.apache.lucene.queryParser.original;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
/**
* This class defines utility methods to (help) parse query strings into
* {@link Query} objects.
*/
final public class QueryParserUtil {
/**
* Parses a query which searches on the fields specified.
* <p>
* If x fields are specified, this effectively constructs:
*
* <pre>
* &lt;code&gt;
* (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
* &lt;/code&gt;
* </pre>
*
* @param queries
* Queries strings to parse
* @param fields
* Fields to search on
* @param analyzer
* Analyzer to use
* @throws IllegalArgumentException
* if the length of the queries array differs from the length of the
* fields array
*/
public static Query parse(String[] queries, String[] fields, Analyzer analyzer)
throws QueryNodeException {
if (queries.length != fields.length)
throw new IllegalArgumentException("queries.length != fields.length");
BooleanQuery bQuery = new BooleanQuery();
OriginalQueryParserHelper qp = new OriginalQueryParserHelper();
qp.setAnalyzer(analyzer);
for (int i = 0; i < fields.length; i++) {
Query q = qp.parse(queries[i], fields[i]);
if (q != null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
bQuery.add(q, BooleanClause.Occur.SHOULD);
}
}
return bQuery;
}
/**
* Parses a query, searching on the fields specified. Use this if you need to
* specify certain fields as required, and others as prohibited.
* <p>
*
* <pre>
* Usage:
* &lt;code&gt;
* String[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
* BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
* BooleanClause.Occur.MUST,
* BooleanClause.Occur.MUST_NOT};
* MultiFieldQueryParser.parse(&quot;query&quot;, fields, flags, analyzer);
* &lt;/code&gt;
* </pre>
*<p>
* The code above would construct a query:
*
* <pre>
* &lt;code&gt;
* (filename:query) +(contents:query) -(description:query)
* &lt;/code&gt;
* </pre>
*
* @param query
* Query string to parse
* @param fields
* Fields to search on
* @param flags
* Flags describing the fields
* @param analyzer
* Analyzer to use
* @throws IllegalArgumentException
* if the length of the fields array differs from the length of the
* flags array
*/
public static Query parse(String query, String[] fields,
BooleanClause.Occur[] flags, Analyzer analyzer) throws QueryNodeException {
if (fields.length != flags.length)
throw new IllegalArgumentException("fields.length != flags.length");
BooleanQuery bQuery = new BooleanQuery();
OriginalQueryParserHelper qp = new OriginalQueryParserHelper();
qp.setAnalyzer(analyzer);
for (int i = 0; i < fields.length; i++) {
Query q = qp.parse(query, fields[i]);
if (q != null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
bQuery.add(q, flags[i]);
}
}
return bQuery;
}
/**
* Parses a query, searching on the fields specified. Use this if you need to
* specify certain fields as required, and others as prohibited.
* <p>
*
* <pre>
* Usage:
* &lt;code&gt;
* String[] query = {&quot;query1&quot;, &quot;query2&quot;, &quot;query3&quot;};
* String[] fields = {&quot;filename&quot;, &quot;contents&quot;, &quot;description&quot;};
* BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
* BooleanClause.Occur.MUST,
* BooleanClause.Occur.MUST_NOT};
* MultiFieldQueryParser.parse(query, fields, flags, analyzer);
* &lt;/code&gt;
* </pre>
*<p>
* The code above would construct a query:
*
* <pre>
* &lt;code&gt;
* (filename:query1) +(contents:query2) -(description:query3)
* &lt;/code&gt;
* </pre>
*
* @param queries
* Queries string to parse
* @param fields
* Fields to search on
* @param flags
* Flags describing the fields
* @param analyzer
* Analyzer to use
* @throws IllegalArgumentException
* if the length of the queries, fields, and flags array differ
*/
public static Query parse(String[] queries, String[] fields,
BooleanClause.Occur[] flags, Analyzer analyzer) throws QueryNodeException {
if (!(queries.length == fields.length && queries.length == flags.length))
throw new IllegalArgumentException(
"queries, fields, and flags array have have different length");
BooleanQuery bQuery = new BooleanQuery();
OriginalQueryParserHelper qp = new OriginalQueryParserHelper();
qp.setAnalyzer(analyzer);
for (int i = 0; i < fields.length; i++) {
Query q = qp.parse(queries[i], fields[i]);
if (q != null && // q never null, just being defensive
(!(q instanceof BooleanQuery) || ((BooleanQuery) q).getClauses().length > 0)) {
bQuery.add(q, flags[i]);
}
}
return bQuery;
}
/**
* Returns a String where those characters that TextParser expects to be
* escaped are escaped by a preceding <code>\</code>.
*/
public static String escape(String s) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// These characters are part of the query syntax and must be escaped
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')'
|| c == ':' || c == '^' || c == '[' || c == ']' || c == '\"'
|| c == '{' || c == '}' || c == '~' || c == '*' || c == '?'
|| c == '|' || c == '&') {
sb.append('\\');
}
sb.append(c);
}
return sb.toString();
}
}

View File

@ -0,0 +1,488 @@
package org.apache.lucene.queryParser.original;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.text.Collator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.DateTools.Resolution;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.config.FieldConfig;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.parser.SyntaxParser;
import org.apache.lucene.queryParser.core.processors.QueryNodeProcessor;
import org.apache.lucene.queryParser.original.builders.OriginalQueryBuilder;
import org.apache.lucene.queryParser.original.builders.OriginalQueryTreeBuilder;
import org.apache.lucene.queryParser.original.config.AllowLeadingWildcardAttribute;
import org.apache.lucene.queryParser.original.config.AnalyzerAttribute;
import org.apache.lucene.queryParser.original.config.MultiTermRewriteMethodAttribute;
import org.apache.lucene.queryParser.original.config.DateResolutionAttribute;
import org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute;
import org.apache.lucene.queryParser.original.config.DefaultPhraseSlopAttribute;
import org.apache.lucene.queryParser.original.config.LocaleAttribute;
import org.apache.lucene.queryParser.original.config.LowercaseExpandedTermsAttribute;
import org.apache.lucene.queryParser.original.config.OriginalQueryConfigHandler;
import org.apache.lucene.queryParser.original.config.PositionIncrementsAttribute;
import org.apache.lucene.queryParser.original.config.RangeCollatorAttribute;
import org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser;
import org.apache.lucene.queryParser.original.processors.OriginalQueryNodeProcessorPipeline;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Parameter;
/**
* This class performs the query parsing using the new query parser implementation, but
* keeps the old {@link QueryParser} API. <br/>
* <br/>
* This class should be used when the new query parser features are and
* the old {@link QueryParser} API are needed at the same time. <br/>
*
* @deprecated this class will be removed soon, it's a temporary class to be
* used along the transition from the old query parser to the new
* one
*/
public class QueryParserWrapper {
/**
* The default operator for parsing queries. Use
* {@link QueryParserWrapper#setDefaultOperator} to change it.
*/
static public final class Operator extends Parameter {
private static final long serialVersionUID = 3550299139196880290L;
private Operator(String name) {
super(name);
}
static public final Operator OR = new Operator("OR");
static public final Operator AND = new Operator("AND");
}
// the nested class:
/** Alternative form of QueryParser.Operator.AND */
public static final Operator AND_OPERATOR = Operator.AND;
/** Alternative form of QueryParser.Operator.OR */
public static final Operator OR_OPERATOR = Operator.OR;
/**
* Returns a String where those characters that QueryParser expects to be
* escaped are escaped by a preceding <code>\</code>.
*/
public static String escape(String s) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// These characters are part of the query syntax and must be escaped
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')'
|| c == ':' || c == '^' || c == '[' || c == ']' || c == '\"'
|| c == '{' || c == '}' || c == '~' || c == '*' || c == '?'
|| c == '|' || c == '&') {
sb.append('\\');
}
sb.append(c);
}
return sb.toString();
}
private SyntaxParser syntaxParser = new OriginalSyntaxParser();
private OriginalQueryConfigHandler config;
private OriginalQueryParserHelper qpHelper;
private QueryNodeProcessor processorPipeline;
private OriginalQueryBuilder builder = new OriginalQueryTreeBuilder();
private String defaultField;
public QueryParserWrapper(String defaultField, Analyzer analyzer) {
this.defaultField = defaultField;
this.qpHelper = new OriginalQueryParserHelper();
this.config = (OriginalQueryConfigHandler) qpHelper.getQueryConfigHandler();
this.qpHelper.setAnalyzer(analyzer);
this.processorPipeline = new OriginalQueryNodeProcessorPipeline(this.config);
}
OriginalQueryParserHelper getQueryParserHelper() {
return qpHelper;
}
public String getField() {
return this.defaultField;
}
public Analyzer getAnalyzer() {
if (this.config != null
&& this.config.hasAttribute(AnalyzerAttribute.class)) {
return ((AnalyzerAttribute) this.config
.getAttribute(AnalyzerAttribute.class)).getAnalyzer();
}
return null;
}
/**
* Sets the {@link OriginalQueryBuilder} used to generate a {@link Query} object
* from the parsed and processed query node tree.
*
* @param builder
* the builder
*/
public void setQueryBuilder(OriginalQueryBuilder builder) {
this.builder = builder;
}
/**
* Sets the {@link QueryNodeProcessor} used to process the query node tree
* generated by the
* {@link org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser}.
*
* @param processor
* the processor
*/
public void setQueryProcessor(QueryNodeProcessor processor) {
this.processorPipeline = processor;
this.processorPipeline.setQueryConfigHandler(this.config);
}
/**
* Sets the {@link QueryConfigHandler} used by the {@link QueryNodeProcessor}
* set to this object.
*
* @param queryConfig
* the query config handler
*/
public void setQueryConfig(OriginalQueryConfigHandler queryConfig) {
this.config = queryConfig;
if (this.processorPipeline != null) {
this.processorPipeline.setQueryConfigHandler(this.config);
}
}
/**
* Returns the query config handler used by this query parser
*
* @return the query config handler
*/
public QueryConfigHandler getQueryConfigHandler() {
return this.config;
}
/**
* Returns {@link QueryNodeProcessor} used to process the query node tree
* generated by the
* {@link org.apache.lucene.queryParser.original.parser.OriginalSyntaxParser}.
*
* @return the query processor
*/
public QueryNodeProcessor getQueryProcessor() {
return this.processorPipeline;
}
public ParseException generateParseException() {
return null;
}
public boolean getAllowLeadingWildcard() {
if (this.config != null
&& this.config.hasAttribute(AllowLeadingWildcardAttribute.class)) {
return ((AllowLeadingWildcardAttribute) this.config
.getAttribute(AllowLeadingWildcardAttribute.class))
.isAllowLeadingWildcard();
}
return false;
}
public MultiTermQuery.RewriteMethod getMultiTermRewriteMethod() {
if (this.config != null
&& this.config.hasAttribute(MultiTermRewriteMethodAttribute.class)) {
return ((MultiTermRewriteMethodAttribute) this.config
.getAttribute(MultiTermRewriteMethodAttribute.class))
.getMultiTermRewriteMethod();
}
return MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
}
public Resolution getDateResolution(String fieldName) {
if (this.config != null) {
FieldConfig fieldConfig = this.config.getFieldConfig(fieldName);
if (fieldConfig != null) {
if (this.config.hasAttribute(DateResolutionAttribute.class)) {
return ((DateResolutionAttribute) this.config
.getAttribute(DateResolutionAttribute.class)).getDateResolution();
}
}
}
return null;
}
public boolean getEnablePositionIncrements() {
if (this.config != null
&& this.config.hasAttribute(PositionIncrementsAttribute.class)) {
return ((PositionIncrementsAttribute) this.config
.getAttribute(PositionIncrementsAttribute.class))
.isPositionIncrementsEnabled();
}
return false;
}
public float getFuzzyMinSim() {
return FuzzyQuery.defaultMinSimilarity;
}
public int getFuzzyPrefixLength() {
return FuzzyQuery.defaultPrefixLength;
}
public Locale getLocale() {
if (this.config != null && this.config.hasAttribute(LocaleAttribute.class)) {
return ((LocaleAttribute) this.config.getAttribute(LocaleAttribute.class))
.getLocale();
}
return Locale.getDefault();
}
public boolean getLowercaseExpandedTerms() {
if (this.config != null
&& this.config.hasAttribute(LowercaseExpandedTermsAttribute.class)) {
return ((LowercaseExpandedTermsAttribute) this.config
.getAttribute(LowercaseExpandedTermsAttribute.class))
.isLowercaseExpandedTerms();
}
return true;
}
public int getPhraseSlop() {
if (this.config != null
&& this.config.hasAttribute(AllowLeadingWildcardAttribute.class)) {
return ((DefaultPhraseSlopAttribute) this.config
.getAttribute(DefaultPhraseSlopAttribute.class))
.getDefaultPhraseSlop();
}
return 0;
}
public Collator getRangeCollator() {
if (this.config != null
&& this.config.hasAttribute(RangeCollatorAttribute.class)) {
return ((RangeCollatorAttribute) this.config
.getAttribute(RangeCollatorAttribute.class)).getRangeCollator();
}
return null;
}
public boolean getUseOldRangeQuery() {
if (getMultiTermRewriteMethod() == MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE) {
return true;
} else {
return false;
}
}
public Query parse(String query) throws ParseException {
try {
QueryNode queryTree = this.syntaxParser.parse(query, getField());
queryTree = this.processorPipeline.process(queryTree);
return (Query) this.builder.build(queryTree);
} catch (QueryNodeException e) {
throw new ParseException("parse exception");
}
}
public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
this.qpHelper.setAllowLeadingWildcard(allowLeadingWildcard);
}
public void setMultiTermRewriteMethod(MultiTermQuery.RewriteMethod method) {
this.qpHelper.setMultiTermRewriteMethod(method);
}
public void setDateResolution(Resolution dateResolution) {
this.qpHelper.setDateResolution(dateResolution);
}
private Map<CharSequence, DateTools.Resolution> dateRes = new HashMap<CharSequence, DateTools.Resolution>();
public void setDateResolution(String fieldName, Resolution dateResolution) {
dateRes.put(fieldName, dateResolution);
this.qpHelper.setDateResolution(dateRes);
}
public void setDefaultOperator(Operator op) {
this.qpHelper
.setDefaultOperator(OR_OPERATOR.equals(op) ? org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute.Operator.OR
: org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute.Operator.AND);
}
public Operator getDefaultOperator() {
if (this.config != null
&& this.config.hasAttribute(DefaultOperatorAttribute.class)) {
return (((DefaultOperatorAttribute) this.config
.getAttribute(DefaultOperatorAttribute.class)).getOperator() == org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute.Operator.AND) ? AND_OPERATOR
: OR_OPERATOR;
}
return OR_OPERATOR;
}
public void setEnablePositionIncrements(boolean enable) {
this.qpHelper.setEnablePositionIncrements(enable);
}
public void setFuzzyMinSim(float fuzzyMinSim) {
// TODO Auto-generated method stub
}
public void setFuzzyPrefixLength(int fuzzyPrefixLength) {
// TODO Auto-generated method stub
}
public void setLocale(Locale locale) {
this.qpHelper.setLocale(locale);
}
public void setLowercaseExpandedTerms(boolean lowercaseExpandedTerms) {
this.qpHelper.setLowercaseExpandedTerms(lowercaseExpandedTerms);
}
public void setPhraseSlop(int phraseSlop) {
this.qpHelper.setDefaultPhraseSlop(phraseSlop);
}
public void setRangeCollator(Collator rc) {
this.qpHelper.setRangeCollator(rc);
}
public void setUseOldRangeQuery(boolean useOldRangeQuery) {
if (useOldRangeQuery) {
setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
} else {
setMultiTermRewriteMethod(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
}
}
protected Query getPrefixQuery(String field, String termStr)
throws ParseException {
throw new UnsupportedOperationException();
}
protected Query getWildcardQuery(String field, String termStr)
throws ParseException {
throw new UnsupportedOperationException();
}
protected Query getFuzzyQuery(String field, String termStr,
float minSimilarity) throws ParseException {
throw new UnsupportedOperationException();
}
/**
* @exception ParseException
* throw in overridden method to disallow
*/
protected Query getFieldQuery(String field, String queryText)
throws ParseException {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
protected Query getBooleanQuery(List clauses, boolean disableCoord)
throws ParseException {
throw new UnsupportedOperationException();
}
/**
* Base implementation delegates to {@link #getFieldQuery(String,String)}.
* This method may be overridden, for example, to return a SpanNearQuery
* instead of a PhraseQuery.
*
* @exception ParseException
* throw in overridden method to disallow
*/
protected Query getFieldQuery(String field, String queryText, int slop)
throws ParseException {
throw new UnsupportedOperationException();
}
/**
* @exception ParseException
* throw in overridden method to disallow
*/
protected Query getRangeQuery(String field, String part1, String part2,
boolean inclusive) throws ParseException {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,77 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.AnyQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.BooleanQuery.TooManyClauses;
public class AnyQueryNodeBuilder implements OriginalQueryBuilder {
public AnyQueryNodeBuilder() {
// empty constructor
}
public BooleanQuery build(QueryNode queryNode) throws QueryNodeException {
AnyQueryNode andNode = (AnyQueryNode) queryNode;
BooleanQuery bQuery = new BooleanQuery();
List<QueryNode> children = andNode.getChildren();
if (children != null) {
for (QueryNode child : children) {
Object obj = child.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
if (obj != null) {
Query query = (Query) obj;
try {
bQuery.add(query, BooleanClause.Occur.SHOULD);
} catch (TooManyClauses ex) {
throw new QueryNodeException(new MessageImpl(
/*
* IQQQ.Q0028E_TOO_MANY_BOOLEAN_CLAUSES,
* BooleanQuery.getMaxClauseCount()
*/QueryParserMessages.EMPTY_MESSAGE), ex);
}
}
}
}
bQuery.setMinimumNumberShouldMatch(andNode.getMinimumMatchingElements());
return bQuery;
}
}

View File

@ -0,0 +1,110 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.BooleanQueryNode;
import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.original.parser.EscapeQuerySyntaxImpl;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.BooleanQuery.TooManyClauses;
/**
* Builds a {@link BooleanQuery} object from a {@link BooleanQueryNode} object.
* Every children in the {@link BooleanQueryNode} object must be already tagged
* using {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID} with a {@link Query}
* object. <br/>
* <br/>
* It takes in consideration if the children is a {@link ModifierQueryNode} to
* define the {@link BooleanClause}.
*/
public class BooleanQueryNodeBuilder implements OriginalQueryBuilder {
public BooleanQueryNodeBuilder() {
// empty constructor
}
public BooleanQuery build(QueryNode queryNode) throws QueryNodeException {
BooleanQueryNode booleanNode = (BooleanQueryNode) queryNode;
BooleanQuery bQuery = new BooleanQuery();
List<QueryNode> children = booleanNode.getChildren();
if (children != null) {
for (QueryNode child : children) {
Object obj = child.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
if (obj != null) {
Query query = (Query) obj;
try {
bQuery.add(query, getModifierValue(child));
} catch (TooManyClauses ex) {
throw new QueryNodeException(new MessageImpl(
QueryParserMessages.TOO_MANY_BOOLEAN_CLAUSES, BooleanQuery
.getMaxClauseCount(), queryNode
.toQueryString(new EscapeQuerySyntaxImpl())), ex);
}
}
}
}
return bQuery;
}
private static BooleanClause.Occur getModifierValue(QueryNode node)
throws QueryNodeException {
if (node instanceof ModifierQueryNode) {
ModifierQueryNode mNode = ((ModifierQueryNode) node);
switch (mNode.getModifier()) {
case MOD_REQ:
return BooleanClause.Occur.MUST;
case MOD_NOT:
return BooleanClause.Occur.MUST_NOT;
case MOD_NONE:
return BooleanClause.Occur.SHOULD;
}
}
return BooleanClause.Occur.SHOULD;
}
}

View File

@ -0,0 +1,54 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.BoostQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.Query;
/**
* This builder basically reads the {@link Query} object set on the
* {@link BoostQueryNode} child using
* {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID} and applies the boost value
* defined in the {@link BoostQueryNode}.
*/
public class BoostQueryNodeBuilder implements OriginalQueryBuilder {
public BoostQueryNodeBuilder() {
// empty constructor
}
public Query build(QueryNode queryNode) throws QueryNodeException {
BoostQueryNode boostNode = (BoostQueryNode) queryNode;
QueryNode child = boostNode.getChild();
if (child == null) {
return null;
}
Query query = (Query) child
.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
query.setBoost(boostNode.getValue());
return query;
}
}

View File

@ -0,0 +1,43 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.FieldQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.TermQuery;
/**
* Builds a {@link TermQuery} object from a {@link FieldQueryNode} object.
*/
public class FieldQueryNodeBuilder implements OriginalQueryBuilder {
public FieldQueryNodeBuilder() {
// empty constructor
}
public TermQuery build(QueryNode queryNode) throws QueryNodeException {
FieldQueryNode fieldNode = (FieldQueryNode) queryNode;
return new TermQuery(new Term(fieldNode.getFieldAsString(), fieldNode
.getTextAsString()));
}
}

View File

@ -0,0 +1,44 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.FuzzyQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.FuzzyQuery;
/**
* Builds a {@link FuzzyQuery} object from a {@link FuzzyQueryNode} object.
*/
public class FuzzyQueryNodeBuilder implements OriginalQueryBuilder {
public FuzzyQueryNodeBuilder() {
// empty constructor
}
public FuzzyQuery build(QueryNode queryNode) throws QueryNodeException {
FuzzyQueryNode fuzzyNode = (FuzzyQueryNode) queryNode;
return new FuzzyQuery(new Term(fuzzyNode.getFieldAsString(), fuzzyNode
.getTextAsString()), fuzzyNode.getSimilarity(), fuzzyNode
.getPrefixLength());
}
}

View File

@ -0,0 +1,45 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.GroupQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.Query;
/**
* Builds no object, it only returns the {@link Query} object set on the
* {@link GroupQueryNode} object using a
* {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID} tag.
*/
public class GroupQueryNodeBuilder implements OriginalQueryBuilder {
public GroupQueryNodeBuilder() {
// empty constructor
}
public Query build(QueryNode queryNode) throws QueryNodeException {
GroupQueryNode groupNode = (GroupQueryNode) queryNode;
return (Query) (groupNode).getChild().getTag(
QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
}
}

View File

@ -0,0 +1,52 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.MatchAllDocsQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.original.parser.EscapeQuerySyntaxImpl;
import org.apache.lucene.search.MatchAllDocsQuery;
/**
* Builds a {@link MatchAllDocsQuery} object from a
* {@link MatchAllDocsQueryNode} object.
*/
public class MatchAllDocsQueryNodeBuilder implements OriginalQueryBuilder {
public MatchAllDocsQueryNodeBuilder() {
// empty constructor
}
public MatchAllDocsQuery build(QueryNode queryNode) throws QueryNodeException {
// validates node
if (!(queryNode instanceof MatchAllDocsQueryNode)) {
throw new QueryNodeException(new MessageImpl(
QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, queryNode
.toQueryString(new EscapeQuerySyntaxImpl()), queryNode.getClass()
.getName()));
}
return new MatchAllDocsQuery();
}
}

View File

@ -0,0 +1,52 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.MatchNoDocsQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.original.parser.EscapeQuerySyntaxImpl;
import org.apache.lucene.search.BooleanQuery;
/**
* Builds an empty {@link BooleanQuery} object from a
* {@link MatchNoDocsQueryNode} object.
*/
public class MatchNoDocsQueryNodeBuilder implements OriginalQueryBuilder {
public MatchNoDocsQueryNodeBuilder() {
// empty constructor
}
public BooleanQuery build(QueryNode queryNode) throws QueryNodeException {
// validates node
if (!(queryNode instanceof MatchNoDocsQueryNode)) {
throw new QueryNodeException(new MessageImpl(
QueryParserMessages.LUCENE_QUERY_CONVERSION_ERROR, queryNode
.toQueryString(new EscapeQuerySyntaxImpl()), queryNode.getClass()
.getName()));
}
return new BooleanQuery();
}
}

View File

@ -0,0 +1,45 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.Query;
/**
* Builds no object, it only returns the {@link Query} object set on the
* {@link ModifierQueryNode} object using a
* {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID} tag.
*/
public class ModifierQueryNodeBuilder implements OriginalQueryBuilder {
public ModifierQueryNodeBuilder() {
// empty constructor
}
public Query build(QueryNode queryNode) throws QueryNodeException {
ModifierQueryNode modifierNode = (ModifierQueryNode) queryNode;
return (Query) (modifierNode).getChild().getTag(
QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
}
}

View File

@ -0,0 +1,84 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.FieldQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.original.nodes.MultiPhraseQueryNode;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.TermQuery;
/**
* Builds a {@link MultiPhraseQuery} object from a {@link MultiPhraseQueryNode}
* object.
*/
public class MultiPhraseQueryNodeBuilder implements OriginalQueryBuilder {
public MultiPhraseQueryNodeBuilder() {
// empty constructor
}
public MultiPhraseQuery build(QueryNode queryNode) throws QueryNodeException {
MultiPhraseQueryNode phraseNode = (MultiPhraseQueryNode) queryNode;
MultiPhraseQuery phraseQuery = new MultiPhraseQuery();
List<QueryNode> children = phraseNode.getChildren();
if (children != null) {
TreeMap<Integer, List<Term>> positionTermMap = new TreeMap<Integer, List<Term>>();
for (QueryNode child : children) {
FieldQueryNode termNode = (FieldQueryNode) child;
TermQuery termQuery = (TermQuery) termNode
.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
List<Term> termList = positionTermMap.get(termNode
.getPositionIncrement());
if (termList == null) {
termList = new LinkedList<Term>();
positionTermMap.put(termNode.getPositionIncrement(), termList);
}
termList.add(termQuery.getTerm());
}
for (int positionIncrement : positionTermMap.keySet()) {
List<Term> termList = positionTermMap.get(positionIncrement);
phraseQuery.add(termList.toArray(new Term[termList.size()]),
positionIncrement);
}
}
return phraseQuery;
}
}

View File

@ -0,0 +1,109 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.messages.MessageImpl;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.messages.QueryParserMessages;
import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode.Modifier;
import org.apache.lucene.queryParser.original.nodes.OriginalBooleanQueryNode;
import org.apache.lucene.queryParser.original.parser.EscapeQuerySyntaxImpl;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Similarity;
import org.apache.lucene.search.BooleanQuery.TooManyClauses;
/**
* This builder does the same as the {@link BooleanQueryNodeBuilder}, but this
* considers if the built {@link BooleanQuery} should have its coord disabled or
* not. <br/>
*
* @see BooleanQueryNodeBuilder
* @see BooleanQuery
* @see Similarity#coord(int, int)
*/
public class OriginalBooleanQueryNodeBuilder implements OriginalQueryBuilder {
public OriginalBooleanQueryNodeBuilder() {
// empty constructor
}
public BooleanQuery build(QueryNode queryNode) throws QueryNodeException {
OriginalBooleanQueryNode booleanNode = (OriginalBooleanQueryNode) queryNode;
BooleanQuery bQuery = new BooleanQuery(booleanNode.isDisableCoord());
List<QueryNode> children = booleanNode.getChildren();
if (children != null) {
for (QueryNode child : children) {
Object obj = child.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
if (obj != null) {
Query query = (Query) obj;
try {
bQuery.add(query, getModifierValue(child));
} catch (TooManyClauses ex) {
throw new QueryNodeException(new MessageImpl(
QueryParserMessages.TOO_MANY_BOOLEAN_CLAUSES, BooleanQuery
.getMaxClauseCount(), queryNode
.toQueryString(new EscapeQuerySyntaxImpl())), ex);
}
}
}
}
return bQuery;
}
private static BooleanClause.Occur getModifierValue(QueryNode node)
throws QueryNodeException {
if (node instanceof ModifierQueryNode) {
ModifierQueryNode mNode = ((ModifierQueryNode) node);
Modifier modifier = mNode.getModifier();
if (Modifier.MOD_NONE.equals(modifier)) {
return BooleanClause.Occur.SHOULD;
} else if (Modifier.MOD_NOT.equals(modifier)) {
return BooleanClause.Occur.MUST_NOT;
} else {
return BooleanClause.Occur.MUST;
}
}
return BooleanClause.Occur.SHOULD;
}
}

View File

@ -0,0 +1,37 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryBuilder;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.Query;
/**
* This interface should be implemented by every class that wants to build
* {@link Query} objects from {@link QueryNode} objects. <br/>
*
* @see QueryBuilder
* @see QueryTreeBuilder
*/
public interface OriginalQueryBuilder extends QueryBuilder {
public Query build(QueryNode queryNode) throws QueryNodeException;
}

View File

@ -0,0 +1,78 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.BooleanQueryNode;
import org.apache.lucene.queryParser.core.nodes.BoostQueryNode;
import org.apache.lucene.queryParser.core.nodes.FieldQueryNode;
import org.apache.lucene.queryParser.core.nodes.FuzzyQueryNode;
import org.apache.lucene.queryParser.core.nodes.GroupQueryNode;
import org.apache.lucene.queryParser.core.nodes.MatchAllDocsQueryNode;
import org.apache.lucene.queryParser.core.nodes.MatchNoDocsQueryNode;
import org.apache.lucene.queryParser.core.nodes.ModifierQueryNode;
import org.apache.lucene.queryParser.core.nodes.PrefixWildcardQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.SlopQueryNode;
import org.apache.lucene.queryParser.core.nodes.TokenizedPhraseQueryNode;
import org.apache.lucene.queryParser.core.nodes.WildcardQueryNode;
import org.apache.lucene.queryParser.original.nodes.OriginalBooleanQueryNode;
import org.apache.lucene.queryParser.original.nodes.MultiPhraseQueryNode;
import org.apache.lucene.queryParser.original.nodes.RangeQueryNode;
import org.apache.lucene.queryParser.original.processors.OriginalQueryNodeProcessorPipeline;
import org.apache.lucene.search.Query;
/**
* This query tree builder only defines the necessary map to build a
* {@link Query} tree object. It should be used to generate a {@link Query} tree
* object from a query node tree processed by a
* {@link OriginalQueryNodeProcessorPipeline}. <br/>
*
* @see QueryTreeBuilder
* @see OriginalQueryNodeProcessorPipeline
*/
public class OriginalQueryTreeBuilder extends QueryTreeBuilder implements
OriginalQueryBuilder {
public OriginalQueryTreeBuilder() {
setBuilder(GroupQueryNode.class, new GroupQueryNodeBuilder());
setBuilder(FieldQueryNode.class, new FieldQueryNodeBuilder());
setBuilder(BooleanQueryNode.class, new BooleanQueryNodeBuilder());
setBuilder(FuzzyQueryNode.class, new FuzzyQueryNodeBuilder());
setBuilder(BoostQueryNode.class, new BoostQueryNodeBuilder());
setBuilder(ModifierQueryNode.class, new ModifierQueryNodeBuilder());
setBuilder(WildcardQueryNode.class, new WildcardQueryNodeBuilder());
setBuilder(TokenizedPhraseQueryNode.class, new PhraseQueryNodeBuilder());
setBuilder(MatchNoDocsQueryNode.class, new MatchNoDocsQueryNodeBuilder());
setBuilder(PrefixWildcardQueryNode.class,
new PrefixWildcardQueryNodeBuilder());
setBuilder(RangeQueryNode.class, new RangeQueryNodeBuilder());
setBuilder(SlopQueryNode.class, new SlopQueryNodeBuilder());
setBuilder(OriginalBooleanQueryNode.class,
new OriginalBooleanQueryNodeBuilder());
setBuilder(MultiPhraseQueryNode.class, new MultiPhraseQueryNodeBuilder());
setBuilder(MatchAllDocsQueryNode.class, new MatchAllDocsQueryNodeBuilder());
}
public Query build(QueryNode queryNode) throws QueryNodeException {
return (Query) super.build(queryNode);
}
}

View File

@ -0,0 +1,64 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.FieldQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.TokenizedPhraseQueryNode;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.TermQuery;
/**
* Builds a {@link PhraseQuery} object from a {@link TokenizedPhraseQueryNode}
* object.
*/
public class PhraseQueryNodeBuilder implements OriginalQueryBuilder {
public PhraseQueryNodeBuilder() {
// empty constructor
}
public PhraseQuery build(QueryNode queryNode) throws QueryNodeException {
TokenizedPhraseQueryNode phraseNode = (TokenizedPhraseQueryNode) queryNode;
PhraseQuery phraseQuery = new PhraseQuery();
List<QueryNode> children = phraseNode.getChildren();
if (children != null) {
for (QueryNode child : children) {
TermQuery termQuery = (TermQuery) child
.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
FieldQueryNode termNode = (FieldQueryNode) child;
phraseQuery.add(termQuery.getTerm(), termNode.getPositionIncrement());
}
}
return phraseQuery;
}
}

View File

@ -0,0 +1,44 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.PrefixWildcardQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.search.PrefixQuery;
/**
* Builds a {@link PrefixQuery} object from a {@link PrefixWildcardQueryNode}
* object.
*/
public class PrefixWildcardQueryNodeBuilder implements OriginalQueryBuilder {
public PrefixWildcardQueryNodeBuilder() {
// empty constructor
}
public PrefixQuery build(QueryNode queryNode) throws QueryNodeException {
PrefixWildcardQueryNode wildcardNode = (PrefixWildcardQueryNode) queryNode;
return new PrefixQuery(new Term(wildcardNode.getFieldAsString(),
wildcardNode.getTextAsString()));
}
}

View File

@ -0,0 +1,63 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.ParametricQueryNode;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.ParametricQueryNode.CompareOperator;
import org.apache.lucene.queryParser.original.nodes.RangeQueryNode;
import org.apache.lucene.search.TermRangeQuery;
/**
* Builds a {@link TermRangeQuery} object from a {@link RangeQueryNode} object.
*/
public class RangeQueryNodeBuilder implements OriginalQueryBuilder {
public RangeQueryNodeBuilder() {
// empty constructor
}
public TermRangeQuery build(QueryNode queryNode) throws QueryNodeException {
RangeQueryNode rangeNode = (RangeQueryNode) queryNode;
ParametricQueryNode upper = rangeNode.getUpperBound();
ParametricQueryNode lower = rangeNode.getLowerBound();
boolean lowerInclusive = false;
boolean upperInclusive = false;
if (upper.getOperator() == CompareOperator.LE) {
upperInclusive = true;
}
if (lower.getOperator() == CompareOperator.GE) {
lowerInclusive = true;
}
String field = rangeNode.getField().toString();
TermRangeQuery rangeQuery = new TermRangeQuery(field, lower
.getTextAsString(), upper.getTextAsString(), lowerInclusive,
upperInclusive, rangeNode.getCollator());
rangeQuery.setRewriteMethod(rangeNode.getMultiTermRewriteMethod());
return rangeQuery;
}
}

View File

@ -0,0 +1,57 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.SlopQueryNode;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
/**
* This builder basically reads the {@link Query} object set on the
* {@link SlopQueryNode} child using
* {@link QueryTreeBuilder#QUERY_TREE_BUILDER_TAGID} and applies the slop value
* defined in the {@link SlopQueryNode}.
*/
public class SlopQueryNodeBuilder implements OriginalQueryBuilder {
public SlopQueryNodeBuilder() {
// empty constructor
}
public Query build(QueryNode queryNode) throws QueryNodeException {
SlopQueryNode phraseSlopNode = (SlopQueryNode) queryNode;
Query query = (Query) phraseSlopNode.getChild().getTag(
QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
if (query instanceof PhraseQuery) {
((PhraseQuery) query).setSlop(phraseSlopNode.getValue());
} else {
((MultiPhraseQuery) query).setSlop(phraseSlopNode.getValue());
}
return query;
}
}

View File

@ -0,0 +1,44 @@
package org.apache.lucene.queryParser.original.builders;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.core.QueryNodeException;
import org.apache.lucene.queryParser.core.nodes.QueryNode;
import org.apache.lucene.queryParser.core.nodes.WildcardQueryNode;
import org.apache.lucene.search.WildcardQuery;
/**
* Builds a {@link WildcardQuery} object from a {@link WildcardQueryNode}
* object.
*/
public class WildcardQueryNodeBuilder implements OriginalQueryBuilder {
public WildcardQueryNodeBuilder() {
// empty constructor
}
public WildcardQuery build(QueryNode queryNode) throws QueryNodeException {
WildcardQueryNode wildcardNode = (WildcardQueryNode) queryNode;
return new WildcardQuery(new Term(wildcardNode.getFieldAsString(),
wildcardNode.getTextAsString()));
}
}

View File

@ -0,0 +1,35 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<h2>Original Lucene Query Node Builders</h2>
<p>
The package org.apache.lucene.queryParser.original.builders contains all the builders needed
to build a Lucene Query object from a query node tree. These builders expect the query node tree was
already processed by the {@link org.apache.lucene.queryParser.original.processors.OriginalQueryNodeProcessorPipeline}.
</p>
<p>
{@link org.apache.lucene.queryParser.original.builders.OriginalQueryTreeBuilder} is a builder that already contains a defined map that maps each QueryNode object
with its respective builder.
</p>
</body>
</html>

View File

@ -0,0 +1,33 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.AllowLeadingWildcardProcessor;
import org.apache.lucene.util.Attribute;
/**
* This attribute is used by {@link AllowLeadingWildcardProcessor} processor and
* must be defined in the {@link QueryConfigHandler}. It basically tells the
* processor if it should allow leading wildcard. <br/>
*
*/
public interface AllowLeadingWildcardAttribute extends Attribute {
public void setAllowLeadingWildcard(boolean allowLeadingWildcard);
public boolean isAllowLeadingWildcard();
}

View File

@ -0,0 +1,80 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.AllowLeadingWildcardProcessor;
import org.apache.lucene.util.AttributeImpl;
/**
* This attribute is used by {@link AllowLeadingWildcardProcessor} processor and
* must be defined in the {@link QueryConfigHandler}. It basically tells the
* processor if it should allow leading wildcard. <br/>
*
* @see org.apache.lucene.queryParser.original.config.AllowLeadingWildcardAttribute
*/
public class AllowLeadingWildcardAttributeImpl extends AttributeImpl
implements AllowLeadingWildcardAttribute {
private static final long serialVersionUID = -2804763012723049527L;
private boolean allowLeadingWildcard = true;
public AllowLeadingWildcardAttributeImpl() {
allowLeadingWildcard = true; // default in 2.4
}
public void setAllowLeadingWildcard(boolean allowLeadingWildcard) {
this.allowLeadingWildcard = allowLeadingWildcard;
}
public boolean isAllowLeadingWildcard() {
return this.allowLeadingWildcard;
}
public void clear() {
throw new UnsupportedOperationException();
}
public void copyTo(AttributeImpl target) {
throw new UnsupportedOperationException();
}
public boolean equals(Object other) {
if (other instanceof AllowLeadingWildcardAttributeImpl
&& ((AllowLeadingWildcardAttributeImpl) other).allowLeadingWildcard == this.allowLeadingWildcard) {
return true;
}
return false;
}
public int hashCode() {
return this.allowLeadingWildcard ? -1 : Integer.MAX_VALUE;
}
public String toString() {
return "<allowLeadingWildcard allowLeadingWildcard="
+ this.allowLeadingWildcard + "/>";
}
}

View File

@ -0,0 +1,35 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.AnalyzerQueryNodeProcessor;
import org.apache.lucene.util.Attribute;
/**
* This attribute is used by {@link AnalyzerQueryNodeProcessor} processor and
* must be defined in the {@link QueryConfigHandler}. It provides to this
* processor the {@link Analyzer}, if there is one, which will be used to
* analyze the query terms. <br/>
*
*/
public interface AnalyzerAttribute extends Attribute {
public void setAnalyzer(Analyzer analyzer);
public Analyzer getAnalyzer();
}

View File

@ -0,0 +1,87 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.AnalyzerQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
/**
* This attribute is used by {@link AnalyzerQueryNodeProcessor} processor and
* must be defined in the {@link QueryConfigHandler}. It provides to this
* processor the {@link Analyzer}, if there is one, which will be used to
* analyze the query terms. <br/>
*
* @see org.apache.lucene.queryParser.original.config.AnalyzerAttribute
*/
public class AnalyzerAttributeImpl extends AttributeImpl
implements AnalyzerAttribute {
private static final long serialVersionUID = -6804760312723049526L;
private Analyzer analyzer;
public AnalyzerAttributeImpl() {
analyzer = null; //default value 2.4
}
public void setAnalyzer(Analyzer analyzer) {
this.analyzer = analyzer;
}
public Analyzer getAnalyzer() {
return this.analyzer;
}
public void clear() {
throw new UnsupportedOperationException();
}
public void copyTo(AttributeImpl target) {
throw new UnsupportedOperationException();
}
public boolean equals(Object other) {
if (other instanceof AnalyzerAttributeImpl) {
AnalyzerAttributeImpl analyzerAttr = (AnalyzerAttributeImpl) other;
if (analyzerAttr.analyzer == this.analyzer
|| (this.analyzer != null && analyzerAttr.analyzer != null && this.analyzer
.equals(analyzerAttr.analyzer))) {
return true;
}
}
return false;
}
public int hashCode() {
return (this.analyzer == null) ? 0 : this.analyzer.hashCode();
}
public String toString() {
return "<analyzerAttribute analyzer='" + this.analyzer + "'/>";
}
}

View File

@ -0,0 +1,35 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.FieldConfig;
import org.apache.lucene.queryParser.original.processors.MultiFieldQueryNodeProcessor;
import org.apache.lucene.util.Attribute;
/**
* This attribute is used by {@link MultiFieldQueryNodeProcessor} processor and
* it should be defined in a {@link FieldConfig}. This processor uses this
* attribute to define which boost a specific field should have when none is
* defined to it. <br/>
* <br/>
*
*/
public interface BoostAttribute extends Attribute {
public void setBoost(float boost);
public float getBoost();
}

View File

@ -0,0 +1,81 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.FieldConfig;
import org.apache.lucene.queryParser.original.processors.MultiFieldQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
/**
* This attribute is used by {@link MultiFieldQueryNodeProcessor} processor and
* it should be defined in a {@link FieldConfig}. This processor uses this
* attribute to define which boost a specific field should have when none is
* defined to it. <br/>
* <br/>
*
* @see org.apache.lucene.queryParser.original.config.BoostAttribute
*/
public class BoostAttributeImpl extends AttributeImpl
implements BoostAttribute {
private static final long serialVersionUID = -2104763012523049527L;
private float boost = 1.0f;
public BoostAttributeImpl() {
// empty constructor
}
public void setBoost(float boost) {
this.boost = boost;
}
public float getBoost() {
return this.boost;
}
public void clear() {
throw new UnsupportedOperationException();
}
public void copyTo(AttributeImpl target) {
throw new UnsupportedOperationException();
}
public boolean equals(Object other) {
if (other instanceof BoostAttributeImpl && other != null
&& ((BoostAttributeImpl) other).boost == this.boost) {
return true;
}
return false;
}
public int hashCode() {
return Float.valueOf(this.boost).hashCode();
}
public String toString() {
return "<boostAttribute boost=" + this.boost + "/>";
}
}

View File

@ -0,0 +1,43 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.DateTools.Resolution;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.nodes.RangeQueryNode;
import org.apache.lucene.queryParser.original.processors.ParametricRangeQueryNodeProcessor;
import org.apache.lucene.util.Attribute;
/**
* This attribute is used by {@link ParametricRangeQueryNodeProcessor} processor
* and must be defined in the {@link QueryConfigHandler}. This attribute tells
* the processor which {@link Resolution} to use when parsing the date. <br/>
*
*/
public interface DateResolutionAttribute extends Attribute {
/**
* Sets the default date resolution used by {@link RangeQueryNode}s for
* fields for which no specific date resolutions has been set. Field
* specific resolutions can be set with
*
* @param dateResolution the default date resolution to set
*/
public void setDateResolution(DateTools.Resolution dateResolution);
public DateTools.Resolution getDateResolution();
}

View File

@ -0,0 +1,87 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.DateTools.Resolution;
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.ParametricRangeQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
/**
* This attribute is used by {@link ParametricRangeQueryNodeProcessor} processor
* and must be defined in the {@link QueryConfigHandler}. This attribute tells
* the processor which {@link Resolution} to use when parsing the date. <br/>
*
* @see org.apache.lucene.queryParser.original.config.DateResolutionAttribute
*/
public class DateResolutionAttributeImpl extends AttributeImpl
implements DateResolutionAttribute {
private static final long serialVersionUID = -6804360312723049526L;
private DateTools.Resolution dateResolution = null;
public DateResolutionAttributeImpl() {
dateResolution = null; //default in 2.4
}
public void setDateResolution(DateTools.Resolution dateResolution) {
this.dateResolution = dateResolution;
}
public DateTools.Resolution getDateResolution() {
return this.dateResolution;
}
public void clear() {
throw new UnsupportedOperationException();
}
public void copyTo(AttributeImpl target) {
throw new UnsupportedOperationException();
}
public boolean equals(Object other) {
if (other instanceof DateResolutionAttributeImpl) {
DateResolutionAttributeImpl dateResAttr = (DateResolutionAttributeImpl) other;
if (dateResAttr.getDateResolution() == getDateResolution()
|| dateResAttr.getDateResolution().equals(getDateResolution())) {
return true;
}
}
return false;
}
public int hashCode() {
return (this.dateResolution == null) ? 0 : this.dateResolution.hashCode();
}
public String toString() {
return "<dateResolutionAttribute dateResolution='" + this.dateResolution
+ "'/>";
}
}

View File

@ -0,0 +1,39 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.GroupQueryNodeProcessor;
import org.apache.lucene.util.Attribute;
/**
* This attribute is used by {@link GroupQueryNodeProcessor} processor and must
* be defined in the {@link QueryConfigHandler}. This attribute tells the
* processor which is the default boolean operator when no operator is defined
* between terms. <br/>
*
*/
public interface DefaultOperatorAttribute extends Attribute {
public static enum Operator {
AND, OR;
}
public void setOperator(Operator operator);
public Operator getOperator();
}

View File

@ -0,0 +1,89 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.GroupQueryNodeProcessor;
import org.apache.lucene.util.AttributeImpl;
/**
* This attribute is used by {@link GroupQueryNodeProcessor} processor and must
* be defined in the {@link QueryConfigHandler}. This attribute tells the
* processor which is the default boolean operator when no operator is defined
* between terms. <br/>
*
* @see org.apache.lucene.queryParser.original.config.DefaultOperatorAttribute
*/
public class DefaultOperatorAttributeImpl extends AttributeImpl
implements DefaultOperatorAttribute {
private static final long serialVersionUID = -6804760312723049526L;
private Operator operator = Operator.OR;
public DefaultOperatorAttributeImpl() {
// empty constructor
}
public void setOperator(Operator operator) {
if (operator == null) {
throw new IllegalArgumentException("default operator cannot be null!");
}
this.operator = operator;
}
public Operator getOperator() {
return this.operator;
}
public void clear() {
throw new UnsupportedOperationException();
}
public void copyTo(AttributeImpl target) {
throw new UnsupportedOperationException();
}
public boolean equals(Object other) {
if (other instanceof DefaultOperatorAttributeImpl) {
DefaultOperatorAttributeImpl defaultOperatorAttr = (DefaultOperatorAttributeImpl) other;
if (defaultOperatorAttr.getOperator() == this.getOperator()) {
return true;
}
}
return false;
}
public int hashCode() {
return getOperator().hashCode() * 31;
}
public String toString() {
return "<defaultOperatorAttribute operator=" + this.operator.name() + "/>";
}
}

View File

@ -0,0 +1,34 @@
package org.apache.lucene.queryParser.original.config;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.queryParser.core.config.QueryConfigHandler;
import org.apache.lucene.queryParser.original.processors.PhraseSlopQueryNodeProcessor;
import org.apache.lucene.util.Attribute;
/**
* This attribute is used by {@link PhraseSlopQueryNodeProcessor} processor and
* must be defined in the {@link QueryConfigHandler}. This attribute tells the
* processor what is the default phrase slop when no slop is defined in a
* phrase. <br/>
*
*/
public interface DefaultPhraseSlopAttribute extends Attribute {
public void setDefaultPhraseSlop(int defaultPhraseSlop);
public int getDefaultPhraseSlop();
}

Some files were not shown because too many files have changed in this diff Show More