ソースを参照

fix #1985 add screen_width parameter

Shinsuke Sugaya 6 年 前
コミット
197d95b6a6

+ 6 - 1
src/main/java/org/codelibs/fess/api/gsa/GsaApiManager.java

@@ -49,6 +49,7 @@ import org.codelibs.fess.api.WebApiRequest;
 import org.codelibs.fess.app.service.SearchService;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.SearchRenderData;
 import org.codelibs.fess.entity.SearchRequestParams;
 import org.codelibs.fess.exception.InvalidAccessTokenException;
@@ -433,7 +434,7 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
         }
     }
 
-    protected static class GsaRequestParams implements SearchRequestParams {
+    protected static class GsaRequestParams extends SearchRequestParams {
 
         private final HttpServletRequest request;
 
@@ -622,6 +623,10 @@ public class GsaApiManager extends BaseApiManager implements WebApiManager {
             return request.getParameter("sdh");
         }
 
+        @Override
+        public HighlightInfo getHighlightInfo() {
+            return ComponentUtil.getViewHelper().createHighlightInfo();
+        }
     }
 
     public void setGsaPathPrefix(final String gsaPathPrefix) {

+ 6 - 1
src/main/java/org/codelibs/fess/api/json/JsonApiManager.java

@@ -40,6 +40,7 @@ import org.codelibs.fess.app.service.FavoriteLogService;
 import org.codelibs.fess.app.service.SearchService;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.PingResponse;
 import org.codelibs.fess.entity.SearchRenderData;
 import org.codelibs.fess.entity.SearchRequestParams;
@@ -674,7 +675,7 @@ public class JsonApiManager extends BaseJsonApiManager {
 
     }
 
-    protected static class JsonRequestParams implements SearchRequestParams {
+    protected static class JsonRequestParams extends SearchRequestParams {
 
         private final HttpServletRequest request;
 
@@ -806,5 +807,9 @@ public class JsonApiManager extends BaseJsonApiManager {
             return request.getParameter("sdh");
         }
 
+        @Override
+        public HighlightInfo getHighlightInfo() {
+            return ComponentUtil.getViewHelper().createHighlightInfo();
+        }
     }
 }

+ 7 - 1
src/main/java/org/codelibs/fess/api/suggest/SuggestApiManager.java

@@ -35,6 +35,7 @@ import org.codelibs.fess.api.BaseJsonApiManager;
 import org.codelibs.fess.app.service.SearchService;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.SearchRequestParams;
 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
 import org.codelibs.fess.exception.InvalidAccessTokenException;
@@ -163,7 +164,7 @@ public class SuggestApiManager extends BaseJsonApiManager {
         writeJsonResponse(status, buf.toString(), errMsg);
     }
 
-    protected static class RequestParameter implements SearchRequestParams {
+    protected static class RequestParameter extends SearchRequestParams {
         private final String query;
 
         private final String[] fields;
@@ -293,5 +294,10 @@ public class SuggestApiManager extends BaseJsonApiManager {
         public String getSimilarDocHash() {
             throw new UnsupportedOperationException();
         }
+
+        @Override
+        public HighlightInfo getHighlightInfo() {
+            return new HighlightInfo();
+        }
     }
 }

+ 2 - 4
src/main/java/org/codelibs/fess/app/service/SearchService.java

@@ -111,13 +111,11 @@ public class SearchService {
             query = ComponentUtil.getQueryStringBuilder().params(params).build() + " sort:" + sortField;
         }
         final List<Map<String, Object>> documentItems =
-                fessEsClient.search(
-                        fessConfig.getIndexDocumentSearchIndex(),
-                        fessConfig.getIndexDocumentType(),
+                fessEsClient.search(fessConfig.getIndexDocumentSearchIndex(), fessConfig.getIndexDocumentType(),
                         searchRequestBuilder -> {
                             queryHelper.processSearchPreference(searchRequestBuilder, userBean, query);
                             return SearchConditionBuilder.builder(searchRequestBuilder).query(query).offset(pageStart).size(pageSize)
-                                    .facetInfo(params.getFacetInfo()).geoInfo(params.getGeoInfo())
+                                    .facetInfo(params.getFacetInfo()).geoInfo(params.getGeoInfo()).highlightInfo(params.getHighlightInfo())
                                     .similarDocHash(params.getSimilarDocHash()).responseFields(queryHelper.getResponseFields())
                                     .searchRequestType(params.getType()).build();
                         }, (searchRequestBuilder, execTime, searchResponse) -> {

+ 7 - 1
src/main/java/org/codelibs/fess/app/web/admin/searchlist/ListForm.java

@@ -26,6 +26,7 @@ import javax.validation.constraints.Size;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.SearchRequestParams;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
@@ -36,7 +37,7 @@ import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
  * @author shinsuke
  * @author Keiichi Watanabe
  */
-public class ListForm implements SearchRequestParams {
+public class ListForm extends SearchRequestParams {
 
     @Size(max = 1000)
     public String q;
@@ -117,6 +118,11 @@ public class ListForm implements SearchRequestParams {
         return null;
     }
 
+    @Override
+    public HighlightInfo getHighlightInfo() {
+        return new HighlightInfo();
+    }
+
     @Override
     public String getSort() {
         return sort;

+ 7 - 1
src/main/java/org/codelibs/fess/app/web/base/SearchForm.java

@@ -26,13 +26,14 @@ import javax.validation.constraints.Size;
 import org.codelibs.core.lang.StringUtil;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.SearchRequestParams;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
 import org.lastaflute.web.util.LaRequestUtil;
 import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
 
-public class SearchForm implements SearchRequestParams {
+public class SearchForm extends SearchRequestParams {
 
     public Map<String, String[]> fields = new HashMap<>();
 
@@ -122,6 +123,11 @@ public class SearchForm implements SearchRequestParams {
         return ComponentUtil.getQueryHelper().getDefaultFacetInfo();
     }
 
+    @Override
+    public HighlightInfo getHighlightInfo() {
+        return ComponentUtil.getViewHelper().createHighlightInfo();
+    }
+
     @Override
     public String getSort() {
         return sort;

+ 59 - 0
src/main/java/org/codelibs/fess/entity/HighlightInfo.java

@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012-2019 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 org.codelibs.fess.mylasta.direction.FessConfig;
+import org.codelibs.fess.util.ComponentUtil;
+
+public class HighlightInfo {
+    private String type;
+    private int fragmentSize;
+    private int numOfFragments;
+
+    public HighlightInfo() {
+        FessConfig fessConfig = ComponentUtil.getFessConfig();
+        this.type = fessConfig.getQueryHighlightType();
+        this.fragmentSize = fessConfig.getQueryHighlightFragmentSizeAsInteger();
+        this.numOfFragments = fessConfig.getQueryHighlightNumberOfFragmentsAsInteger();
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public HighlightInfo type(String type) {
+        this.type = type;
+        return this;
+    }
+
+    public int getFragmentSize() {
+        return fragmentSize;
+    }
+
+    public HighlightInfo fragmentSize(int fragmentSize) {
+        this.fragmentSize = fragmentSize;
+        return this;
+    }
+
+    public int getNumOfFragments() {
+        return numOfFragments;
+    }
+
+    public HighlightInfo numOfFragments(int numOfFragments) {
+        this.numOfFragments = numOfFragments;
+        return this;
+    }
+}

+ 31 - 29
src/main/java/org/codelibs/fess/entity/SearchRequestParams.java

@@ -24,53 +24,55 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.codelibs.core.lang.StringUtil;
 
-public interface SearchRequestParams {
+public abstract class SearchRequestParams {
 
-    String AS_NQ = "nq";
+    public static final String AS_NQ = "nq";
 
-    String AS_OQ = "oq";
+    public static final String AS_OQ = "oq";
 
-    String AS_EPQ = "epq";
+    public static final String AS_EPQ = "epq";
 
-    String AS_Q = "q";
+    public static final String AS_Q = "q";
 
-    String AS_FILETYPE = "filetype";
+    public static final String AS_FILETYPE = "filetype";
 
-    String AS_SITESEARCH = "sitesearch";
+    public static final String AS_SITESEARCH = "sitesearch";
 
-    String AS_OCCURRENCE = "occt";
+    public static final String AS_OCCURRENCE = "occt";
 
-    String AS_TIMESTAMP = "timestamp";
+    public static final String AS_TIMESTAMP = "timestamp";
 
-    String getQuery();
+    public abstract String getQuery();
 
-    Map<String, String[]> getFields();
+    public abstract Map<String, String[]> getFields();
 
-    Map<String, String[]> getConditions();
+    public abstract Map<String, String[]> getConditions();
 
-    String[] getLanguages();
+    public abstract String[] getLanguages();
 
-    GeoInfo getGeoInfo();
+    public abstract GeoInfo getGeoInfo();
 
-    FacetInfo getFacetInfo();
+    public abstract FacetInfo getFacetInfo();
 
-    String getSort();
+    public abstract HighlightInfo getHighlightInfo();
 
-    int getStartPosition();
+    public abstract String getSort();
 
-    int getPageSize();
+    public abstract int getStartPosition();
 
-    String[] getExtraQueries();
+    public abstract int getPageSize();
 
-    Object getAttribute(String name);
+    public abstract String[] getExtraQueries();
 
-    Locale getLocale();
+    public abstract Object getAttribute(String name);
 
-    SearchRequestType getType();
+    public abstract Locale getLocale();
 
-    String getSimilarDocHash();
+    public abstract SearchRequestType getType();
 
-    default boolean hasConditionQuery() {
+    public abstract String getSimilarDocHash();
+
+    public boolean hasConditionQuery() {
         final Map<String, String[]> conditions = getConditions();
         return !isEmptyArray(conditions.get(AS_Q))//
                 || !isEmptyArray(conditions.get(AS_EPQ))//
@@ -81,22 +83,22 @@ public interface SearchRequestParams {
                 || !isEmptyArray(conditions.get(AS_FILETYPE));
     }
 
-    default boolean isEmptyArray(final String[] values) {
+    protected boolean isEmptyArray(final String[] values) {
         if (values == null || values.length == 0) {
             return true;
         }
         return stream(values).get(stream -> stream.allMatch(StringUtil::isBlank));
     }
 
-    default String[] simplifyArray(final String[] values) {
+    protected String[] simplifyArray(final String[] values) {
         return stream(values).get(stream -> stream.filter(StringUtil::isNotBlank).distinct().toArray(n -> new String[n]));
     }
 
-    default String[] getParamValueArray(final HttpServletRequest request, final String param) {
+    protected String[] getParamValueArray(final HttpServletRequest request, final String param) {
         return simplifyArray(request.getParameterValues(param));
     }
 
-    default FacetInfo createFacetInfo(final HttpServletRequest request) {
+    protected FacetInfo createFacetInfo(final HttpServletRequest request) {
         final String[] fields = getParamValueArray(request, "facet.field");
         final String[] queries = getParamValueArray(request, "facet.query");
         if (fields.length == 0 && queries.length == 0) {
@@ -124,7 +126,7 @@ public interface SearchRequestParams {
         return facetInfo;
     }
 
-    default GeoInfo createGeoInfo(final HttpServletRequest request) {
+    protected GeoInfo createGeoInfo(final HttpServletRequest request) {
         return new GeoInfo(request);
     }
 

+ 12 - 4
src/main/java/org/codelibs/fess/es/client/FessEsClient.java

@@ -51,6 +51,7 @@ import org.codelibs.elasticsearch.runner.ElasticsearchClusterRunner.Configs;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.PingResponse;
 import org.codelibs.fess.entity.QueryContext;
 import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType;
@@ -942,6 +943,7 @@ public class FessEsClient implements Client {
         private int size = Constants.DEFAULT_PAGE_SIZE;
         private GeoInfo geoInfo;
         private FacetInfo facetInfo;
+        private HighlightInfo highlightInfo;
         private String similarDocHash;
         private SearchRequestType searchRequestType = SearchRequestType.SEARCH;
         private boolean isScroll = false;
@@ -960,8 +962,9 @@ public class FessEsClient implements Client {
             params.put("responseFields", responseFields);
             params.put("offset", offset);
             params.put("size", size);
-            //            params.put("geoInfo", geoInfo);
-            //            params.put("facetInfo", facetInfo);
+            // TODO support rescorer(convert to map)
+            // params.put("geoInfo", geoInfo);
+            // params.put("facetInfo", facetInfo);
             params.put("similarDocHash", similarDocHash);
             return params;
         }
@@ -996,6 +999,11 @@ public class FessEsClient implements Client {
             return this;
         }
 
+        public SearchConditionBuilder highlightInfo(final HighlightInfo highlightInfo) {
+            this.highlightInfo = highlightInfo;
+            return this;
+        }
+
         public SearchConditionBuilder similarDocHash(final String similarDocHash) {
             if (StringUtil.isNotBlank(similarDocHash)) {
                 this.similarDocHash = similarDocHash;
@@ -1059,8 +1067,8 @@ public class FessEsClient implements Client {
             // highlighting
             final HighlightBuilder highlightBuilder = new HighlightBuilder();
             queryHelper.highlightedFields(stream -> stream.forEach(hf -> highlightBuilder.field(new HighlightBuilder.Field(hf)
-                    .highlighterType(fessConfig.getQueryHighlightType()).fragmentSize(fessConfig.getQueryHighlightFragmentSizeAsInteger())
-                    .numOfFragments(fessConfig.getQueryHighlightNumberOfFragmentsAsInteger()))));
+                    .highlighterType(highlightInfo.getType()).fragmentSize(highlightInfo.getFragmentSize())
+                    .numOfFragments(highlightInfo.getNumOfFragments()))));
             searchRequestBuilder.highlighter(highlightBuilder);
 
             // facets

+ 40 - 0
src/main/java/org/codelibs/fess/helper/ViewHelper.java

@@ -39,6 +39,7 @@ import java.util.stream.Collectors;
 
 import javax.annotation.PostConstruct;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 
 import org.apache.catalina.connector.ClientAbortException;
 import org.apache.commons.lang3.StringUtils;
@@ -54,6 +55,7 @@ import org.codelibs.fess.crawler.client.CrawlerClientFactory;
 import org.codelibs.fess.crawler.entity.ResponseData;
 import org.codelibs.fess.crawler.util.CharUtil;
 import org.codelibs.fess.entity.FacetQueryView;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.es.config.exentity.CrawlingConfig;
 import org.codelibs.fess.exception.FessSystemException;
 import org.codelibs.fess.helper.UserAgentHelper.UserAgentType;
@@ -82,6 +84,10 @@ public class ViewHelper {
 
     private static final Logger logger = LoggerFactory.getLogger(ViewHelper.class);
 
+    protected static final String SCREEN_WIDTH = "screen_width";
+
+    protected static final int TABLET_WIDTH = 768;
+
     protected static final String CONTENT_DISPOSITION = "Content-Disposition";
 
     protected static final String HL_CACHE = "hl_cache";
@@ -210,6 +216,40 @@ public class ViewHelper {
         return str.replaceAll(originalHighlightTagPre, StringUtil.EMPTY).replaceAll(originalHighlightTagPost, StringUtil.EMPTY);
     }
 
+    public HighlightInfo createHighlightInfo() {
+        return LaRequestUtil.getOptionalRequest().map(req -> {
+            final HighlightInfo highlightInfo = new HighlightInfo();
+            final String widthStr = req.getParameter(SCREEN_WIDTH);
+            if (StringUtil.isNotBlank(widthStr)) {
+                final int width = Integer.parseInt(widthStr);
+                updateHighlisthInfo(highlightInfo, width);
+                final HttpSession session = req.getSession(false);
+                if (session != null) {
+                    session.setAttribute(SCREEN_WIDTH, width);
+                }
+            } else {
+                final HttpSession session = req.getSession(false);
+                if (session != null) {
+                    final Integer width = (Integer) session.getAttribute(SCREEN_WIDTH);
+                    if (width != null) {
+                        updateHighlisthInfo(highlightInfo, width);
+                    }
+                }
+            }
+            return highlightInfo;
+        }).orElse(new HighlightInfo());
+    }
+
+    protected void updateHighlisthInfo(final HighlightInfo highlightInfo, final int width) {
+        if (width < TABLET_WIDTH) {
+            float ratio = ((float) width) / ((float) TABLET_WIDTH);
+            if (ratio < 0.5) {
+                ratio = 0.5f;
+            }
+            highlightInfo.fragmentSize((int) (highlightInfo.getFragmentSize() * ratio));
+        }
+    }
+
     public String getUrlLink(final Map<String, Object> document) {
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
         String url = DocumentUtil.getValue(document, fessConfig.getIndexFieldUrl(), String.class);

+ 6 - 0
src/test/java/org/codelibs/fess/util/QueryStringBuilderTest.java

@@ -21,6 +21,7 @@ import java.util.Map;
 
 import org.codelibs.fess.entity.FacetInfo;
 import org.codelibs.fess.entity.GeoInfo;
+import org.codelibs.fess.entity.HighlightInfo;
 import org.codelibs.fess.entity.SearchRequestParams;
 import org.codelibs.fess.unit.UnitFessTestCase;
 
@@ -150,6 +151,11 @@ public class QueryStringBuilderTest extends UnitFessTestCase {
                 return null;
             }
 
+            @Override
+            public HighlightInfo getHighlightInfo() {
+                return new HighlightInfo();
+            }
+
         }).build();
     }
 }