Selaa lähdekoodia

fix #2707 add QueryParser

Shinsuke Sugaya 2 vuotta sitten
vanhempi
commit
679e106739

+ 28 - 0
src/main/java/org/codelibs/fess/exception/QueryParseException.java

@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012-2023 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.exception;
+
+import org.apache.lucene.queryparser.classic.ParseException;
+
+public class QueryParseException extends FessSystemException {
+
+    private static final long serialVersionUID = 1L;
+
+    public QueryParseException(final ParseException cause) {
+        super(cause);
+    }
+
+}

+ 3 - 3
src/main/java/org/codelibs/fess/helper/QueryHelper.java

@@ -30,8 +30,6 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.lucene.queryparser.classic.ParseException;
-import org.apache.lucene.queryparser.classic.QueryParser;
 import org.apache.lucene.search.Query;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.fess.Constants;
@@ -40,9 +38,11 @@ import org.codelibs.fess.entity.GeoInfo;
 import org.codelibs.fess.entity.QueryContext;
 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
 import org.codelibs.fess.exception.InvalidQueryException;
+import org.codelibs.fess.exception.QueryParseException;
 import org.codelibs.fess.mylasta.action.FessUserBean;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.query.QueryFieldConfig;
+import org.codelibs.fess.query.parser.QueryParser;
 import org.codelibs.fess.score.QueryRescorer;
 import org.codelibs.fess.util.ComponentUtil;
 import org.dbflute.optional.OptionalThing;
@@ -158,7 +158,7 @@ public class QueryHelper {
             }
             // TODO options query
             context.accept(queryContext);
-        } catch (final ParseException e) {
+        } catch (final QueryParseException e) {
             throw new InvalidQueryException(messages -> messages.addErrorsInvalidQueryParseError(UserMessages.GLOBAL_PROPERTY_KEY),
                     "Invalid query: " + queryContext.getQueryString(), e);
         }

+ 112 - 0
src/main/java/org/codelibs/fess/query/parser/QueryParser.java

@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012-2023 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.query.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
+import org.apache.lucene.queryparser.classic.ParseException;
+import org.apache.lucene.queryparser.classic.QueryParser.Operator;
+import org.apache.lucene.queryparser.ext.ExtendableQueryParser;
+import org.apache.lucene.search.Query;
+import org.codelibs.fess.Constants;
+import org.codelibs.fess.exception.QueryParseException;
+
+public class QueryParser {
+
+    protected String defaultField = Constants.DEFAULT_FIELD;
+
+    protected Analyzer analyzer = new WhitespaceAnalyzer();
+
+    protected boolean allowLeadingWildcard = true;
+
+    protected Operator defaultOperator = Operator.AND;
+
+    protected List<Filter> filterList = new ArrayList<>();
+
+    protected FilterChain filterChain;
+
+    @PostConstruct
+    public void init() {
+        createFilterChain();
+    }
+
+    public Query parse(final String query) {
+        return filterChain.parse(query);
+    }
+
+    protected org.apache.lucene.queryparser.classic.QueryParser createQueryParser() {
+        final ExtendableQueryParser parser = new ExtendableQueryParser(defaultField, analyzer);
+        parser.setAllowLeadingWildcard(allowLeadingWildcard);
+        parser.setDefaultOperator(defaultOperator);
+        return parser;
+    }
+
+    public void setDefaultField(final String defaultField) {
+        this.defaultField = defaultField;
+    }
+
+    public void setAnalyzer(final Analyzer analyzer) {
+        this.analyzer = analyzer;
+    }
+
+    public void setAllowLeadingWildcard(final boolean allowLeadingWildcard) {
+        this.allowLeadingWildcard = allowLeadingWildcard;
+    }
+
+    public void setDefaultOperator(final Operator defaultOperator) {
+        this.defaultOperator = defaultOperator;
+    }
+
+    public void addFilter(final Filter filter) {
+        filterList.add(filter);
+        createFilterChain();
+    }
+
+    protected void createFilterChain() {
+        FilterChain chain = createDefaultFilterChain();
+        for (final Filter element : filterList) {
+            chain = appendFilterChain(element, chain);
+        }
+        filterChain = chain;
+    }
+
+    protected FilterChain appendFilterChain(final Filter filter, final FilterChain chain) {
+        return query -> filter.parse(query, chain);
+    }
+
+    protected FilterChain createDefaultFilterChain() {
+        return query -> {
+            try {
+                return createQueryParser().parse(query);
+            } catch (final ParseException e) {
+                throw new QueryParseException(e);
+            }
+        };
+    }
+
+    public interface Filter {
+        Query parse(final String query, final FilterChain chain);
+    }
+
+    public interface FilterChain {
+        Query parse(final String query);
+    }
+}

