ソースを参照

refactoring for query helper

Shinsuke Sugaya 9 年 前
コミット
e8ced1368c
22 ファイル変更2362 行追加856 行削除
  1. 1 1
      pom.xml
  2. 0 4
      src/main/java/org/codelibs/fess/Constants.java
  3. 1 1
      src/main/java/org/codelibs/fess/FessBoot.java
  4. 3 2
      src/main/java/org/codelibs/fess/api/suggest/SuggestApiManager.java
  5. 7 6
      src/main/java/org/codelibs/fess/app/service/SearchService.java
  6. 2 2
      src/main/java/org/codelibs/fess/app/web/admin/crawlingsession/AdminCrawlingsessionAction.java
  7. 1 0
      src/main/java/org/codelibs/fess/app/web/base/FessAdminAction.java
  8. 1 0
      src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java
  9. 108 0
      src/main/java/org/codelibs/fess/entity/QueryContext.java
  10. 0 131
      src/main/java/org/codelibs/fess/entity/SearchQuery.java
  11. 50 102
      src/main/java/org/codelibs/fess/es/client/FessEsClient.java
  12. 1 1
      src/main/java/org/codelibs/fess/es/exentity/CrawlingSession.java
  13. 2 2
      src/main/java/org/codelibs/fess/exec/Crawler.java
  14. 370 540
      src/main/java/org/codelibs/fess/helper/QueryHelper.java
  15. 2 2
      src/main/java/org/codelibs/fess/helper/SearchLogHelper.java
  16. 16 15
      src/main/java/org/codelibs/fess/helper/ViewHelper.java
  17. 10 4
      src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java
  18. 73 2
      src/main/java/org/codelibs/fess/mylasta/action/FessMessages.java
  19. 0 40
      src/main/java/org/codelibs/fess/mylasta/direction/FessEnv.java
  20. 15 0
      src/main/java/org/codelibs/fess/util/StreamUtil.java
  21. 5 1
      src/main/resources/fess_message.properties
  22. 1694 0
      src/test/java/org/codelibs/fess/helper/QueryHelperTest.java

+ 1 - 1
pom.xml

@@ -53,7 +53,7 @@
 		<commons.fileupload.version>1.3.1</commons.fileupload.version>
 
 		<!-- Testing -->
-		<junit.version>4.8.2</junit.version>
+		<junit.version>4.12</junit.version>
 		<utflute.version>0.5.2</utflute.version>
 
 		<!-- Crawler -->

+ 0 - 4
src/main/java/org/codelibs/fess/Constants.java