+ 1 - 1
src/main/java/org/codelibs/fess/util/ComponentUtil.java

@@ -23,7 +23,6 @@ import java.util.function.Consumer;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.lucene.queryparser.classic.QueryParser;
 import org.codelibs.core.crypto.CachedCipher;
 import org.codelibs.core.misc.DynamicProperties;
 import org.codelibs.fess.api.WebApiManagerFactory;
@@ -80,6 +79,7 @@ import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.mylasta.direction.FessProp;
 import org.codelibs.fess.query.QueryFieldConfig;
 import org.codelibs.fess.query.QueryProcessor;
+import org.codelibs.fess.query.parser.QueryParser;
 import org.codelibs.fess.script.ScriptEngineFactory;
 import org.codelibs.fess.sso.SsoManager;
 import org.codelibs.fess.thumbnail.ThumbnailManager;

+ 1 - 7
src/main/resources/app.xml

@@ -41,13 +41,7 @@
 	</component>
 	<component name="queryStringBuilder" class="org.codelibs.fess.util.QueryStringBuilder" instance="prototype">
 	</component>
-	<component name="queryParser" class="org.apache.lucene.queryparser.ext.ExtendableQueryParser" instance="prototype">
-		<arg>org.codelibs.fess.Constants.DEFAULT_FIELD</arg>
-		<arg>
-			<component class="org.apache.lucene.analysis.core.WhitespaceAnalyzer"></component>
-		</arg>
-		<property name="allowLeadingWildcard">true</property>
-		<property name="defaultOperator">org.apache.lucene.queryparser.classic.QueryParser$Operator.AND</property>
+	<component name="queryParser" class="org.codelibs.fess.query.parser.QueryParser">
 	</component>
 	<component name="facetInfo" class="org.codelibs.fess.entity.FacetInfo">
 	</component>

+ 3 - 6
src/test/java/org/codelibs/fess/helper/QueryHelperTest.java

@@ -21,9 +21,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
-import org.apache.lucene.queryparser.classic.QueryParser;
-import org.apache.lucene.queryparser.ext.ExtendableQueryParser;
 import org.codelibs.core.io.FileUtil;
 import org.codelibs.core.misc.DynamicProperties;
 import org.codelibs.fess.Constants;
@@ -41,6 +38,7 @@ import org.codelibs.fess.query.QueryProcessor;
 import org.codelibs.fess.query.TermQueryCommand;
 import org.codelibs.fess.query.TermRangeQueryCommand;
 import org.codelibs.fess.query.WildcardQueryCommand;
+import org.codelibs.fess.query.parser.QueryParser;
 import org.codelibs.fess.unit.UnitFessTestCase;
 import org.codelibs.fess.util.ComponentUtil;
 import org.opensearch.index.query.BoolQueryBuilder;
@@ -59,9 +57,8 @@ public class QueryHelperTest extends UnitFessTestCase {
         super.setUp();
         queryHelper = new QueryHelper() {
             protected QueryParser getQueryParser() {
-                ExtendableQueryParser queryParser = new ExtendableQueryParser(Constants.DEFAULT_FIELD, new WhitespaceAnalyzer());
-                queryParser.setAllowLeadingWildcard(true);
-                queryParser.setDefaultOperator(QueryParser.Operator.AND);
+                QueryParser queryParser = new QueryParser();
+                queryParser.init();
                 return queryParser;
             }
         };

+ 3 - 7
src/test/java/org/codelibs/fess/query/TermQueryCommandTest.java

@@ -19,14 +19,11 @@ import java.util.List;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
-import org.apache.lucene.queryparser.classic.QueryParser.Operator;
-import org.apache.lucene.queryparser.ext.ExtendableQueryParser;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
-import org.codelibs.fess.Constants;
 import org.codelibs.fess.entity.QueryContext;
 import org.codelibs.fess.exception.InvalidQueryException;
+import org.codelibs.fess.query.parser.QueryParser;
 import org.codelibs.fess.unit.UnitFessTestCase;
 import org.codelibs.fess.util.ComponentUtil;
 import org.opensearch.index.query.BoolQueryBuilder;
@@ -50,9 +47,8 @@ public class TermQueryCommandTest extends UnitFessTestCase {
         queryFieldConfig.init();
         ComponentUtil.register(queryFieldConfig, "queryFieldConfig");
 
-        ExtendableQueryParser queryParser = new ExtendableQueryParser(Constants.DEFAULT_FIELD, new WhitespaceAnalyzer());
-        queryParser.setAllowLeadingWildcard(true);
-        queryParser.setDefaultOperator(Operator.AND);
+        QueryParser queryParser = new QueryParser();
+        queryParser.init();
         ComponentUtil.register(queryParser, "queryParser");
 
         queryCommand = new TermQueryCommand();