@@ -46,10 +46,6 @@ public class Constants extends CoreLibConstants {
 
     public static final String ON = "on";
 
-    public static final String ASC = "asc";
-
-    public static final String DESC = "desc";
-
     public static final String READY = "ready";
 
     public static final String RUNNING = "running";

+ 1 - 1
src/main/java/org/codelibs/fess/FessBoot.java

@@ -61,7 +61,7 @@ public class FessBoot extends TomcatBoot {
         }
 
         final String tomcatConfigPath = getTomcatConfigPath();
-        TomcatBoot tomcatBoot = new FessBoot(getPort(), getContextPath()) //
+        final TomcatBoot tomcatBoot = new FessBoot(getPort(), getContextPath()) //
                 .useTldDetect(); // for JSP
         if (tomcatConfigPath != null) {
             tomcatBoot.configure(tomcatConfigPath); // e.g. URIEncoding

+ 3 - 2
src/main/java/org/codelibs/fess/api/suggest/SuggestApiManager.java

@@ -19,14 +19,15 @@ public class SuggestApiManager extends BaseApiManager {
     }
 
     @Override
-    public boolean matches(HttpServletRequest request) {
+    public boolean matches(final HttpServletRequest request) {
         return false; // TODO remove
         //        final String servletPath = request.getServletPath();
         //        return servletPath.startsWith(pathPrefix);
     }
 
     @Override
-    public void process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+    public void process(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException,
+            ServletException {
         throw new UnsupportedOperationException("TODO");
     }
 

+ 7 - 6
src/main/java/org/codelibs/fess/app/service/SearchService.java

@@ -128,12 +128,13 @@ public class SearchService {
         final QueryResponseList queryResponseList = (QueryResponseList) documentItems;
         data.setFacetResponse(queryResponseList.getFacetResponse());
 
-        final String[] highlightQueries = (String[]) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
+        @SuppressWarnings("unchecked")
+        final Set<String> highlightQueries = (Set<String>) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
         if (highlightQueries != null) {
             final StringBuilder buf = new StringBuilder(100);
-            for (final String q : highlightQueries) {
+            highlightQueries.stream().forEach(q -> {
                 buf.append("&hq=").append(q);
-            }
+            });
             data.setAppendHighlightParams(buf.toString());
         }
 
@@ -325,11 +326,11 @@ public class SearchService {
         return fessEsClient.update(fieldHelper.docIndex, fieldHelper.docType, id, field, value);
     }
 
-    public boolean bulkUpdate(Consumer<BulkRequestBuilder> consumer) {
-        BulkRequestBuilder builder = fessEsClient.prepareBulk();
+    public boolean bulkUpdate(final Consumer<BulkRequestBuilder> consumer) {
+        final BulkRequestBuilder builder = fessEsClient.prepareBulk();
         consumer.accept(builder);
         try {
-            BulkResponse response = builder.execute().get();
+            final BulkResponse response = builder.execute().get();
             if (response.hasFailures()) {
                 throw new FessEsClientException(response.buildFailureMessage());
             } else {

+ 2 - 2
src/main/java/org/codelibs/fess/app/web/admin/crawlingsession/AdminCrawlingsessionAction.java

@@ -126,7 +126,7 @@ public class AdminCrawlingsessionAction extends FessAdminAction {
     public HtmlResponse deletefromconfirm(final EditForm form) {
         form.crudMode = CrudMode.DELETE;
         validate(form, messages -> {}, toIndexHtml());
-        String id = form.id;
+        final String id = form.id;
         crawlingSessionService.getCrawlingSession(id).ifPresent(entity -> {
             copyBeanToBean(entity, form, op -> {});
         }).orElse(() -> {
@@ -166,7 +166,7 @@ public class AdminCrawlingsessionAction extends FessAdminAction {
     public HtmlResponse delete(final EditForm form) {
         verifyCrudMode(form.crudMode, CrudMode.DELETE);
         validate(form, messages -> {}, toIndexHtml());
-        String id = form.id;
+        final String id = form.id;
         crawlingSessionService.getCrawlingSession(id).alwaysPresent(entity -> {
             crawlingSessionService.delete(entity);
             saveInfo(messages -> messages.addSuccessCrudDeleteCrudTable(GLOBAL));

+ 1 - 0
src/main/java/org/codelibs/fess/app/web/base/FessAdminAction.java

@@ -100,6 +100,7 @@ public abstract class FessAdminAction extends FessBaseAction {
     @Override
     protected TypicalEmbeddedKeySupplier newTypicalEmbeddedKeySupplier() {
         return new TypicalSimpleEmbeddedKeySupplier() {
+            @Override
             public String getErrorMessageForwardPath() {
                 return "/admin/error/error.jsp";
             }

+ 1 - 0
src/main/java/org/codelibs/fess/app/web/base/FessSearchAction.java

@@ -100,6 +100,7 @@ public abstract class FessSearchAction extends FessBaseAction {
     @Override
     protected TypicalEmbeddedKeySupplier newTypicalEmbeddedKeySupplier() {
         return new TypicalSimpleEmbeddedKeySupplier() {
+            @Override
             public String getErrorMessageForwardPath() {
                 return "/error/system.jsp";
             }

+ 108 - 0
src/main/java/org/codelibs/fess/entity/QueryContext.java

@@ -0,0 +1,108 @@
+/*
+ * Copyright 2009-2015 the 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.entity;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import org.codelibs.fess.Constants;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.FilterBuilder;
+import org.elasticsearch.index.query.MatchAllQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.sort.SortBuilder;
+import org.lastaflute.web.util.LaRequestUtil;
+
+public class QueryContext {
+    private QueryBuilder queryBuilder;
+
+    private final List<SortBuilder> sortBuilderList = new ArrayList<>();
+
+    private final String queryString;
+
+    private final Set<String> highlightedQuerySet = new HashSet<>();
+
+    private final Map<String, List<String>> fieldLogMap = new HashMap<>();
+
+    public QueryContext(final String queryString) {
+        this.queryString = queryString;
+        LaRequestUtil.getOptionalRequest().ifPresent(request -> {
+            request.setAttribute(Constants.HIGHLIGHT_QUERIES, highlightedQuerySet);
+            request.setAttribute(Constants.FIELD_LOGS, fieldLogMap);
+        });
+    }
+
+    public void addFilter(final FilterBuilder filterBuilder) {
+        queryBuilder = QueryBuilders.filteredQuery(queryBuilder, filterBuilder);
+    }
+
+    public void addQuery(final Consumer<BoolQueryBuilder> boolQuery) {
+        BoolQueryBuilder builder;
+        if (queryBuilder instanceof BoolQueryBuilder) {
+            builder = (BoolQueryBuilder) queryBuilder;
+        } else if (queryBuilder instanceof MatchAllQueryBuilder) {
+            builder = QueryBuilders.boolQuery();
+        } else {
+            builder = QueryBuilders.boolQuery().must(queryBuilder);
+        }
+        boolQuery.accept(builder);
+        if (builder.hasClauses()) {
+            queryBuilder = builder;
+        }
+    }
+
+    public void setQueryBuilder(final QueryBuilder queryBuilder) {
+        this.queryBuilder = queryBuilder;
+    }
+
+    public void addSorts(final SortBuilder... sortBuilders) {
+        Stream.of(sortBuilders).forEach(sortBuilder -> sortBuilderList.add(sortBuilder));
+    }
+
+    public boolean hasSorts() {
+        return !sortBuilderList.isEmpty();
+    }
+
+    public List<SortBuilder> sortBuilders() {
+        return sortBuilderList;
+    }
+
+    public QueryBuilder getQueryBuilder() {
+        return queryBuilder;
+    }
+
+    public void addFieldLog(String field, String text) {
+        List<String> list = fieldLogMap.get(field);
+        if (list == null) {
+            list = new ArrayList<>();
+            fieldLogMap.put(field, list);
+        }
+        list.add(text);
+    }
+
+    public void addHighlightedQuery(String text) {
+        highlightedQuerySet.add(text);
+    }
+
+}

+ 0 - 131
src/main/java/org/codelibs/fess/entity/SearchQuery.java

@@ -1,131 +0,0 @@
-/*
- * Copyright 2009-2015 the 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.entity;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.codelibs.core.lang.StringUtil;
-import org.codelibs.fess.Constants;
-
-public class SearchQuery {
-    private String query;
-
-    private final List<String> filterQueryList = new ArrayList<String>();
-
-    private final List<SortField> sortFieldList = new ArrayList<SortField>();
-
-    private String minimumShouldMatch;
-
-    private String defType;
-
-    public String getQuery() {
-        return query;
-    }
-
-    public void setQuery(final String query) {
-        this.query = query;
-    }
-
-    public SearchQuery query(final String query) {
-        setQuery(query);
-        return this;
-    }
-
-    public boolean queryExists() {
-        return StringUtil.isNotBlank(query);
-    }
-
-    public void addSortField(final String field, final String order) {
-        if (StringUtil.isNotBlank(field) && (Constants.ASC.equals(order) || Constants.DESC.equals(order))) {
-            final SortField sortField = new SortField();
-            sortField.setField(field);
-            sortField.setOrder(order);
-            sortFieldList.add(sortField);
-        }
-    }
-
-    public SearchQuery sortField(final String field, final String order) {
-        addSortField(field, order);
-        return this;
-    }
-
-    public SortField[] getSortFields() {
-        return sortFieldList.toArray(new SortField[sortFieldList.size()]);
-    }
-
-    public void addFilterQuery(final String fq) {
-        filterQueryList.add(fq);
-    }
-
-    public boolean hasFilterQueries() {
-        return !filterQueryList.isEmpty();
-    }
-
-    public String[] getFilterQueries() {
-        return filterQueryList.toArray(new String[filterQueryList.size()]);
-    }
-
-    public String getMinimumShouldMatch() {
-        return minimumShouldMatch;
-    }
-
-    public void setMinimumShouldMatch(final String minimumShouldMatch) {
-        this.minimumShouldMatch = minimumShouldMatch;
-    }
-
-    public String getDefType() {
-        return defType;
-    }
-
-    public void setDefType(final String defType) {
-        this.defType = defType;
-    }
-
-    public static class SortField {
-        private String field;
-
-        private String order;
-
-        public String getField() {
-            return field;
-        }
-
-        public void setField(final String field) {
-            this.field = field;
-        }
-
-        public String getOrder() {
-            return order;
-        }
-
-        public void setOrder(final String order) {
-            this.order = order;
-        }
-
-        @Override
-        public String toString() {
-            return "SortField [field=" + field + ", order=" + order + "]";
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "SearchQuery [query=" + query + ", filterQueryList=" + filterQueryList + ", sortFieldList=" + sortFieldList
-                + ", minimumShouldMatch=" + minimumShouldMatch + "]";
-    }
-}

+ 50 - 102
src/main/java/org/codelibs/fess/es/client/FessEsClient.java

@@ -3,6 +3,7 @@ package org.codelibs.fess.es.client;
 import static org.codelibs.elasticsearch.runner.ElasticsearchClusterRunner.newConfigs;
 
 import java.io.File;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -29,12 +30,12 @@ import org.codelibs.fess.Constants;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
 import org.codelibs.fess.entity.PingResponse;
-import org.codelibs.fess.entity.SearchQuery;
-import org.codelibs.fess.entity.SearchQuery.SortField;
+import org.codelibs.fess.entity.QueryContext;
 import org.codelibs.fess.exception.ResultOffsetExceededException;
 import org.codelibs.fess.helper.QueryHelper;
 import org.codelibs.fess.indexer.FessSearchQueryException;
 import org.codelibs.fess.util.ComponentUtil;
+import org.codelibs.fess.util.StreamUtil;
 import org.dbflute.optional.OptionalEntity;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.action.Action;
@@ -134,10 +135,8 @@ import org.elasticsearch.common.transport.InetSocketTransportAddress;
 import org.elasticsearch.common.transport.TransportAddress;
 import org.elasticsearch.common.unit.TimeValue;
 import org.elasticsearch.index.get.GetField;
-import org.elasticsearch.index.query.BoolFilterBuilder;
 import org.elasticsearch.index.query.FilterBuilders;
 import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.indices.IndexAlreadyExistsException;
 import org.elasticsearch.indices.IndexMissingException;
 import org.elasticsearch.search.SearchHit;
@@ -145,9 +144,6 @@ import org.elasticsearch.search.SearchHitField;
 import org.elasticsearch.search.aggregations.AggregationBuilders;
 import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
 import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
-import org.elasticsearch.search.sort.FieldSortBuilder;
-import org.elasticsearch.search.sort.SortBuilders;
-import org.elasticsearch.search.sort.SortOrder;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -670,7 +666,6 @@ public class FessEsClient implements Client {
     public static class SearchConditionBuilder {
         private final SearchRequestBuilder searchRequestBuilder;
         private String query;
-        private boolean administrativeAccess = false;
         private String[] responseFields;
         private int offset = Constants.DEFAULT_START_COUNT;
         private int size = Constants.DEFAULT_PAGE_SIZE;
@@ -691,7 +686,6 @@ public class FessEsClient implements Client {
         }
 
         public SearchConditionBuilder administrativeAccess() {
-            this.administrativeAccess = true;
             return this;
         }
 
@@ -721,16 +715,23 @@ public class FessEsClient implements Client {
         }
 
         public boolean build() {
-            if (offset > ComponentUtil.getQueryHelper().getMaxSearchResultOffset()) {
-                throw new ResultOffsetExceededException("The number of result size is exceeded.");
+            if (StringUtil.isBlank(query)) {
+                return false;
             }
 
-            final SearchQuery searchQuery = ComponentUtil.getQueryHelper().build(query, administrativeAccess);
-            final String q = searchQuery.getQuery();
-            if (StringUtil.isBlank(q)) {
-                return false;
+            final QueryHelper queryHelper = ComponentUtil.getQueryHelper();
+
+            if (offset > queryHelper.getMaxSearchResultOffset()) {
+                throw new ResultOffsetExceededException("The number of result size is exceeded.");
             }
 
+            final QueryContext queryContext = queryHelper.build(query, context -> {
+                // geo
+                    if (geoInfo != null && geoInfo.isAvailable()) {
+                        context.addFilter(geoInfo.toFilterBuilder());
+                    }
+                });
+
             searchRequestBuilder.setFrom(offset).setSize(size);
 
             if (responseFields != null) {
@@ -738,102 +739,49 @@ public class FessEsClient implements Client {
             }
 
             // sort
-            final SortField[] sortFields = searchQuery.getSortFields();
-            if (sortFields.length != 0) {
-                for (final SortField sortField : sortFields) {
-                    final FieldSortBuilder fieldSort = SortBuilders.fieldSort(sortField.getField());
-                    if (Constants.DESC.equals(sortField.getOrder())) {
-                        fieldSort.order(SortOrder.DESC);
-                    } else {
-                        fieldSort.order(SortOrder.ASC);
-                    }
-                    searchRequestBuilder.addSort(fieldSort);
-                }
-            } else if (ComponentUtil.getQueryHelper().hasDefaultSortFields()) {
-                for (final SortField sortField : ComponentUtil.getQueryHelper().getDefaultSortFields()) {
-                    final FieldSortBuilder fieldSort = SortBuilders.fieldSort(sortField.getField());
-                    if (Constants.DESC.equals(sortField.getOrder())) {
-                        fieldSort.order(SortOrder.DESC);
-                    } else {
-                        fieldSort.order(SortOrder.ASC);
-                    }
-                    searchRequestBuilder.addSort(fieldSort);
-                }
-            }
+            queryContext.sortBuilders().forEach(sortBuilder -> searchRequestBuilder.addSort(sortBuilder));
+
             // highlighting
-            if (ComponentUtil.getQueryHelper().getHighlightedFields() != null
-                    && ComponentUtil.getQueryHelper().getHighlightedFields().length != 0) {
-                for (final String hf : ComponentUtil.getQueryHelper().getHighlightedFields()) {
-                    searchRequestBuilder.addHighlightedField(hf, ComponentUtil.getQueryHelper().getHighlightFragmentSize());
-                }
-            }
+            queryHelper.highlightedFields().forEach(
+                    hf -> searchRequestBuilder.addHighlightedField(hf, queryHelper.getHighlightFragmentSize()));
 
             // facets
             if (facetInfo != null) {
-                if (facetInfo.field != null) {
-                    for (final String f : facetInfo.field) {
-                        if (ComponentUtil.getQueryHelper().isFacetField(f)) {
-                            final String encodedField = BaseEncoding.base64().encode(f.getBytes(Charsets.UTF_8));
-                            final TermsBuilder termsBuilder =
-                                    AggregationBuilders.terms(Constants.FACET_FIELD_PREFIX + encodedField).field(f);
-                            // TODO order
-                            if (facetInfo.limit != null) {
-                                // TODO
-                                termsBuilder.size(Integer.parseInt(facetInfo.limit));
-                            }
-                            searchRequestBuilder.addAggregation(termsBuilder);
-                        } else {
-                            throw new FessSearchQueryException("Invalid facet field: " + f);
+                StreamUtil.of(facetInfo.field).forEach(f -> {
+                    if (queryHelper.isFacetField(f)) {
+                        final String encodedField = BaseEncoding.base64().encode(f.getBytes(Charsets.UTF_8));
+                        final TermsBuilder termsBuilder = AggregationBuilders.terms(Constants.FACET_FIELD_PREFIX + encodedField).field(f);
+                        // TODO order
+                        if (facetInfo.limit != null) {
+                            // TODO
+                            termsBuilder.size(Integer.parseInt(facetInfo.limit));
                         }
+                        searchRequestBuilder.addAggregation(termsBuilder);
+                    } else {
+                        throw new FessSearchQueryException("Invalid facet field: " + f);
                     }
-                }
-                if (facetInfo.query != null) {
-                    for (final String fq : facetInfo.query) {
-                        final String facetQuery = ComponentUtil.getQueryHelper().buildFacetQuery(fq);
-                        if (StringUtil.isNotBlank(facetQuery)) {
-                            final String encodedFacetQuery = BaseEncoding.base64().encode(facetQuery.getBytes(Charsets.UTF_8));
-                            final FilterAggregationBuilder filterBuilder =
-                                    AggregationBuilders.filter(Constants.FACET_QUERY_PREFIX + encodedFacetQuery).filter(
-                                            FilterBuilders.queryFilter(QueryBuilders.queryStringQuery(facetQuery)));
-                            // TODO order
-                            if (facetInfo.limit != null) {
-                                // TODO
-                                //    filterBuilder.size(Integer.parseInt(facetInfo .limit));
+                });
+                StreamUtil.of(facetInfo.query).forEach(
+                        fq -> {
+                            final QueryContext facetContext = queryHelper.buildBaseQuery(fq, c -> {});
+                            if (facetContext != null) {
+                                final String encodedFacetQuery = BaseEncoding.base64().encode(fq.getBytes(StandardCharsets.UTF_8));
+                                final FilterAggregationBuilder filterBuilder =
+                                        AggregationBuilders.filter(Constants.FACET_QUERY_PREFIX + encodedFacetQuery).filter(
+                                                FilterBuilders.queryFilter(facetContext.getQueryBuilder()));
+                                // TODO order
+                                if (facetInfo.limit != null) {
+                                    // TODO
+                                    //    filterBuilder.size(Integer.parseInt(facetInfo .limit));
+                                }
+                                searchRequestBuilder.addAggregation(filterBuilder);
+                            } else {
+                                throw new FessSearchQueryException("Invalid facet query: " + fq);
                             }
-                            searchRequestBuilder.addAggregation(filterBuilder);
-                        } else {
-                            throw new FessSearchQueryException("Invalid facet query: " + facetQuery);
-                        }
-                    }
-                }
-            }
-
-            BoolFilterBuilder boolFilterBuilder = null;
-
-            // query
-            QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(q);
-            // filter query
-            if (searchQuery.hasFilterQueries()) {
-                if (boolFilterBuilder == null) {
-                    boolFilterBuilder = FilterBuilders.boolFilter();
-                }
-                for (final String filterQuery : searchQuery.getFilterQueries()) {
-                    boolFilterBuilder.must(FilterBuilders.queryFilter(QueryBuilders.queryStringQuery(filterQuery)));
-                }
-            }
-            // geo
-            if (geoInfo != null && geoInfo.isAvailable()) {
-                if (boolFilterBuilder == null) {
-                    boolFilterBuilder = FilterBuilders.boolFilter();
-                }
-                boolFilterBuilder.must(geoInfo.toFilterBuilder());
-            }
-
-            if (boolFilterBuilder != null) {
-                queryBuilder = QueryBuilders.filteredQuery(queryBuilder, boolFilterBuilder);
+                        });
             }
 
-            searchRequestBuilder.setQuery(queryBuilder);
+            searchRequestBuilder.setQuery(queryContext.getQueryBuilder());
 
             return true;
         }

+ 1 - 1
src/main/java/org/codelibs/fess/es/exentity/CrawlingSession.java

@@ -38,7 +38,7 @@ public class CrawlingSession extends BsCrawlingSession {
         asDocMeta().version(version);
     }
 
-    public void setCrawlingSessionInfoList(List<CrawlingSessionInfo> crawlingSessionInfoList) {
+    public void setCrawlingSessionInfoList(final List<CrawlingSessionInfo> crawlingSessionInfoList) {
         this.crawlingSessionInfoList = crawlingSessionInfoList;
     }
 

+ 2 - 2
src/main/java/org/codelibs/fess/exec/Crawler.java

@@ -296,8 +296,8 @@ public class Crawler implements Serializable {
             }
 
             try {
-                FessConfig fessConfig = ComponentUtil.getComponent(FessConfig.class);
-                Postbox postbox = ComponentUtil.getComponent(Postbox.class);
+                final FessConfig fessConfig = ComponentUtil.getComponent(FessConfig.class);
+                final Postbox postbox = ComponentUtil.getComponent(Postbox.class);
                 CrawlerPostcard.droppedInto(postbox, postcard -> {
                     postcard.setFrom(fessConfig.getMailFromAddress(), fessConfig.getMailFromName());
                     postcard.addReplyTo(fessConfig.getMailReturnPath());

ファイルの差分が大きいため隠しています
+ 370 - 540
src/main/java/org/codelibs/fess/helper/QueryHelper.java


+ 2 - 2
src/main/java/org/codelibs/fess/helper/SearchLogHelper.java

@@ -151,7 +151,7 @@ public class SearchLogHelper {
         final Map<String, UserInfo> userInfoMap = new HashMap<>();
         queue.stream().forEach(searchLog -> {
             final String userAgent = searchLog.getUserAgent();
-            boolean isBot = userAgent != null && Stream.of(botNames).anyMatch(botName -> userAgent.indexOf(botName) >= 0);
+            final boolean isBot = userAgent != null && Stream.of(botNames).anyMatch(botName -> userAgent.indexOf(botName) >= 0);
             if (!isBot) {
                 searchLog.getUserInfo().ifPresent(userInfo -> {
                     final String code = userInfo.getCode();
@@ -265,7 +265,7 @@ public class SearchLogHelper {
                             .stream()
                             .forEach(
                                     entry -> {
-                                        String id = docIdMap.get(entry.getKey());
+                                        final String id = docIdMap.get(entry.getKey());
                                         if (id != null) {
                                             builder.add(new UpdateRequest(fieldHelper.docIndex, fieldHelper.docType, id).doc(
                                                     fieldHelper.clickCountField, entry.getValue()));

+ 16 - 15
src/main/java/org/codelibs/fess/helper/ViewHelper.java

@@ -27,23 +27,23 @@ import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.lang3.StringUtils;
 import org.codelibs.core.CoreLibConstants;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.core.misc.Base64Util;
 import org.codelibs.core.misc.DynamicProperties;
-import org.codelibs.core.net.URLUtil;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.app.service.DataConfigService;
 import org.codelibs.fess.app.service.FileConfigService;
@@ -101,7 +101,7 @@ public class ViewHelper implements Serializable {
 
     public String urlLinkEncoding = Constants.UTF_8;
 
-    public String[] highlightingFields = new String[] { "hl_content", "digest" };
+    public String[] highlightedFields = new String[] { "hl_content", "digest" };
 
     public boolean useHighlight = false;
 
@@ -158,11 +158,16 @@ public class ViewHelper implements Serializable {
     }
 
     public String getContentDescription(final Map<String, Object> document) {
-        final HttpServletRequest request = LaRequestUtil.getOptionalRequest().orElse(null);
-        final String[] queries = request == null ? StringUtil.EMPTY_STRINGS : (String[]) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
+        final Set<String> queries = new HashSet<>();
+        LaRequestUtil.getOptionalRequest().ifPresent(request -> {
+            Set<String> set = (Set<String>) request.getAttribute(Constants.HIGHLIGHT_QUERIES);
+            if (set != null) {
+                queries.addAll(set);
+            }
+        });
         final int size = descriptionLength;
 
-        for (final String field : highlightingFields) {
+        for (final String field : highlightedFields) {
             final String text = getString(document, field);
             if (StringUtil.isNotBlank(text)) {
                 if (useHighlight) {
@@ -185,8 +190,9 @@ public class ViewHelper implements Serializable {
         return str.replaceAll(originalHighlightTagPre, StringUtil.EMPTY).replaceAll(originalHighlightTagPost, StringUtil.EMPTY);
     }
 
-    protected String highlight(final String content, final String[] queries) {
-        if (StringUtil.isBlank(content) || queries == null || queries.length == 0) {
+    @Deprecated
+    protected String highlight(final String content, final Set<String> queries) {
+        if (StringUtil.isBlank(content) || queries.isEmpty()) {
             return content;
         }
         String newContent = content;
@@ -313,16 +319,11 @@ public class ViewHelper implements Serializable {
     }
 
     protected String appendPDFSearchWord(final String url) {
-        final String[] queries = (String[]) LaRequestUtil.getRequest().getAttribute(Constants.HIGHLIGHT_QUERIES);
+        final Set<String> queries = (Set<String>) LaRequestUtil.getRequest().getAttribute(Constants.HIGHLIGHT_QUERIES);
         if (queries != null) {
             final StringBuilder buf = new StringBuilder(url.length() + 100);
             buf.append(url).append("#search=%22");
-            for (int i = 0; i < queries.length; i++) {
-                if (i != 0) {
-                    buf.append(' ');
-                }
-                buf.append(URLUtil.encode(queries[i], urlLinkEncoding));
-            }
+            buf.append(String.join(" ", queries.toArray(new String[queries.size()])));
             buf.append("%22");
             return buf.toString();
         }

+ 10 - 4
src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java

@@ -512,7 +512,7 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Scheduler */
     public static final String LABELS_menu_scheduled_job_config = "{labels.menu_scheduled_job_config}";
 
-    /** The key of the message: System */
+    /** The key of the message: Dashboard */
     public static final String LABELS_menu_system_config = "{labels.menu_system_config}";
 
     /** The key of the message: Index */
@@ -632,7 +632,7 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Search... */
     public static final String LABELS_SIDEBAR_placeholder_search = "{labels.sidebar.placeholder_search}";
 
-    /** The key of the message: Copyright(C) 2009-2015 CodeLibs Project. <span class="br-phone"></span>All Rights Reserved. */
+    /** The key of the message: Copyright(C) 2009-2015 <a href="https://github.com/codelibs">CodeLibs Project</a>. <span class="br-phone"></span>All Rights Reserved. */
     public static final String LABELS_FOOTER_COPYRIGHT = "{labels.footer.copyright}";
 
     /** The key of the message: Search */
@@ -839,11 +839,17 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Login */
     public static final String LABELS_LOGIN = "{labels.login}";
 
+    /** The key of the message: User name */
+    public static final String LABELS_LOGIN_placeholder_username = "{labels.login.placeholder_username}";
+
+    /** The key of the message: Password */
+    public static final String LABELS_LOGIN_placeholder_password = "{labels.login.placeholder_password}";
+
     /** The key of the message: Copyright(C) 2009-2014 CodeLibs Project. All Rights Reserved. */
     public static final String LABELS_LOGIN_footer_copyright = "{labels.login.footer_copyright}";
 
     /** The key of the message: Login */
-    public static final String LABELS_login_title = "{labels.login_title}";
+    public static final String LABELS_LOGIN_TITLE = "{labels.login.title}";
 
     /** The key of the message: Labels */
     public static final String LABELS_index_label = "{labels.index_label}";
@@ -1115,7 +1121,7 @@ public class FessLabels extends ActionMessages {
     /** The key of the message: Remove Index Before */
     public static final String LABELS_day_for_cleanup = "{labels.day_for_cleanup}";
 
-    /** The key of the message: Day */
+    /** The key of the message: Day(s) */
     public static final String LABELS_DAY = "{labels.day}";
 
     /** The key of the message: Update */

+ 73 - 2
src/main/java/org/codelibs/fess/mylasta/action/FessMessages.java

@@ -294,7 +294,7 @@ public class FessMessages extends FessLabels {
     /** The key of the message: Invalid password. */
     public static final String ERRORS_password_does_not_exist_in_session = "{errors.password_does_not_exist_in_session}";
 
-    /** The key of the message: The given query is invalid. */
+    /** The key of the message: The given query has unknown condition. */
     public static final String ERRORS_invalid_query_unknown = "{errors.invalid_query_unknown}";
 
     /** The key of the message: An invalid quote character is used. */
@@ -315,6 +315,18 @@ public class FessMessages extends FessLabels {
     /** The key of the message: An invalid range is used. The example of the range format is "field:'{'Aida TO Carmen'}'". */
     public static final String ERRORS_invalid_query_str_range = "{errors.invalid_query_str_range}";
 
+    /** The key of the message: The given query is invalid. */
+    public static final String ERRORS_invalid_query_parse_error = "{errors.invalid_query_parse_error}";
+
+    /** The key of the message: The given sort ({0}) is invalid. */
+    public static final String ERRORS_invalid_query_sort_value = "{errors.invalid_query_sort_value}";
+
+    /** The key of the message: The given sort ({0}) is not supported. */
+    public static final String ERRORS_invalid_query_unsupported_sort_field = "{errors.invalid_query_unsupported_sort_field}";
+
+    /** The key of the message: The given sort order ({0}) is not supported. */
+    public static final String ERRORS_invalid_query_unsupported_sort_order = "{errors.invalid_query_unsupported_sort_order}";
+
     /** The key of the message: Invalid mode(expected value is {0}, but it's {1}). */
     public static final String ERRORS_crud_invalid_mode = "{errors.crud_invalid_mode}";
 
@@ -1786,7 +1798,7 @@ public class FessMessages extends FessLabels {
     /**
      * Add the created action message for the key 'errors.invalid_query_unknown' with parameters.
      * <pre>
-     * message: The given query is invalid.
+     * message: The given query has unknown condition.
      * </pre>
      * @param property The property name for the message. (NotNull)
      * @return this. (NotNull)
@@ -1881,6 +1893,65 @@ public class FessMessages extends FessLabels {
         return this;
     }
 
+    /**
+     * Add the created action message for the key 'errors.invalid_query_parse_error' with parameters.
+     * <pre>
+     * message: The given query is invalid.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsInvalidQueryParseError(String property) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(ERRORS_invalid_query_parse_error));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'errors.invalid_query_sort_value' with parameters.
+     * <pre>
+     * message: The given sort ({0}) is invalid.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsInvalidQuerySortValue(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(ERRORS_invalid_query_sort_value, arg0));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'errors.invalid_query_unsupported_sort_field' with parameters.
+     * <pre>
+     * message: The given sort ({0}) is not supported.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsInvalidQueryUnsupportedSortField(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(ERRORS_invalid_query_unsupported_sort_field, arg0));
+        return this;
+    }
+
+    /**
+     * Add the created action message for the key 'errors.invalid_query_unsupported_sort_order' with parameters.
+     * <pre>
+     * message: The given sort order ({0}) is not supported.
+     * </pre>
+     * @param property The property name for the message. (NotNull)
+     * @param arg0 The parameter arg0 for message. (NotNull)
+     * @return this. (NotNull)
+     */
+    public FessMessages addErrorsInvalidQueryUnsupportedSortOrder(String property, String arg0) {
+        assertPropertyNotNull(property);
+        add(property, new ActionMessage(ERRORS_invalid_query_unsupported_sort_order, arg0));
+        return this;
+    }
+
     /**
      * Add the created action message for the key 'errors.crud_invalid_mode' with parameters.
      * <pre>

+ 0 - 40
src/main/java/org/codelibs/fess/mylasta/direction/FessEnv.java

@@ -35,12 +35,6 @@ public interface FessEnv {
     /** The key of the configuration. e.g. root@localhost */
     String MAIL_RETURN_PATH = "mail.return.path";
 
-    /** The key of the configuration. e.g. UTF-8 */
-    String TOMCAT_URIEncoding = "tomcat.URIEncoding";
-
-    /** The key of the configuration. e.g. true */
-    String TOMCAT_USE_BODY_ENCODING_FORURI = "tomcat.useBodyEncodingForURI";
-
     /**
      * Get the value of property as {@link String}.
      * @param propertyKey The key of the property. (NotNull)
@@ -162,28 +156,6 @@ public interface FessEnv {
      */
     String getMailReturnPath();
 
-    /**
-     * Get the value for the key 'tomcat.URIEncoding'. <br>
-     * The value is, e.g. UTF-8 <br>
-     * comment: ------
-     * @return The value of found property. (NotNull: if not found, exception but basically no way)
-     */
-    String getTomcatURIEncoding();
-
-    /**
-     * Get the value for the key 'tomcat.useBodyEncodingForURI'. <br>
-     * The value is, e.g. true <br>
-     * @return The value of found property. (NotNull: if not found, exception but basically no way)
-     */
-    String getTomcatUseBodyEncodingForuri();
-
-    /**
-     * Is the property for the key 'tomcat.useBodyEncodingForURI' true? <br>
-     * The value is, e.g. true <br>
-     * @return The determination, true or false. (if not found, exception but basically no way)
-     */
-    boolean isTomcatUseBodyEncodingForuri();
-
     /**
      * The simple implementation for configuration.
      * @author FreeGen
@@ -244,17 +216,5 @@ public interface FessEnv {
         public String getMailReturnPath() {
             return get(FessEnv.MAIL_RETURN_PATH);
         }
-
-        public String getTomcatURIEncoding() {
-            return get(FessEnv.TOMCAT_URIEncoding);
-        }
-
-        public String getTomcatUseBodyEncodingForuri() {
-            return get(FessEnv.TOMCAT_USE_BODY_ENCODING_FORURI);
-        }
-
-        public boolean isTomcatUseBodyEncodingForuri() {
-            return is(FessEnv.TOMCAT_USE_BODY_ENCODING_FORURI);
-        }
     }
 }

+ 15 - 0
src/main/java/org/codelibs/fess/util/StreamUtil.java

@@ -0,0 +1,15 @@
+package org.codelibs.fess.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.stream.Stream;
+
+public class StreamUtil {
+    public static <T> Stream<T> of(final T... values) {
+        if (values != null) {
+            return Arrays.stream(values);
+        } else {
+            return Collections.<T> emptyList().stream();
+        }
+    }
+}

+ 5 - 1
src/main/resources/fess_message.properties

@@ -125,13 +125,17 @@ errors.blank_password=Password is required.
 errors.invalid_confirm_password=Confirm Password does not match.
 errors.password_does_not_exist_in_session=Invalid password.
 
-errors.invalid_query_unknown=The given query is invalid.
+errors.invalid_query_unknown=The given query has unknown condition.
 errors.invalid_query_quoted=An invalid quote character is used.
 errors.invalid_query_curly_bracket=An invalid curly bracket character is used.
 errors.invalid_query_square_bracket=An invalid square bracket character is used.
 errors.invalid_query_parenthesis=An invalid parenthesis character is used.
 errors.invalid_query_num_range=An invalid range is used. The example of the range format is "field:[20020101 TO 20030101]".
 errors.invalid_query_str_range=An invalid range is used. The example of the range format is "field:'{'Aida TO Carmen'}'".
+errors.invalid_query_parse_error=The given query is invalid.
+errors.invalid_query_sort_value=The given sort ({0}) is invalid.
+errors.invalid_query_unsupported_sort_field=The given sort ({0}) is not supported.
+errors.invalid_query_unsupported_sort_order=The given sort order ({0}) is not supported.
 
 errors.crud_invalid_mode=Invalid mode(expected value is {0}, but it's {1}).
 errors.crud_failed_to_create_crud_table=Failed to create a new data.

+ 1694 - 0
src/test/java/org/codelibs/fess/helper/QueryHelperTest.java

@@ -0,0 +1,1694 @@
+/*
+ * Copyright 2009-2015 the 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.helper;
+
+import org.apache.lucene.queryparser.classic.ParseException;
+import org.codelibs.fess.unit.UnitFessTestCase;
+
+public class QueryHelperTest extends UnitFessTestCase {
+
+    private QueryHelper queryHelper;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        queryHelper = new QueryHelper();
+        FieldHelper fieldHelper = new FieldHelper();
+        registerMockInstance(fieldHelper);
+        registerMockInstance(new SystemHelper());
+        inject(queryHelper);
+        queryHelper.init();
+    }
+
+    public void test_dummy() throws ParseException {
+        System.out.println(queryHelper);
+    }
+
+    //    public void test_build() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("", queryHelper.buildQuery("").getQuery());
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery("QUERY").getQuery());
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery("QUERY ").getQuery());
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery(" QUERY").getQuery());
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1 QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1 QUERY2 ").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery(" QUERY1 QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildQuery("\"QUERY1 QUERY2\"").getQuery());
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildQuery("\"QUERY1 QUERY2\" ").getQuery());
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildQuery(" \"QUERY1 QUERY2\"").getQuery());
+    //
+    //            assertEquals("(title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("\"QUERY1 QUERY2\" QUERY3").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_build_fullwidthSpace() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1\u3000QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1\u3000QUERY2\u3000").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("\u3000QUERY1\u3000QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\\u3000QUERY2 OR content:QUERY1\\\u3000QUERY2",
+    //                    queryHelper.buildQuery("\"QUERY1\u3000QUERY2\"").getQuery());
+    //
+    //            assertEquals("(title:QUERY1\\\u3000QUERY2 OR content:QUERY1\\\u3000QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("\"QUERY1\u3000QUERY2\"\u3000QUERY3").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_build_prefix() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("mimetype:QUERY1", queryHelper.buildQuery("mimetype:QUERY1").getQuery());
+    //            assertEquals("mimetype:QUERY1 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1 QUERY2").getQuery());
+    //            assertEquals("mimetype:QUERY1 " + op + " (title:QUERY2 OR content:QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1 QUERY2 QUERY3").getQuery());
+    //            assertEquals("mimetype:QUERY1 " + op + " host:QUERY2 " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1 host:QUERY2 QUERY3").getQuery());
+    //            assertEquals("mimetype:QUERY1\\ QUERY2 " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("mimetype:\"QUERY1 QUERY2\" QUERY3").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_build_prefix_unknown() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("title:site\\: OR content:site\\:", queryHelper.buildQuery("site:").getQuery());
+    //            assertEquals("title:hoge\\:QUERY1 OR content:hoge\\:QUERY1", queryHelper.buildQuery("hoge:QUERY1").getQuery());
+    //            assertEquals("(title:hoge\\:QUERY1 OR content:hoge\\:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("hoge:QUERY1 QUERY2").getQuery());
+    //            assertEquals("(title:hoge\\:QUERY1 OR content:hoge\\:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2) " + op
+    //                    + " (title:QUERY3 OR content:QUERY3)", queryHelper.buildQuery("hoge:QUERY1 QUERY2 QUERY3").getQuery());
+    //            assertEquals(
+    //                    "(title:hoge\\:QUERY1 OR content:hoge\\:QUERY1) " + op + " host:QUERY2 " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("hoge:QUERY1 host:QUERY2 QUERY3").getQuery());
+    //            assertEquals("(title:hoge\\:QUERY1\\ QUERY2 OR content:hoge\\:QUERY1\\ QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("hoge:\"QUERY1 QUERY2\" QUERY3").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_build_roleType() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            queryHelper.roleQueryHelper = new RoleQueryHelper() {
+    //                @Override
+    //                public Set<String> build() {
+    //                    final Set<String> list = new LinkedHashSet<>();
+    //                    list.add("guest");
+    //                    return list;
+    //                }
+    //            };
+    //
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("", queryHelper.build("", true).getQuery());
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.build("QUERY", true).getQuery());
+    //            assertEquals("role:guest", queryHelper.build("QUERY", true).getFilterQueries()[0]);
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.build("QUERY1 QUERY2", true).getQuery());
+    //            assertEquals("role:guest", queryHelper.build("QUERY1 QUERY2", true).getFilterQueries()[0]);
+    //
+    //            queryHelper.roleQueryHelper = new RoleQueryHelper() {
+    //                @Override
+    //                public Set<String> build() {
+    //                    final Set<String> list = new LinkedHashSet<>();
+    //                    list.add("guest");
+    //                    list.add("admin");
+    //                    return list;
+    //                }
+    //            };
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.build("QUERY", true).getQuery());
+    //            assertEquals("role:guest OR role:admin", queryHelper.build("QUERY", true).getFilterQueries()[0]);
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.build("QUERY1 QUERY2", true).getQuery());
+    //            assertEquals("role:guest OR role:admin", queryHelper.build("QUERY1 QUERY2", true).getFilterQueries()[0]);
+    //        }
+    //    }
+    //
+    //    public void test_sortField() {
+    //        String query;
+    //        QueryContext queryContext;
+    //
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            query = "";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("", queryContext.getQuery());
+    //            assertEquals(0, queryContext.getSortFields().length);
+    //
+    //            query = "sort:content_length";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("", queryContext.getQuery());
+    //            assertEquals(1, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //
+    //            query = "sort:content_length.desc";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("", queryContext.getQuery());
+    //            assertEquals(1, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.DESC, queryContext.getSortFields()[0].getOrder());
+    //
+    //            query = "sort:content_length.asc,last_modified";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("", queryContext.getQuery());
+    //            assertEquals(2, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //            assertEquals("last_modified", queryContext.getSortFields()[1].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[1].getOrder());
+    //
+    //            query = "QUERY sort:content_length";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("title:QUERY OR content:QUERY", queryContext.getQuery());
+    //            assertEquals(1, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //
+    //            query = "QUERY sort:content_length.desc";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("title:QUERY OR content:QUERY", queryContext.getQuery());
+    //            assertEquals(1, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.DESC, queryContext.getSortFields()[0].getOrder());
+    //
+    //            query = "QUERY sort:content_length.asc,last_modified";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("title:QUERY OR content:QUERY", queryContext.getQuery());
+    //            assertEquals(2, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //            assertEquals("last_modified", queryContext.getSortFields()[1].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[1].getOrder());
+    //
+    //            query = "QUERY mimetype:QUERY1 sort:content_length";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " mimetype:QUERY1", queryContext.getQuery());
+    //            assertEquals(1, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //
+    //            query = "QUERY sort:content_length.desc  mimetype:QUERY1";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " mimetype:QUERY1", queryContext.getQuery());
+    //            assertEquals(1, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.DESC, queryContext.getSortFields()[0].getOrder());
+    //
+    //            query = "QUERY sort:content_length.asc,last_modified mimetype:QUERY1";
+    //            queryContext = queryHelper.buildQuery(query);
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " mimetype:QUERY1", queryContext.getQuery());
+    //            assertEquals(2, queryContext.getSortFields().length);
+    //            assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //            assertEquals("last_modified", queryContext.getSortFields()[1].getField());
+    //            assertEquals(Constants.ASC, queryContext.getSortFields()[1].getOrder());
+    //        }
+    //    }
+    //
+    //    public void test_sortField_invalid() {
+    //        String query;
+    //        QueryContext queryContext;
+    //
+    //        query = "sort:hoge";
+    //        queryContext = queryHelper.buildQuery(query);
+    //        assertEquals("", queryContext.getQuery());
+    //        assertEquals(0, queryContext.getSortFields().length);
+    //
+    //        query = "sort:content_length.hoge";
+    //        queryContext = queryHelper.buildQuery(query);
+    //        assertEquals("", queryContext.getQuery());
+    //        assertEquals(0, queryContext.getSortFields().length);
+    //
+    //        query = "sort:content_length.asc,hoge";
+    //        queryContext = queryHelper.buildQuery(query);
+    //        assertEquals("", queryContext.getQuery());
+    //        assertEquals(1, queryContext.getSortFields().length);
+    //        assertEquals("content_length", queryContext.getSortFields()[0].getField());
+    //        assertEquals(Constants.ASC, queryContext.getSortFields()[0].getOrder());
+    //    }
+    //
+    //    public void test_wildcardSearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // *
+    //
+    //            assertEquals("title:\\* OR content:\\*", queryHelper.buildQuery("*").getQuery());
+    //            assertEquals("title:QUERY* OR content:QUERY*", queryHelper.buildQuery("QUERY* ").getQuery());
+    //            assertEquals("title:Q*ERY OR content:Q*ERY", queryHelper.buildQuery(" Q*ERY").getQuery());
+    //
+    //            assertEquals("(title:Q*ERY1 OR content:Q*ERY1) " + op + " (title:Q*ERY2 OR content:Q*ERY2)",
+    //                    queryHelper.buildQuery("Q*ERY1 Q*ERY2").getQuery());
+    //
+    //            assertEquals("title:Q*ERY1\\ Q*ERY2 OR content:Q*ERY1\\ Q*ERY2", queryHelper.buildQuery("\"Q*ERY1 Q*ERY2\"").getQuery());
+    //
+    //            assertEquals("(title:Q*ERY1\\ Q*ERY2 OR content:Q*ERY1\\ Q*ERY2) " + op + " (title:Q*ERY3 OR content:Q*ERY3)",
+    //                    queryHelper.buildQuery("\"Q*ERY1 Q*ERY2\" Q*ERY3").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1*", queryHelper.buildQuery("mimetype:QUERY1*").getQuery());
+    //            assertEquals("mimetype:QUERY1* " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1* QUERY2").getQuery());
+    //
+    //            // ?
+    //
+    //            assertEquals("title:\\? OR content:\\?", queryHelper.buildQuery("?").getQuery());
+    //            assertEquals("title:QUERY? OR content:QUERY?", queryHelper.buildQuery("QUERY? ").getQuery());
+    //            assertEquals("title:Q?ERY OR content:Q?ERY", queryHelper.buildQuery(" Q?ERY").getQuery());
+    //
+    //            assertEquals("(title:Q?ERY1 OR content:Q?ERY1) " + op + " (title:Q?ERY2 OR content:Q?ERY2)",
+    //                    queryHelper.buildQuery("Q?ERY1 Q?ERY2").getQuery());
+    //
+    //            assertEquals("title:Q?ERY1\\ Q?ERY2 OR content:Q?ERY1\\ Q?ERY2", queryHelper.buildQuery("\"Q?ERY1 Q?ERY2\"").getQuery());
+    //
+    //            assertEquals("(title:Q?ERY1\\ Q?ERY2 OR content:Q?ERY1\\ Q?ERY2) " + op + " (title:Q?ERY3 OR content:Q?ERY3)",
+    //                    queryHelper.buildQuery("\"Q?ERY1 Q?ERY2\" Q?ERY3").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1?", queryHelper.buildQuery("mimetype:QUERY1?").getQuery());
+    //            assertEquals("mimetype:QUERY1? " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1? QUERY2").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_fuzzySearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ~
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery("QUERY~").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~ QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~ QUERY2~").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1~", queryHelper.buildQuery("mimetype:QUERY1~").getQuery());
+    //            assertEquals("mimetype:QUERY1~ " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1~ QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildQuery("\"QUERY1 QUERY2\"~").getQuery());
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildQuery("\"QUERY1~\"").getQuery());
+    //
+    //            // ~0.8
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery("QUERY~0.8").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~0.8 QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~0.5 QUERY2~0.8").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1~0.8", queryHelper.buildQuery("mimetype:QUERY1~0.8").getQuery());
+    //            assertEquals("mimetype:QUERY1~0.8 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1~0.8 QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildQuery("\"QUERY1 QUERY2\"~0.8").getQuery());
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildQuery("\"QUERY1~0.8\"").getQuery());
+    //
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildQuery("\"QUERY1~0.8a\"").getQuery());
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildQuery("\"QUERY1~a\"").getQuery());
+    //        }
+    //
+    //        getMockRequest().setLocale(Locale.JAPANESE);
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ~
+    //
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY~", queryHelper.buildQuery("QUERY~").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~ QUERY2").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2~)",
+    //                    queryHelper.buildQuery("QUERY1~ QUERY2~").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1~", queryHelper.buildQuery("mimetype:QUERY1~").getQuery());
+    //            assertEquals("mimetype:QUERY1~ " + op + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1~ QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2 OR content_ja:QUERY1\\ QUERY2~",
+    //                    queryHelper.buildQuery("\"QUERY1 QUERY2\"~").getQuery());
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~", queryHelper.buildQuery("\"QUERY1~\"").getQuery());
+    //
+    //            // ~0.8
+    //
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY~0.8", queryHelper.buildQuery("QUERY~0.8").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.8) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~0.8 QUERY2").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.5) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2~0.8)",
+    //                    queryHelper.buildQuery("QUERY1~0.5 QUERY2~0.8").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1~0.8", queryHelper.buildQuery("mimetype:QUERY1~0.8").getQuery());
+    //            assertEquals("mimetype:QUERY1~0.8 " + op + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1~0.8 QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2 OR content_ja:QUERY1\\ QUERY2~0.8",
+    //                    queryHelper.buildQuery("\"QUERY1 QUERY2\"~0.8").getQuery());
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.8", queryHelper.buildQuery("\"QUERY1~0.8\"").getQuery());
+    //
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.8", queryHelper.buildQuery("\"QUERY1~0.8a\"").getQuery());
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~", queryHelper.buildQuery("\"QUERY1~a\"").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_proximitySearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ~10
+    //            assertEquals("title:\"QUERY\"~10 OR content:\"QUERY\"~10", queryHelper.buildQuery("QUERY~10").getQuery());
+    //            assertEquals("title:\"QUERY\"~1 OR content:\"QUERY\"~1", queryHelper.buildQuery("QUERY~1").getQuery());
+    //            assertEquals("title:\"QUERY\"~5 OR content:\"QUERY\"~5", queryHelper.buildQuery("QUERY~5.5").getQuery());
+    //            assertEquals("(title:\"QUERY1\"~10 OR content:\"QUERY1\"~10) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1~10 QUERY2").getQuery());
+    //            assertEquals("(title:\"QUERY1\"~5 OR content:\"QUERY1\"~5) " + op + " (title:\"QUERY2\"~10 OR content:\"QUERY2\"~10)",
+    //                    queryHelper.buildQuery("QUERY1~5 QUERY2~10").getQuery());
+    //
+    //            assertEquals("mimetype:\"QUERY1\"~10", queryHelper.buildQuery("mimetype:QUERY1~10").getQuery());
+    //            assertEquals("mimetype:\"QUERY1\"~10 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1~10 QUERY2").getQuery());
+    //
+    //            assertEquals("title:\"QUERY1\\ QUERY2\"~10 OR content:\"QUERY1\\ QUERY2\"~10",
+    //                    queryHelper.buildQuery("\"QUERY1 QUERY2\"~10").getQuery());
+    //            assertEquals("title:\"QUERY1\"~10 OR content:\"QUERY1\"~10", queryHelper.buildQuery("\"QUERY1~10\"").getQuery());
+    //
+    //            assertEquals("title:\"QUERY1\"~10 OR content:\"QUERY1\"~10", queryHelper.buildQuery("\"QUERY1~10a\"").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_rangeSearches() {
+    //        String rangeQuery;
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // mod_date:[20020101 TO 20030101]
+    //            assertEquals("title:[20020101 TO 20030101] OR content:[20020101 TO 20030101]",
+    //                    queryHelper.buildQuery("[20020101 TO 20030101]").getQuery());
+    //            assertEquals("last_modified:[20020101 TO 20030101]", queryHelper.buildQuery("last_modified:[20020101 TO 20030101]").getQuery());
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " last_modified:[20020101 TO 20030101]",
+    //                    queryHelper.buildQuery("QUERY last_modified:[20020101 TO 20030101]").getQuery());
+    //            assertEquals("title:{Aida TO Carmen} OR content:{Aida TO Carmen}", queryHelper.buildQuery("{Aida TO Carmen}").getQuery());
+    //            assertEquals("last_modified:{Aida TO Carmen}", queryHelper.buildQuery("last_modified:{Aida TO Carmen}").getQuery());
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " title:{Aida TO Carmen}",
+    //                    queryHelper.buildQuery("QUERY title:{Aida TO Carmen}").getQuery());
+    //            assertEquals("last_modified:[20020101 TO abc]", queryHelper.buildQuery("last_modified:[20020101 TO abc]").getQuery());
+    //            assertEquals("last_modified:[abc TO 20020101]", queryHelper.buildQuery("last_modified:[abc TO 20020101]").getQuery());
+    //            assertEquals("last_modified:[20020101 TO *]", queryHelper.buildQuery("last_modified:[20020101 TO *]").getQuery());
+    //            assertEquals("last_modified:[* TO 20020101]", queryHelper.buildQuery("last_modified:[* TO 20020101]").getQuery());
+    //
+    //            rangeQuery = "(content:[1 TO 2] OR content:[3 TO 4]) " + op + " (content:[5 TO 6] OR content:[7 TO 8])";
+    //            assertEquals(rangeQuery, queryHelper.buildQuery(rangeQuery).getQuery());
+    //
+    //            try {
+    //                queryHelper.buildQuery("last_modified:[20020101 TO]").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //            try {
+    //                queryHelper.buildQuery("last_modified:[TO 20030101]").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //            try {
+    //                queryHelper.buildQuery("last_modified:[20020101]").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //            try {
+    //                queryHelper.buildQuery("last_modified:[20030101]").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //
+    //            // mod_date:{20020101 TO 20030101}
+    //            assertEquals("title:{20020101 TO 20030101} OR content:{20020101 TO 20030101}",
+    //                    queryHelper.buildQuery("{20020101 TO 20030101}").getQuery());
+    //            assertEquals("last_modified:{20020101 TO 20030101}", queryHelper.buildQuery("last_modified:{20020101 TO 20030101}").getQuery());
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " last_modified:{20020101 TO 20030101}",
+    //                    queryHelper.buildQuery("QUERY last_modified:{20020101 TO 20030101}").getQuery());
+    //            assertEquals("title:{Aida TO Carmen} OR content:{Aida TO Carmen}", queryHelper.buildQuery("{Aida TO Carmen}").getQuery());
+    //            assertEquals("last_modified:{Aida TO Carmen}", queryHelper.buildQuery("last_modified:{Aida TO Carmen}").getQuery());
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " title:{Aida TO Carmen}",
+    //                    queryHelper.buildQuery("QUERY title:{Aida TO Carmen}").getQuery());
+    //            assertEquals("last_modified:{20020101 TO abc}", queryHelper.buildQuery("last_modified:{20020101 TO abc}").getQuery());
+    //            assertEquals("last_modified:{abc TO 20020101}", queryHelper.buildQuery("last_modified:{abc TO 20020101}").getQuery());
+    //            assertEquals("last_modified:{20020101 TO *}", queryHelper.buildQuery("last_modified:{20020101 TO *}").getQuery());
+    //            assertEquals("last_modified:{* TO 20020101}", queryHelper.buildQuery("last_modified:{* TO 20020101}").getQuery());
+    //
+    //            rangeQuery = "(content:{1 TO 2} OR content:{3 TO 4}) " + op + " (content:{5 TO 6} OR content:{7 TO 8})";
+    //            assertEquals(rangeQuery, queryHelper.buildQuery(rangeQuery).getQuery());
+    //
+    //            try {
+    //                queryHelper.buildQuery("last_modified:{20020101 TO}").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //            try {
+    //                queryHelper.buildQuery("last_modified:{TO 20030101}").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //            try {
+    //                queryHelper.buildQuery("last_modified:{20020101}").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //            try {
+    //                queryHelper.buildQuery("last_modified:{20030101}").getQuery();
+    //                fail();
+    //            } catch (final InvalidQueryException e) {}
+    //
+    //            rangeQuery = "(content:[1 TO 2] OR content:{3 TO 4}) " + op + " (content:{5 TO 6} OR content:[7 TO 8])";
+    //            assertEquals(rangeQuery, queryHelper.buildQuery(rangeQuery).getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_boosting() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ^1000 ""^1000
+    //            assertEquals("title:QUERY^1000 OR content:QUERY^1000", queryHelper.buildQuery("QUERY^1000").getQuery());
+    //            assertEquals("(title:QUERY1^1000 OR content:QUERY1^1000) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1^1000 QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1^500 OR content:QUERY1^500) " + op + " (title:QUERY2^1000 OR content:QUERY2^1000)",
+    //                    queryHelper.buildQuery("QUERY1^500 QUERY2^1000").getQuery());
+    //
+    //            assertEquals("mimetype:QUERY1^1000", queryHelper.buildQuery("mimetype:QUERY1^1000").getQuery());
+    //            assertEquals("mimetype:QUERY1^1000 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("mimetype:QUERY1^1000 QUERY2").getQuery());
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2^1000 OR content:QUERY1\\ QUERY2^1000",
+    //                    queryHelper.buildQuery("\"QUERY1 QUERY2\"^1000").getQuery());
+    //            assertEquals("title:QUERY1^1000 OR content:QUERY1^1000", queryHelper.buildQuery("\"QUERY1^1000\"").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_reserved() {
+    //        for (int i = 0; i < Constants.RESERVED.length - 1; i++) {
+    //            try {
+    //                assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                        queryHelper.buildQuery(Constants.RESERVED[i]).getQuery());
+    //            } catch (final InvalidQueryException e) {
+    //                if (Constants.RESERVED[i].equals("\"") && e.getMessageCode().equals("errors.invalid_query_quoted")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildQuery("\\" + Constants.RESERVED[i]).getQuery());
+    //                    continue;
+    //                } else if (Constants.RESERVED[i].equals("{") && e.getMessageCode().equals("errors.invalid_query_curly_bracket")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildQuery("\\" + Constants.RESERVED[i]).getQuery());
+    //                    continue;
+    //                } else if (Constants.RESERVED[i].equals("[") && e.getMessageCode().equals("errors.invalid_query_square_bracket")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildQuery("\\" + Constants.RESERVED[i]).getQuery());
+    //                    continue;
+    //                } else if (Constants.RESERVED[i].equals("(") && e.getMessageCode().equals("errors.invalid_query_parenthesis")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildQuery("\\" + Constants.RESERVED[i]).getQuery());
+    //                    continue;
+    //                }
+    //            }
+    //        }
+    //        assertEquals("title:\\: OR content:\\:", queryHelper.buildQuery(":").getQuery());
+    //    }
+    //
+    //    public void test_or() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery("OR QUERY").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1 OR QUERY2").getQuery());
+    //            assertEquals("title:QUERY", queryHelper.buildQuery("OR title:QUERY").getQuery());
+    //            assertEquals("title:QUERY1 OR title:QUERY2", queryHelper.buildQuery("title:QUERY1 OR title:QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR title:QUERY2", queryHelper.buildQuery("QUERY1 OR title:QUERY2").getQuery());
+    //            assertEquals("mimetype:QUERY1 OR title:QUERY2", queryHelper.buildQuery("mimetype:QUERY1 OR title:QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR (title:QUERY2 OR content:QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("QUERY1 OR QUERY2 QUERY3").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR (title:QUERY2 OR content:QUERY2) OR (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("QUERY1 OR QUERY2 OR QUERY3").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_and() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildQuery("AND QUERY").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) AND (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1 AND QUERY2").getQuery());
+    //            assertEquals("title:QUERY", queryHelper.buildQuery("AND title:QUERY").getQuery());
+    //            assertEquals("title:QUERY1 AND title:QUERY2", queryHelper.buildQuery("title:QUERY1 AND title:QUERY2").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) AND title:QUERY2", queryHelper.buildQuery("QUERY1 AND title:QUERY2").getQuery());
+    //            assertEquals("mimetype:QUERY1 AND title:QUERY2", queryHelper.buildQuery("mimetype:QUERY1 AND title:QUERY2").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1) AND (title:QUERY2 OR content:QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("QUERY1 AND QUERY2 QUERY3").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2) AND (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("QUERY1 QUERY2 AND QUERY3").getQuery());
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) AND (title:QUERY2 OR content:QUERY2) AND (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildQuery("QUERY1 AND QUERY2 AND QUERY3").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_not() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("NOT (title:QUERY OR content:QUERY)", queryHelper.buildQuery("NOT QUERY").getQuery());
+    //            assertEquals("NOT title:QUERY", queryHelper.buildQuery("NOT title:QUERY").getQuery());
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT (title:QUERY1 OR content:QUERY1)",
+    //                    queryHelper.buildQuery("NOT QUERY1 QUERY2").getQuery());
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT (title:QUERY1 OR content:QUERY1)",
+    //                    queryHelper.buildQuery("NOT QUERY1 OR QUERY2").getQuery());
+    //            assertEquals("NOT (title:QUERY1 OR content:QUERY1) " + op + " NOT (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("NOT QUERY1 NOT QUERY2").getQuery());
+    //            assertEquals("NOT (title:QUERY1 OR content:QUERY1) " + op + " NOT (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildQuery("NOT QUERY1 OR NOT QUERY2").getQuery());
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT (title:QUERY1 OR content:QUERY1) " + op
+    //                    + " NOT (title:QUERY3 OR content:QUERY3)", queryHelper.buildQuery("NOT QUERY1 QUERY2 NOT QUERY3").getQuery());
+    //            assertEquals("NOT mimetype:QUERY", queryHelper.buildQuery("NOT mimetype:QUERY").getQuery());
+    //            assertEquals("NOT mimetype:QUERY1 " + op + " NOT title:QUERY2",
+    //                    queryHelper.buildQuery("NOT mimetype:QUERY1 NOT title:QUERY2").getQuery());
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT mimetype:QUERY1",
+    //                    queryHelper.buildQuery("NOT mimetype:QUERY1 QUERY2").getQuery());
+    //            assertEquals("mimetype:QUERY2 " + op + " NOT (title:QUERY1 OR content:QUERY1)",
+    //                    queryHelper.buildQuery("NOT QUERY1 mimetype:QUERY2").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_escapeValue() {
+    //        final String[] targets =
+    //                new String[] { "+", "-", "&&", "||", "!", "(", ")", "{", "}", "[", "]", "^", "\"", "~", ":", "\\", " ", "\u3000" };
+    //        for (final String target : targets) {
+    //            assertEquals("abc\\" + target + "123", QueryUtil.escapeValue("abc" + target + "123"));
+    //        }
+    //        for (final String target : targets) {
+    //            assertEquals("abc\\" + target, QueryUtil.escapeValue("abc" + target));
+    //        }
+    //        for (final String target : targets) {
+    //            assertEquals("\\" + target + "123", QueryUtil.escapeValue(target + "123"));
+    //        }
+    //        for (final String target : targets) {
+    //            assertEquals("abc\\" + target + "123\\" + target + "ABC", QueryUtil.escapeValue("abc" + target + "123" + target + "ABC"));
+    //        }
+    //    }
+    //
+    //    public void test_escapeRangeValue() {
+    //        final String[] targets = new String[] { "&&", "||", "!", "(", ")", "{", "}", "[", "]", "\"", "~", ":", "\\", " ", "\u3000" };
+    //        for (final String target : targets) {
+    //            assertEquals("abc\\" + target + "123", QueryUtil.escapeValue("abc" + target + "123"));
+    //        }
+    //        for (final String target : targets) {
+    //            assertEquals("abc\\" + target, QueryUtil.escapeValue("abc" + target));
+    //        }
+    //        for (final String target : targets) {
+    //            assertEquals("\\" + target + "123", QueryUtil.escapeValue(target + "123"));
+    //        }
+    //        for (final String target : targets) {
+    //            assertEquals("abc\\" + target + "123\\" + target + "ABC", QueryUtil.escapeValue("abc" + target + "123" + target + "ABC"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("", queryHelper.buildFacetQuery(""));
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery("QUERY"));
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery("QUERY "));
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery(" QUERY"));
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1 QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1 QUERY2 "));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery(" QUERY1 QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildFacetQuery("\"QUERY1 QUERY2\""));
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildFacetQuery("\"QUERY1 QUERY2\" "));
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildFacetQuery(" \"QUERY1 QUERY2\""));
+    //
+    //            assertEquals("(title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("\"QUERY1 QUERY2\" QUERY3"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_fullwidthSpace() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1\u3000QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1\u3000QUERY2\u3000"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("\u3000QUERY1\u3000QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\\u3000QUERY2 OR content:QUERY1\\\u3000QUERY2",
+    //                    queryHelper.buildFacetQuery("\"QUERY1\u3000QUERY2\""));
+    //
+    //            assertEquals("(title:QUERY1\\\u3000QUERY2 OR content:QUERY1\\\u3000QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("\"QUERY1\u3000QUERY2\"\u3000QUERY3"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_prefix() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("mimetype:QUERY1", queryHelper.buildFacetQuery("mimetype:QUERY1"));
+    //            assertEquals("mimetype:QUERY1 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1 QUERY2"));
+    //            assertEquals("mimetype:QUERY1 " + op + " (title:QUERY2 OR content:QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1 QUERY2 QUERY3"));
+    //            assertEquals("mimetype:QUERY1 " + op + " host:QUERY2 " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1 host:QUERY2 QUERY3"));
+    //            assertEquals("mimetype:QUERY1\\ QUERY2 " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("mimetype:\"QUERY1 QUERY2\" QUERY3"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_prefix_unknown() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("title:site\\: OR content:site\\:", queryHelper.buildFacetQuery("site:"));
+    //            assertEquals("title:hoge\\:QUERY1 OR content:hoge\\:QUERY1", queryHelper.buildFacetQuery("hoge:QUERY1"));
+    //            assertEquals("(title:hoge\\:QUERY1 OR content:hoge\\:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("hoge:QUERY1 QUERY2"));
+    //            assertEquals("(title:hoge\\:QUERY1 OR content:hoge\\:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2) " + op
+    //                    + " (title:QUERY3 OR content:QUERY3)", queryHelper.buildFacetQuery("hoge:QUERY1 QUERY2 QUERY3"));
+    //            assertEquals(
+    //                    "(title:hoge\\:QUERY1 OR content:hoge\\:QUERY1) " + op + " host:QUERY2 " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("hoge:QUERY1 host:QUERY2 QUERY3"));
+    //            assertEquals("(title:hoge\\:QUERY1\\ QUERY2 OR content:hoge\\:QUERY1\\ QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("hoge:\"QUERY1 QUERY2\" QUERY3"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_sortField() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            String query;
+    //            String searchQuery;
+    //
+    //            query = "";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("", searchQuery);
+    //
+    //            query = "sort:content_length";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("", searchQuery);
+    //
+    //            query = "sort:content_length.desc";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("", searchQuery);
+    //
+    //            query = "sort:content_length.asc,last_modified";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("", searchQuery);
+    //
+    //            query = "QUERY sort:content_length";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("title:QUERY OR content:QUERY", searchQuery);
+    //
+    //            query = "QUERY sort:content_length.desc";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("title:QUERY OR content:QUERY", searchQuery);
+    //
+    //            query = "QUERY sort:content_length.asc,last_modified";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("title:QUERY OR content:QUERY", searchQuery);
+    //
+    //            query = "QUERY mimetype:QUERY1 sort:content_length";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " mimetype:QUERY1", searchQuery);
+    //
+    //            query = "QUERY sort:content_length.desc  mimetype:QUERY1";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " mimetype:QUERY1", searchQuery);
+    //
+    //            query = "QUERY sort:content_length.asc,last_modified mimetype:QUERY1";
+    //            searchQuery = queryHelper.buildFacetQuery(query);
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " mimetype:QUERY1", searchQuery);
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_sortField_invalid() {
+    //        String query;
+    //        String searchQuery;
+    //
+    //        query = "sort:hoge";
+    //        searchQuery = queryHelper.buildFacetQuery(query);
+    //        assertEquals("", searchQuery);
+    //
+    //        query = "sort:content_length.hoge";
+    //        searchQuery = queryHelper.buildFacetQuery(query);
+    //        assertEquals("", searchQuery);
+    //
+    //        query = "sort:content_length.asc,hoge";
+    //        searchQuery = queryHelper.buildFacetQuery(query);
+    //        assertEquals("", searchQuery);
+    //    }
+    //
+    //    public void test_buildFacet_wildcardSearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // *
+    //
+    //            assertEquals("title:\\* OR content:\\*", queryHelper.buildFacetQuery("*"));
+    //            assertEquals("title:QUERY* OR content:QUERY*", queryHelper.buildFacetQuery("QUERY* "));
+    //            assertEquals("title:Q*ERY OR content:Q*ERY", queryHelper.buildFacetQuery(" Q*ERY"));
+    //
+    //            assertEquals("(title:Q*ERY1 OR content:Q*ERY1) " + op + " (title:Q*ERY2 OR content:Q*ERY2)",
+    //                    queryHelper.buildFacetQuery("Q*ERY1 Q*ERY2"));
+    //
+    //            assertEquals("title:Q*ERY1\\ Q*ERY2 OR content:Q*ERY1\\ Q*ERY2", queryHelper.buildFacetQuery("\"Q*ERY1 Q*ERY2\""));
+    //
+    //            assertEquals("(title:Q*ERY1\\ Q*ERY2 OR content:Q*ERY1\\ Q*ERY2) " + op + " (title:Q*ERY3 OR content:Q*ERY3)",
+    //                    queryHelper.buildFacetQuery("\"Q*ERY1 Q*ERY2\" Q*ERY3"));
+    //
+    //            assertEquals("mimetype:QUERY1*", queryHelper.buildFacetQuery("mimetype:QUERY1*"));
+    //            assertEquals("mimetype:QUERY1* " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1* QUERY2"));
+    //
+    //            assertEquals("title:\\*QUERY1 OR content:\\*QUERY1", queryHelper.buildFacetQuery("*QUERY1"));
+    //            assertEquals("title:\\*QUERY1* OR content:\\*QUERY1*", queryHelper.buildFacetQuery("*QUERY1*"));
+    //
+    //            // ?
+    //
+    //            assertEquals("title:\\? OR content:\\?", queryHelper.buildFacetQuery("?"));
+    //            assertEquals("title:QUERY? OR content:QUERY?", queryHelper.buildFacetQuery("QUERY? "));
+    //            assertEquals("title:Q?ERY OR content:Q?ERY", queryHelper.buildFacetQuery(" Q?ERY"));
+    //
+    //            assertEquals("(title:Q?ERY1 OR content:Q?ERY1) " + op + " (title:Q?ERY2 OR content:Q?ERY2)",
+    //                    queryHelper.buildFacetQuery("Q?ERY1 Q?ERY2"));
+    //
+    //            assertEquals("title:Q?ERY1\\ Q?ERY2 OR content:Q?ERY1\\ Q?ERY2", queryHelper.buildFacetQuery("\"Q?ERY1 Q?ERY2\""));
+    //
+    //            assertEquals("(title:Q?ERY1\\ Q?ERY2 OR content:Q?ERY1\\ Q?ERY2) " + op + " (title:Q?ERY3 OR content:Q?ERY3)",
+    //                    queryHelper.buildFacetQuery("\"Q?ERY1 Q?ERY2\" Q?ERY3"));
+    //
+    //            assertEquals("mimetype:QUERY1?", queryHelper.buildFacetQuery("mimetype:QUERY1?"));
+    //            assertEquals("mimetype:QUERY1? " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1? QUERY2"));
+    //
+    //            assertEquals("title:\\?QUERY1 OR content:\\?QUERY1", queryHelper.buildFacetQuery("?QUERY1"));
+    //            assertEquals("title:\\?QUERY1? OR content:\\?QUERY1?", queryHelper.buildFacetQuery("?QUERY1?"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_fuzzySearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ~
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery("QUERY~"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1~ QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1~ QUERY2~"));
+    //
+    //            assertEquals("mimetype:QUERY1~", queryHelper.buildFacetQuery("mimetype:QUERY1~"));
+    //            assertEquals("mimetype:QUERY1~ " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1~ QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildFacetQuery("\"QUERY1 QUERY2\"~"));
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildFacetQuery("\"QUERY1~\""));
+    //
+    //            // ~0.8
+    //
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery("QUERY~0.8"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1~0.8 QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1~0.5 QUERY2~0.8"));
+    //
+    //            assertEquals("mimetype:QUERY1~0.8", queryHelper.buildFacetQuery("mimetype:QUERY1~0.8"));
+    //            assertEquals("mimetype:QUERY1~0.8 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1~0.8 QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2", queryHelper.buildFacetQuery("\"QUERY1 QUERY2\"~0.8"));
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildFacetQuery("\"QUERY1~0.8\""));
+    //
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildFacetQuery("\"QUERY1~0.8a\""));
+    //            assertEquals("title:QUERY1 OR content:QUERY1", queryHelper.buildFacetQuery("\"QUERY1~a\""));
+    //        }
+    //
+    //        getMockRequest().setLocale(Locale.JAPANESE);
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ~
+    //
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY~", queryHelper.buildFacetQuery("QUERY~"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~) " + op
+    //                    + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)", queryHelper.buildFacetQuery("QUERY1~ QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~) " + op
+    //                    + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2~)", queryHelper.buildFacetQuery("QUERY1~ QUERY2~"));
+    //
+    //            assertEquals("mimetype:QUERY1~", queryHelper.buildFacetQuery("mimetype:QUERY1~"));
+    //            assertEquals("mimetype:QUERY1~ " + op + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1~ QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2 OR content_ja:QUERY1\\ QUERY2~",
+    //                    queryHelper.buildFacetQuery("\"QUERY1 QUERY2\"~"));
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~", queryHelper.buildFacetQuery("\"QUERY1~\""));
+    //
+    //            // ~0.8
+    //
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY~0.8", queryHelper.buildFacetQuery("QUERY~0.8"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.8) " + op
+    //                    + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)", queryHelper.buildFacetQuery("QUERY1~0.8 QUERY2"));
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.5) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2~0.8)",
+    //                    queryHelper.buildFacetQuery("QUERY1~0.5 QUERY2~0.8"));
+    //
+    //            assertEquals("mimetype:QUERY1~0.8", queryHelper.buildFacetQuery("mimetype:QUERY1~0.8"));
+    //            assertEquals("mimetype:QUERY1~0.8 " + op + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1~0.8 QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2 OR content:QUERY1\\ QUERY2 OR content_ja:QUERY1\\ QUERY2~0.8",
+    //                    queryHelper.buildFacetQuery("\"QUERY1 QUERY2\"~0.8"));
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.8", queryHelper.buildFacetQuery("\"QUERY1~0.8\""));
+    //
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~0.8", queryHelper.buildFacetQuery("\"QUERY1~0.8a\""));
+    //            assertEquals("title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1~", queryHelper.buildFacetQuery("\"QUERY1~a\""));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_proximitySearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ~10
+    //            assertEquals("title:\"QUERY\"~10 OR content:\"QUERY\"~10", queryHelper.buildFacetQuery("QUERY~10"));
+    //            assertEquals("title:\"QUERY\"~1 OR content:\"QUERY\"~1", queryHelper.buildFacetQuery("QUERY~1"));
+    //            assertEquals("title:\"QUERY\"~5 OR content:\"QUERY\"~5", queryHelper.buildFacetQuery("QUERY~5.5"));
+    //            assertEquals("(title:\"QUERY1\"~10 OR content:\"QUERY1\"~10) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1~10 QUERY2"));
+    //            assertEquals("(title:\"QUERY1\"~5 OR content:\"QUERY1\"~5) " + op + " (title:\"QUERY2\"~10 OR content:\"QUERY2\"~10)",
+    //                    queryHelper.buildFacetQuery("QUERY1~5 QUERY2~10"));
+    //
+    //            assertEquals("mimetype:\"QUERY1\"~10", queryHelper.buildFacetQuery("mimetype:QUERY1~10"));
+    //            assertEquals("mimetype:\"QUERY1\"~10 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1~10 QUERY2"));
+    //
+    //            assertEquals("title:\"QUERY1\\ QUERY2\"~10 OR content:\"QUERY1\\ QUERY2\"~10",
+    //                    queryHelper.buildFacetQuery("\"QUERY1 QUERY2\"~10"));
+    //            assertEquals("title:\"QUERY1\"~10 OR content:\"QUERY1\"~10", queryHelper.buildFacetQuery("\"QUERY1~10\""));
+    //
+    //            assertEquals("title:\"QUERY1\"~10 OR content:\"QUERY1\"~10", queryHelper.buildFacetQuery("\"QUERY1~10a\""));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_rangeSearches() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // mod_date:[20020101 TO 20030101]
+    //            assertEquals("title:[20020101 TO 20030101] OR content:[20020101 TO 20030101]",
+    //                    queryHelper.buildFacetQuery("[20020101 TO 20030101]"));
+    //            assertEquals("last_modified:[20020101 TO 20030101]", queryHelper.buildFacetQuery("last_modified:[20020101 TO 20030101]"));
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " last_modified:[20020101 TO 20030101]",
+    //                    queryHelper.buildFacetQuery("QUERY last_modified:[20020101 TO 20030101]"));
+    //
+    //            // TODO more..
+    //
+    //            // title:{Aida TO Carmen}
+    //            assertEquals("title:{Aida TO Carmen} OR content:{Aida TO Carmen}", queryHelper.buildFacetQuery("{Aida TO Carmen}"));
+    //            assertEquals("last_modified:{Aida TO Carmen}", queryHelper.buildFacetQuery("last_modified:{Aida TO Carmen}"));
+    //            assertEquals("(title:QUERY OR content:QUERY) " + op + " title:{Aida TO Carmen}",
+    //                    queryHelper.buildFacetQuery("QUERY title:{Aida TO Carmen}"));
+    //
+    //            // TODO more..
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_boosting() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            // ^1000 ""^1000
+    //            assertEquals("title:QUERY^1000 OR content:QUERY^1000", queryHelper.buildFacetQuery("QUERY^1000"));
+    //            assertEquals("(title:QUERY1^1000 OR content:QUERY1^1000) " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1^1000 QUERY2"));
+    //            assertEquals("(title:QUERY1^500 OR content:QUERY1^500) " + op + " (title:QUERY2^1000 OR content:QUERY2^1000)",
+    //                    queryHelper.buildFacetQuery("QUERY1^500 QUERY2^1000"));
+    //
+    //            assertEquals("mimetype:QUERY1^1000", queryHelper.buildFacetQuery("mimetype:QUERY1^1000"));
+    //            assertEquals("mimetype:QUERY1^1000 " + op + " (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("mimetype:QUERY1^1000 QUERY2"));
+    //
+    //            assertEquals("title:QUERY1\\ QUERY2^1000 OR content:QUERY1\\ QUERY2^1000",
+    //                    queryHelper.buildFacetQuery("\"QUERY1 QUERY2\"^1000"));
+    //            assertEquals("title:QUERY1^1000 OR content:QUERY1^1000", queryHelper.buildFacetQuery("\"QUERY1^1000\""));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_reserved() {
+    //        for (int i = 0; i < Constants.RESERVED.length - 1; i++) {
+    //            try {
+    //                assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                        queryHelper.buildFacetQuery(Constants.RESERVED[i]));
+    //            } catch (final InvalidQueryException e) {
+    //                if (Constants.RESERVED[i].equals("\"") && e.getMessageCode().equals("errors.invalid_query_quoted")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildFacetQuery("\\" + Constants.RESERVED[i]));
+    //                    continue;
+    //                } else if (Constants.RESERVED[i].equals("{") && e.getMessageCode().equals("errors.invalid_query_curly_bracket")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildFacetQuery("\\" + Constants.RESERVED[i]));
+    //                    continue;
+    //                } else if (Constants.RESERVED[i].equals("[") && e.getMessageCode().equals("errors.invalid_query_square_bracket")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildFacetQuery("\\" + Constants.RESERVED[i]));
+    //                    continue;
+    //                } else if (Constants.RESERVED[i].equals("(") && e.getMessageCode().equals("errors.invalid_query_parenthesis")) {
+    //                    assertEquals("title:\\" + Constants.RESERVED[i] + " OR content:\\" + Constants.RESERVED[i],
+    //                            queryHelper.buildFacetQuery("\\" + Constants.RESERVED[i]));
+    //                    continue;
+    //                }
+    //            }
+    //        }
+    //        assertEquals("title:\\: OR content:\\:", queryHelper.buildFacetQuery(":"));
+    //    }
+    //
+    //    public void test_buildFacet_or() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery("OR QUERY"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1 OR QUERY2"));
+    //            assertEquals("title:QUERY", queryHelper.buildFacetQuery("OR title:QUERY"));
+    //            assertEquals("title:QUERY1 OR title:QUERY2", queryHelper.buildFacetQuery("title:QUERY1 OR title:QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR title:QUERY2", queryHelper.buildFacetQuery("QUERY1 OR title:QUERY2"));
+    //            assertEquals("mimetype:QUERY1 OR title:QUERY2", queryHelper.buildFacetQuery("mimetype:QUERY1 OR title:QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR (title:QUERY2 OR content:QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("QUERY1 OR QUERY2 QUERY3"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) OR (title:QUERY2 OR content:QUERY2) OR (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("QUERY1 OR QUERY2 OR QUERY3"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_and() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("title:QUERY OR content:QUERY", queryHelper.buildFacetQuery("AND QUERY"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) AND (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("QUERY1 AND QUERY2"));
+    //            assertEquals("title:QUERY", queryHelper.buildFacetQuery("AND title:QUERY"));
+    //            assertEquals("title:QUERY1 AND title:QUERY2", queryHelper.buildFacetQuery("title:QUERY1 AND title:QUERY2"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) AND title:QUERY2", queryHelper.buildFacetQuery("QUERY1 AND title:QUERY2"));
+    //            assertEquals("mimetype:QUERY1 AND title:QUERY2", queryHelper.buildFacetQuery("mimetype:QUERY1 AND title:QUERY2"));
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1) AND (title:QUERY2 OR content:QUERY2) " + op + " (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("QUERY1 AND QUERY2 QUERY3"));
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1) " + op + " (title:QUERY2 OR content:QUERY2) AND (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("QUERY1 QUERY2 AND QUERY3"));
+    //            assertEquals("(title:QUERY1 OR content:QUERY1) AND (title:QUERY2 OR content:QUERY2) AND (title:QUERY3 OR content:QUERY3)",
+    //                    queryHelper.buildFacetQuery("QUERY1 AND QUERY2 AND QUERY3"));
+    //        }
+    //    }
+    //
+    //    public void test_buildFacet_not() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("NOT (title:QUERY OR content:QUERY)", queryHelper.buildFacetQuery("NOT QUERY"));
+    //            assertEquals("NOT title:QUERY", queryHelper.buildFacetQuery("NOT title:QUERY"));
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT (title:QUERY1 OR content:QUERY1)",
+    //                    queryHelper.buildFacetQuery("NOT QUERY1 QUERY2"));
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT (title:QUERY1 OR content:QUERY1)",
+    //                    queryHelper.buildFacetQuery("NOT QUERY1 OR QUERY2"));
+    //            assertEquals("NOT (title:QUERY1 OR content:QUERY1) " + op + " NOT (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("NOT QUERY1 NOT QUERY2"));
+    //            assertEquals("NOT (title:QUERY1 OR content:QUERY1) " + op + " NOT (title:QUERY2 OR content:QUERY2)",
+    //                    queryHelper.buildFacetQuery("NOT QUERY1 OR NOT QUERY2"));
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT (title:QUERY1 OR content:QUERY1) " + op
+    //                    + " NOT (title:QUERY3 OR content:QUERY3)", queryHelper.buildFacetQuery("NOT QUERY1 QUERY2 NOT QUERY3"));
+    //            assertEquals("NOT mimetype:QUERY", queryHelper.buildFacetQuery("NOT mimetype:QUERY"));
+    //            assertEquals("NOT mimetype:QUERY1 " + op + " NOT title:QUERY2",
+    //                    queryHelper.buildFacetQuery("NOT mimetype:QUERY1 NOT title:QUERY2"));
+    //            assertEquals("(title:QUERY2 OR content:QUERY2) " + op + " NOT mimetype:QUERY1",
+    //                    queryHelper.buildFacetQuery("NOT mimetype:QUERY1 QUERY2"));
+    //            assertEquals("mimetype:QUERY2 " + op + " NOT (title:QUERY1 OR content:QUERY1)",
+    //                    queryHelper.buildFacetQuery("NOT QUERY1 mimetype:QUERY2"));
+    //        }
+    //    }
+    //
+    //    public void test_inner_query() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("(title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc)",
+    //                    queryHelper.buildQuery("(bbb ccc)").getQuery());
+    //            assertEquals("(title:bbb OR content:bbb) OR (title:ccc OR content:ccc)", queryHelper.buildQuery("(bbb OR ccc)").getQuery());
+    //            assertEquals("(title:bbb OR content:bbb) AND (title:ccc OR content:ccc)", queryHelper.buildQuery("(bbb AND ccc)").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (bbb ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (bbb AND ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa AND (bbb AND ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa OR (bbb AND ccc)").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (bbb OR ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa AND (bbb OR ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa OR (bbb OR ccc)").getQuery());
+    //
+    //            assertEquals("((title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc)) " + op + " (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb ccc) ddd").getQuery());
+    //            assertEquals("((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) " + op + " (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb AND ccc) ddd").getQuery());
+    //            assertEquals("((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb AND ccc) AND ddd").getQuery());
+    //            assertEquals("((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb AND ccc) OR ddd").getQuery());
+    //
+    //            assertEquals("((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) " + op + " (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb OR ccc) ddd").getQuery());
+    //            assertEquals("((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb OR ccc) AND ddd").getQuery());
+    //            assertEquals("((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("(bbb OR ccc) OR ddd").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildQuery("aaa (bbb ccc) ddd").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildQuery("aaa (bbb AND ccc) ddd").getQuery());
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("aaa AND (bbb AND ccc) AND ddd").getQuery());
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("aaa OR (bbb AND ccc) OR ddd").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildQuery("aaa (bbb OR ccc) ddd").getQuery());
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("aaa AND (bbb OR ccc) AND ddd").getQuery());
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildQuery("aaa OR (bbb OR ccc) OR ddd").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " (label:bbb " + op + " (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (label:bbb ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " (label:bbb AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (label:bbb AND ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " (label:bbb OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (label:bbb OR ccc)").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " label:ccc)",
+    //                    queryHelper.buildQuery("aaa (bbb label:ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) AND label:ccc)",
+    //                    queryHelper.buildQuery("aaa (bbb AND label:ccc)").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) OR label:ccc)",
+    //                    queryHelper.buildQuery("aaa (bbb OR label:ccc)").getQuery());
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " NOT (title:ccc OR content:ccc))",
+    //                    queryHelper.buildQuery("aaa (bbb NOT ccc)").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_more_inner_query() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " ((title:ccc OR content:ccc) " + op
+    //                    + " (title:ddd OR content:ddd)))", queryHelper.buildQuery("aaa (bbb (ccc ddd))").getQuery());
+    //            assertEquals("(((title:aaa OR content:aaa) " + op + " (title:bbb OR content:bbb)) " + op + " (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildQuery("((aaa bbb) ccc) ddd").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_inner_facetQuery() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("(title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc)", queryHelper.buildFacetQuery("(bbb ccc)"));
+    //            assertEquals("(title:bbb OR content:bbb) OR (title:ccc OR content:ccc)", queryHelper.buildFacetQuery("(bbb OR ccc)"));
+    //            assertEquals("(title:bbb OR content:bbb) AND (title:ccc OR content:ccc)", queryHelper.buildFacetQuery("(bbb AND ccc)"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (bbb ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (bbb AND ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa AND (bbb AND ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa OR (bbb AND ccc)"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (bbb OR ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa AND (bbb OR ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa OR (bbb OR ccc)"));
+    //
+    //            assertEquals("((title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc)) " + op + " (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb ccc) ddd"));
+    //            assertEquals("((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) " + op + " (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb AND ccc) ddd"));
+    //            assertEquals("((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb AND ccc) AND ddd"));
+    //            assertEquals("((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb AND ccc) OR ddd"));
+    //
+    //            assertEquals("((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) " + op + " (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb OR ccc) ddd"));
+    //            assertEquals("((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb OR ccc) AND ddd"));
+    //            assertEquals("((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("(bbb OR ccc) OR ddd"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildFacetQuery("aaa (bbb ccc) ddd"));
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildFacetQuery("aaa (bbb AND ccc) ddd"));
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("aaa AND (bbb AND ccc) AND ddd"));
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) AND (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("aaa OR (bbb AND ccc) OR ddd"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildFacetQuery("aaa (bbb OR ccc) ddd"));
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) AND ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) AND (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("aaa AND (bbb OR ccc) AND ddd"));
+    //            assertEquals(
+    //                    "(title:aaa OR content:aaa) OR ((title:bbb OR content:bbb) OR (title:ccc OR content:ccc)) OR (title:ddd OR content:ddd)",
+    //                    queryHelper.buildFacetQuery("aaa OR (bbb OR ccc) OR ddd"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " (label:bbb " + op + " (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (label:bbb ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " (label:bbb AND (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (label:bbb AND ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " (label:bbb OR (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (label:bbb OR ccc)"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " label:ccc)",
+    //                    queryHelper.buildFacetQuery("aaa (bbb label:ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) AND label:ccc)",
+    //                    queryHelper.buildFacetQuery("aaa (bbb AND label:ccc)"));
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) OR label:ccc)",
+    //                    queryHelper.buildFacetQuery("aaa (bbb OR label:ccc)"));
+    //
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " NOT (title:ccc OR content:ccc))",
+    //                    queryHelper.buildFacetQuery("aaa (bbb NOT ccc)"));
+    //        }
+    //    }
+    //
+    //    public void test_more_inner_facetQuery() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " ((title:bbb OR content:bbb) " + op + " ((title:ccc OR content:ccc) " + op
+    //                    + " (title:ddd OR content:ddd)))", queryHelper.buildFacetQuery("aaa (bbb (ccc ddd))"));
+    //            assertEquals("(((title:aaa OR content:aaa) " + op + " (title:bbb OR content:bbb)) " + op + " (title:ccc OR content:ccc)) " + op
+    //                    + " (title:ddd OR content:ddd)", queryHelper.buildFacetQuery("((aaa bbb) ccc) ddd"));
+    //        }
+    //    }
+    //
+    //    public void test_quote_query() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertException(format, "\"", "errors.invalid_query_quoted");
+    //            assertException(format, "a\"", "errors.invalid_query_quoted");
+    //            assertException(format, "\"b", "errors.invalid_query_quoted");
+    //            assertException(format, "a\"b", "errors.invalid_query_quoted");
+    //            assertException(format, "content:\"", "errors.invalid_query_quoted");
+    //            assertException(format, "content:\" ", "errors.invalid_query_quoted");
+    //            assertException(format, "content:a\"", "errors.invalid_query_quoted");
+    //            assertException(format, "content:\"b", "errors.invalid_query_quoted");
+    //            assertException(format, "content:a\"b", "errors.invalid_query_quoted");
+    //        }
+    //    }
+    //
+    //    public void test_curly_bracket_query() {
+    //        queryHelper = new QueryHelper();
+    //        inject(new FieldHelper());
+    //        inject(new SystemHelper());
+    //        inject(queryHelper);
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertException(format, "{", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "a{", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "{b", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "a{b", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "content:{", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "content:{ ", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "content:a{", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "content:{b", "errors.invalid_query_curly_bracket");
+    //            assertException(format, "content:a{b", "errors.invalid_query_curly_bracket");
+    //        }
+    //    }
+    //
+    //    public void test_square_bracket_query() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertException(format, "[", "errors.invalid_query_square_bracket");
+    //            assertException(format, "a[", "errors.invalid_query_square_bracket");
+    //            assertException(format, "[b", "errors.invalid_query_square_bracket");
+    //            assertException(format, "a[b", "errors.invalid_query_square_bracket");
+    //            assertException(format, "content:[", "errors.invalid_query_square_bracket");
+    //            assertException(format, "content:[ ", "errors.invalid_query_square_bracket");
+    //            assertException(format, "content:a[", "errors.invalid_query_square_bracket");
+    //            assertException(format, "content:[b", "errors.invalid_query_square_bracket");
+    //            assertException(format, "content:a[b", "errors.invalid_query_square_bracket");
+    //        }
+    //    }
+    //
+    //    public void test_parenthesis_query() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertException(format, "(", "errors.invalid_query_parenthesis");
+    //            assertException(format, "a(", "errors.invalid_query_parenthesis");
+    //            assertException(format, "(b", "errors.invalid_query_parenthesis");
+    //            assertException(format, "a(b", "errors.invalid_query_parenthesis");
+    //            assertException(format, "content:(", "errors.invalid_query_parenthesis");
+    //            assertException(format, "content:( ", "errors.invalid_query_parenthesis");
+    //            assertException(format, "content:a(", "errors.invalid_query_parenthesis");
+    //            assertException(format, "content:(b", "errors.invalid_query_parenthesis");
+    //            assertException(format, "content:a(b", "errors.invalid_query_parenthesis");
+    //        }
+    //    }
+    //
+    //    private void assertException(final String format, final String query, final String messageCode) {
+    //        try {
+    //            final String ret = queryHelper.buildQuery(String.format(format, query)).getQuery();
+    //            fail("format: " + format + ", query: " + query + ", ret: " + ret);
+    //        } catch (final InvalidQueryException e) {
+    //            FessMessages messages = new FessMessages();
+    //            e.getMessageCode().message(messages);
+    //            if (!messages.hasMessageOf(ActionMessages.GLOBAL_PROPERTY_KEY, messageCode)) {
+    //                throw e;
+    //            }
+    //        }
+    //    }
+    //
+    //    public void test_quote_facetQuery() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertExceptionOnFacetQuery(format, "\"", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "a\"", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "\"b", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "a\"b", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "content:\"", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "content:\" ", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "content:a\"", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "content:\"b", "errors.invalid_query_quoted");
+    //            assertExceptionOnFacetQuery(format, "content:a\"b", "errors.invalid_query_quoted");
+    //        }
+    //    }
+    //
+    //    public void test_curly_bracket_facetQuery() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertExceptionOnFacetQuery(format, "{", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "a{", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "{b", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "a{b", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:{", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:{ ", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:a{", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:{b", "errors.invalid_query_curly_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:a{b", "errors.invalid_query_curly_bracket");
+    //        }
+    //    }
+    //
+    //    public void test_square_bracket_facetQuery() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertExceptionOnFacetQuery(format, "[", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "a[", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "[b", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "a[b", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:[", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:[ ", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:a[", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:[b", "errors.invalid_query_square_bracket");
+    //            assertExceptionOnFacetQuery(format, "content:a[b", "errors.invalid_query_square_bracket");
+    //        }
+    //    }
+    //
+    //    public void test_parenthesis_facetQuery() {
+    //        final String[] formats =
+    //                { "%s", " %s ", "aaa %s", "aaa OR %s", "NOT %s", "%s bbb", "%s bbb", "%s OR bbb", "aaa (%s)", "(%s) bbb", "aaa (%s) bbb" };
+    //        for (final String format : formats) {
+    //            assertExceptionOnFacetQuery(format, "(", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "a(", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "(b", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "a(b", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "content:(", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "content:( ", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "content:a(", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "content:(b", "errors.invalid_query_parenthesis");
+    //            assertExceptionOnFacetQuery(format, "content:a(b", "errors.invalid_query_parenthesis");
+    //        }
+    //    }
+    //
+    //    public void test_buildContentQueryWithLang() {
+    //        StringBuilder buf;
+    //
+    //        buf = new StringBuilder();
+    //        queryHelper.buildContentQueryWithLang(buf, "aaa", null);
+    //        assertEquals("(title:aaa OR content:aaa)", buf.toString());
+    //
+    //        buf = new StringBuilder();
+    //        queryHelper.buildContentQueryWithLang(buf, "aaa", "ja");
+    //        assertEquals("(title:aaa OR content:aaa OR content_ja:aaa)", buf.toString());
+    //
+    //        buf = new StringBuilder();
+    //        queryHelper.buildContentQueryWithLang(buf, "aaa", "zh_CN");
+    //        assertEquals("(title:aaa OR content:aaa OR content_zh_CN:aaa)", buf.toString());
+    //    }
+    //
+    //    public void test_getQueryLanguage() {
+    //        assertNull(queryHelper.getQueryLanguage());
+    //        final MockletHttpServletRequest request = getMockRequest();
+    //        request.setLocale(Locale.JAPAN);
+    //        assertEquals("ja", queryHelper.getQueryLanguage());
+    //        request.setLocale(Locale.SIMPLIFIED_CHINESE);
+    //        assertEquals("zh_CN", queryHelper.getQueryLanguage());
+    //        queryHelper.addFieldLanguage("zh_CN", "cjk");
+    //        assertEquals("cjk", queryHelper.getQueryLanguage());
+    //        request.setLocale(Locale.CHINESE);
+    //        assertEquals("zh", queryHelper.getQueryLanguage());
+    //        request.setLocale(Locale.CANADA_FRENCH);
+    //        assertEquals("fr", queryHelper.getQueryLanguage());
+    //        request.setLocale(new Locale("aa"));
+    //        assertNull(queryHelper.getQueryLanguage());
+    //    }
+    //
+    //    public void test_buildWithLang() {
+    //        final MockletHttpServletRequest request = getMockRequest();
+    //        request.setLocale(Locale.JAPAN);
+    //
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("", queryHelper.buildQuery("").getQuery());
+    //
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY", queryHelper.buildQuery("QUERY").getQuery());
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY", queryHelper.buildQuery("QUERY ").getQuery());
+    //            assertEquals("title:QUERY OR content:QUERY OR content_ja:QUERY", queryHelper.buildQuery(" QUERY").getQuery());
+    //
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1) " + op
+    //                            + " NOT (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1 NOT QUERY2").getQuery());
+    //
+    //            assertEquals("(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1) " + op
+    //                    + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)", queryHelper.buildQuery("QUERY1 QUERY2").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery("QUERY1 QUERY2 ").getQuery());
+    //            assertEquals(
+    //                    "(title:QUERY1 OR content:QUERY1 OR content_ja:QUERY1) " + op
+    //                            + " (title:QUERY2 OR content:QUERY2 OR content_ja:QUERY2)",
+    //                    queryHelper.buildQuery(" QUERY1 QUERY2").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_unbracketQuery() {
+    //        assertEquals("", queryHelper.unbracketQuery(""));
+    //        assertEquals("", queryHelper.unbracketQuery("()"));
+    //        assertEquals("", queryHelper.unbracketQuery("(())"));
+    //        assertEquals("()()", queryHelper.unbracketQuery("()()"));
+    //        assertEquals("()()", queryHelper.unbracketQuery("(()())"));
+    //        assertEquals("()()()", queryHelper.unbracketQuery("()()()"));
+    //        assertEquals("()(()())", queryHelper.unbracketQuery("()(()())"));
+    //
+    //        assertEquals("(", queryHelper.unbracketQuery("("));
+    //        assertEquals(")", queryHelper.unbracketQuery(")"));
+    //        assertEquals("()(", queryHelper.unbracketQuery("()("));
+    //        assertEquals("())", queryHelper.unbracketQuery("())"));
+    //        assertEquals(")()", queryHelper.unbracketQuery(")()"));
+    //        assertEquals("(()", queryHelper.unbracketQuery("(()"));
+    //
+    //        assertEquals("\\(", queryHelper.unbracketQuery("(\\()"));
+    //        assertEquals("\\)", queryHelper.unbracketQuery("(\\))"));
+    //        assertEquals("(\\\\()", queryHelper.unbracketQuery("(\\\\()"));
+    //        assertEquals("(\\\\))", queryHelper.unbracketQuery("(\\\\))"));
+    //        assertEquals("\\\\\\(", queryHelper.unbracketQuery("(\\\\\\()"));
+    //        assertEquals("\\\\\\)", queryHelper.unbracketQuery("(\\\\\\))"));
+    //    }
+    //
+    //    public void test_appendRangeQueryValue() {
+    //        StringBuilder buf = new StringBuilder();
+    //        queryHelper.appendRangeQueryValue(buf, "[1 TO 2]", '[', ']');
+    //        assertEquals("[1 TO 2]", buf.toString());
+    //
+    //        buf = new StringBuilder();
+    //        queryHelper.appendRangeQueryValue(buf, "[1234 TO 2345]", '[', ']');
+    //        assertEquals("[1234 TO 2345]", buf.toString());
+    //
+    //        buf = new StringBuilder();
+    //        queryHelper.appendRangeQueryValue(buf, "[* TO 2345]", '[', ']');
+    //        assertEquals("[* TO 2345]", buf.toString());
+    //
+    //        buf = new StringBuilder();
+    //        queryHelper.appendRangeQueryValue(buf, "[1234 TO *]", '[', ']');
+    //        assertEquals("[1234 TO *]", buf.toString());
+    //
+    //        buf = new StringBuilder();
+    //
+    //        try {
+    //            queryHelper.appendRangeQueryValue(buf, "[* TO *]", '[', ']');
+    //            fail();
+    //        } catch (final InvalidQueryException e) {}
+    //
+    //        try {
+    //            queryHelper.appendRangeQueryValue(buf, "[1]", '[', ']');
+    //            fail();
+    //        } catch (final InvalidQueryException e) {}
+    //
+    //        try {
+    //            queryHelper.appendRangeQueryValue(buf, "[1 TO]", '[', ']');
+    //            fail();
+    //        } catch (final InvalidQueryException e) {}
+    //
+    //        try {
+    //            queryHelper.appendRangeQueryValue(buf, "[1 TO ]", '[', ']');
+    //            fail();
+    //        } catch (final InvalidQueryException e) {}
+    //
+    //        try {
+    //            queryHelper.appendRangeQueryValue(buf, "[TO 1]", '[', ']');
+    //            fail();
+    //        } catch (final InvalidQueryException e) {}
+    //
+    //        try {
+    //            queryHelper.appendRangeQueryValue(buf, "[ TO 1]", '[', ']');
+    //            fail();
+    //        } catch (final InvalidQueryException e) {}
+    //    }
+    //
+    //    public void test_inurl() {
+    //        for (final String op : new String[] { "AND", "OR" }) {
+    //            getMockRequest().setAttribute(Constants.DEFAULT_OPERATOR, op);
+    //            assertEquals("url:*QUERY*", queryHelper.buildQuery("inurl:QUERY").getQuery());
+    //            assertEquals("url:*QUERY1* " + op + " url:*QUERY2*", queryHelper.buildQuery("inurl:QUERY1 inurl:QUERY2").getQuery());
+    //            assertEquals("(title:aaa OR content:aaa) " + op + " url:*QUERY1* " + op + " url:*QUERY2*",
+    //                    queryHelper.buildQuery("aaa inurl:QUERY1 inurl:QUERY2").getQuery());
+    //            assertEquals("url:*QUERY*", queryHelper.buildQuery("inurl:\"QUERY\"").getQuery());
+    //        }
+    //    }
+    //
+    //    public void test_buildOptionQuery() {
+    //        final Map<String, String[]> options = new HashMap<>();
+    //
+    //        assertEquals("", queryHelper.buildOptionQuery(null));
+    //        assertEquals("", queryHelper.buildOptionQuery(options));
+    //
+    //        // Q
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "a" });
+    //        assertEquals("a", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "a b" });
+    //        assertEquals("a b", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "a b c" });
+    //        assertEquals("a b c", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "\"a b\"" });
+    //        assertEquals("\"a b\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "\"a b\" c" });
+    //        assertEquals("\"a b\" c", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "\"a b\" \"c d\"" });
+    //        assertEquals("\"a b\" \"c d\"", queryHelper.buildOptionQuery(options));
+    //
+    //        // CQ
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "a" });
+    //        assertEquals("\"a\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "a b" });
+    //        assertEquals("\"a b\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "a b c" });
+    //        assertEquals("\"a b c\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "\"a b\"" });
+    //        assertEquals("\"a b\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "\"a b\" c" });
+    //        assertEquals("\"a b\" \"c\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "\"a b\" \"c d\"" });
+    //        assertEquals("\"a b\" \"c d\"", queryHelper.buildOptionQuery(options));
+    //
+    //        // OQ
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "a" });
+    //        assertEquals("a", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "a b" });
+    //        assertEquals("a OR b", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "a b c" });
+    //        assertEquals("a OR b OR c", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "\"a b\"" });
+    //        assertEquals("\"a b\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "\"a b\" c" });
+    //        assertEquals("\"a b\" OR c", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "\"a b\" \"c d\"" });
+    //        assertEquals("\"a b\" OR \"c d\"", queryHelper.buildOptionQuery(options));
+    //
+    //        // NQ
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "a" });
+    //        assertEquals("NOT a", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "a b" });
+    //        assertEquals("NOT a NOT b", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "a b c" });
+    //        assertEquals("NOT a NOT b NOT c", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "\"a b\"" });
+    //        assertEquals("NOT \"a b\"", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "\"a b\" c" });
+    //        assertEquals("NOT \"a b\" NOT c", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "\"a b\" \"c d\"" });
+    //        assertEquals("NOT \"a b\" NOT \"c d\"", queryHelper.buildOptionQuery(options));
+    //
+    //        // combine
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "a" });
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "b" });
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "c" });
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "d" });
+    //        assertEquals("a \"b\" c NOT d", queryHelper.buildOptionQuery(options));
+    //
+    //        options.clear();
+    //        options.put(Constants.OPTION_QUERY_Q, new String[] { "a 1" });
+    //        options.put(Constants.OPTION_QUERY_CQ, new String[] { "b 2" });
+    //        options.put(Constants.OPTION_QUERY_OQ, new String[] { "c 3" });
+    //        options.put(Constants.OPTION_QUERY_NQ, new String[] { "d 4" });
+    //        assertEquals("a 1 \"b 2\" (c OR 3) NOT d NOT 4", queryHelper.buildOptionQuery(options));
+    //    }
+    //
+    //    private void assertExceptionOnFacetQuery(final String format, final String query, final String messageCode) {
+    //        try {
+    //            final String ret = queryHelper.buildFacetQuery(String.format(format, query));
+    //            fail("format: " + format + ", query: " + query + ", ret: " + ret);
+    //        } catch (final InvalidQueryException e) {
+    //            FessMessages messages = new FessMessages();
+    //            e.getMessageCode().message(messages);
+    //            if (!messages.hasMessageOf(ActionMessages.GLOBAL_PROPERTY_KEY, messageCode)) {
+    //                throw e;
+    //            }
+    //        }
+    //    }
+    //
+    //    public void test_getQueryParamMap() {
+    //        assertEquals(0, queryHelper.getQueryParamMap().size());
+    //
+    //        Map<String, String[]> queryParamMap;
+    //
+    //        queryHelper.addQueryParam("aaa", new String[] { "111" });
+    //        queryHelper.addQueryParam("bbb", new String[] { "222", "$333" });
+    //        queryParamMap = queryHelper.getQueryParamMap();
+    //        assertEquals(2, queryParamMap.size());
+    //        assertEquals(1, queryParamMap.get("aaa").length);
+    //        assertEquals("111", queryParamMap.get("aaa")[0]);
+    //        assertEquals(2, queryParamMap.get("bbb").length);
+    //        assertEquals("222", queryParamMap.get("bbb")[0]);
+    //        assertEquals("", queryParamMap.get("bbb")[1]);
+    //
+    //        getMockRequest().setParameter("333", "AAA");
+    //        queryParamMap = queryHelper.getQueryParamMap();
+    //        assertEquals(2, queryParamMap.size());
+    //        assertEquals(1, queryParamMap.get("aaa").length);
+    //        assertEquals("111", queryParamMap.get("aaa")[0]);
+    //        assertEquals(2, queryParamMap.get("bbb").length);
+    //        assertEquals("222", queryParamMap.get("bbb")[0]);
+    //        assertEquals("AAA", queryParamMap.get("bbb")[1]);
+    //
+    //    }
+
+}

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません