ソースを参照

fix #1082 add thumnail_id

Shinsuke Sugaya 8 年 前
コミット
3471ee1d90
21 ファイル変更493 行追加82 行削除
  1. 3 0
      src/main/config/es/fess_config.json
  2. 1 0
      src/main/java/org/codelibs/fess/es/config/bsbhv/BsThumbnailQueueBhv.java
  3. 17 0
      src/main/java/org/codelibs/fess/es/config/bsentity/BsThumbnailQueue.java
  4. 9 0
      src/main/java/org/codelibs/fess/es/config/bsentity/dbmeta/ThumbnailQueueDbm.java
  5. 4 0
      src/main/java/org/codelibs/fess/es/config/cbean/bs/BsThumbnailQueueCB.java
  6. 131 0
      src/main/java/org/codelibs/fess/es/config/cbean/ca/bs/BsThumbnailQueueCA.java
  7. 222 0
      src/main/java/org/codelibs/fess/es/config/cbean/cq/bs/BsThumbnailQueueCQ.java
  8. 12 12
      src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java
  9. 3 3
      src/main/java/org/codelibs/fess/thumbnail/ThumbnailGenerator.java
  10. 32 29
      src/main/java/org/codelibs/fess/thumbnail/ThumbnailManager.java
  11. 18 3
      src/main/java/org/codelibs/fess/thumbnail/impl/BaseThumbnailGenerator.java
  12. 2 1
      src/main/java/org/codelibs/fess/thumbnail/impl/CommandGenerator.java
  13. 1 1
      src/main/java/org/codelibs/fess/thumbnail/impl/EmptyGenerator.java
  14. 6 4
      src/main/java/org/codelibs/fess/thumbnail/impl/HtmlTagBasedGenerator.java
  15. 2 1
      src/main/java/org/codelibs/fess/thumbnail/impl/WebDriverGenerator.java
  16. 4 4
      src/main/resources/fess_config.properties
  17. 3 0
      src/main/resources/fess_indices/.fess_config/thumbnail_queue.json
  18. 14 13
      src/main/webapp/WEB-INF/view/searchResults.jsp
  19. 0 2
      src/main/webapp/css/style.css
  20. BIN
      src/main/webapp/images/noimage.png
  21. 9 9
      src/test/java/org/codelibs/fess/thumbnail/impl/HtmlTagBasedGeneratorTest.java

+ 3 - 0
src/main/config/es/fess_config.json

@@ -853,6 +853,9 @@
           "generator" : {
             "type": "keyword"
           },
+          "thumbnail_id" : {
+            "type": "keyword"
+          },
           "path" : {
             "type": "keyword"
           },

+ 1 - 0
src/main/java/org/codelibs/fess/es/config/bsbhv/BsThumbnailQueueBhv.java

@@ -77,6 +77,7 @@ public abstract class BsThumbnailQueueBhv extends EsAbstractBehavior<ThumbnailQu
             result.setCreatedTime(DfTypeUtil.toLong(source.get("createdTime")));
             result.setTarget(DfTypeUtil.toString(source.get("target")));
             result.setGenerator(DfTypeUtil.toString(source.get("generator")));
+            result.setThumbnailId(DfTypeUtil.toString(source.get("thumbnail_id")));
             result.setPath(DfTypeUtil.toString(source.get("path")));
             result.setUrl(DfTypeUtil.toString(source.get("url")));
             return updateEntity(source, result);

+ 17 - 0
src/main/java/org/codelibs/fess/es/config/bsentity/BsThumbnailQueue.java

@@ -49,6 +49,9 @@ public class BsThumbnailQueue extends EsAbstractEntity {
     /** generator */
     protected String generator;
 
+    /** thumbnail_id */
+    protected String thumbnailId;
+
     /** path */
     protected String path;
 
@@ -88,6 +91,9 @@ public class BsThumbnailQueue extends EsAbstractEntity {
         if (generator != null) {
             addFieldToSource(sourceMap, "generator", generator);
         }
+        if (thumbnailId != null) {
+            addFieldToSource(sourceMap, "thumbnail_id", thumbnailId);
+        }
         if (path != null) {
             addFieldToSource(sourceMap, "path", path);
         }
@@ -111,6 +117,7 @@ public class BsThumbnailQueue extends EsAbstractEntity {
         sb.append(dm).append(createdTime);
         sb.append(dm).append(target);
         sb.append(dm).append(generator);
+        sb.append(dm).append(thumbnailId);
         sb.append(dm).append(path);
         sb.append(dm).append(url);
         if (sb.length() > dm.length()) {
@@ -163,6 +170,16 @@ public class BsThumbnailQueue extends EsAbstractEntity {
         this.generator = value;
     }
 
+    public String getThumbnailId() {
+        checkSpecifiedProperty("thumbnailId");
+        return convertEmptyToNull(thumbnailId);
+    }
+
+    public void setThumbnailId(String value) {
+        registerModifiedProperty("thumbnailId");
+        this.thumbnailId = value;
+    }
+
     public String getPath() {
         checkSpecifiedProperty("path");
         return convertEmptyToNull(path);

+ 9 - 0
src/main/java/org/codelibs/fess/es/config/bsentity/dbmeta/ThumbnailQueueDbm.java

@@ -87,6 +87,8 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
                 "target");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getGenerator(),
                 (et, vl) -> ((ThumbnailQueue) et).setGenerator(DfTypeUtil.toString(vl)), "generator");
+        setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getThumbnailId(),
+                (et, vl) -> ((ThumbnailQueue) et).setThumbnailId(DfTypeUtil.toString(vl)), "thumbnailId");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getPath(), (et, vl) -> ((ThumbnailQueue) et).setPath(DfTypeUtil.toString(vl)), "path");
         setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getUrl(), (et, vl) -> ((ThumbnailQueue) et).setUrl(DfTypeUtil.toString(vl)), "url");
     }
@@ -133,6 +135,8 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
             "keyword", 0, 0, null, false, null, null, null, null, null, false);
     protected final ColumnInfo _columnGenerator = cci("generator", "generator", null, null, String.class, "generator", null, false, false,
             false, "keyword", 0, 0, null, false, null, null, null, null, null, false);
+    protected final ColumnInfo _columnThumbnailId = cci("thumbnail_id", "thumbnail_id", null, null, String.class, "thumbnailId", null,
+            false, false, false, "keyword", 0, 0, null, false, null, null, null, null, null, false);
     protected final ColumnInfo _columnPath = cci("path", "path", null, null, String.class, "path", null, false, false, false, "keyword", 0,
             0, null, false, null, null, null, null, null, false);
     protected final ColumnInfo _columnUrl = cci("url", "url", null, null, String.class, "url", null, false, false, false, "keyword", 0, 0,
@@ -154,6 +158,10 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
         return _columnGenerator;
     }
 
+    public ColumnInfo columnThumbnailId() {
+        return _columnThumbnailId;
+    }
+
     public ColumnInfo columnPath() {
         return _columnPath;
     }
@@ -168,6 +176,7 @@ public class ThumbnailQueueDbm extends AbstractDBMeta {
         ls.add(columnCreatedTime());
         ls.add(columnTarget());
         ls.add(columnGenerator());
+        ls.add(columnThumbnailId());
         ls.add(columnPath());
         ls.add(columnUrl());
         return ls;

+ 4 - 0
src/main/java/org/codelibs/fess/es/config/cbean/bs/BsThumbnailQueueCB.java

@@ -192,6 +192,10 @@ public class BsThumbnailQueueCB extends EsAbstractConditionBean {
             doColumn("generator");
         }
 
+        public void columnThumbnailId() {
+            doColumn("thumbnail_id");
+        }
+
         public void columnPath() {
             doColumn("path");
         }

+ 131 - 0
src/main/java/org/codelibs/fess/es/config/cbean/ca/bs/BsThumbnailQueueCA.java

@@ -725,6 +725,137 @@ public abstract class BsThumbnailQueueCA extends EsAbstractConditionAggregation
         }
     }
 
+    public void setThumbnailId_Terms() {
+        setThumbnailId_Terms(null);
+    }
+
+    public void setThumbnailId_Terms(ConditionOptionCall<TermsAggregationBuilder> opLambda) {
+        setThumbnailId_Terms("thumbnail_id", opLambda, null);
+    }
+
+    public void setThumbnailId_Terms(ConditionOptionCall<TermsAggregationBuilder> opLambda, OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        setThumbnailId_Terms("thumbnail_id", opLambda, aggsLambda);
+    }
+
+    public void setThumbnailId_Terms(String name, ConditionOptionCall<TermsAggregationBuilder> opLambda,
+            OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        TermsAggregationBuilder builder = regTermsA(name, "thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+        if (aggsLambda != null) {
+            ThumbnailQueueCA ca = new ThumbnailQueueCA();
+            aggsLambda.callback(ca);
+            ca.getAggregationBuilderList().forEach(builder::subAggregation);
+        }
+    }
+
+    public void setThumbnailId_SignificantTerms() {
+        setThumbnailId_SignificantTerms(null);
+    }
+
+    public void setThumbnailId_SignificantTerms(ConditionOptionCall<SignificantTermsAggregationBuilder> opLambda) {
+        setThumbnailId_SignificantTerms("thumbnail_id", opLambda, null);
+    }
+
+    public void setThumbnailId_SignificantTerms(ConditionOptionCall<SignificantTermsAggregationBuilder> opLambda,
+            OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        setThumbnailId_SignificantTerms("thumbnail_id", opLambda, aggsLambda);
+    }
+
+    public void setThumbnailId_SignificantTerms(String name, ConditionOptionCall<SignificantTermsAggregationBuilder> opLambda,
+            OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        SignificantTermsAggregationBuilder builder = regSignificantTermsA(name, "thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+        if (aggsLambda != null) {
+            ThumbnailQueueCA ca = new ThumbnailQueueCA();
+            aggsLambda.callback(ca);
+            ca.getAggregationBuilderList().forEach(builder::subAggregation);
+        }
+    }
+
+    public void setThumbnailId_IpRange() {
+        setThumbnailId_IpRange(null);
+    }
+
+    public void setThumbnailId_IpRange(ConditionOptionCall<IpRangeAggregationBuilder> opLambda) {
+        setThumbnailId_IpRange("thumbnail_id", opLambda, null);
+    }
+
+    public void setThumbnailId_IpRange(ConditionOptionCall<IpRangeAggregationBuilder> opLambda, OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        setThumbnailId_IpRange("thumbnail_id", opLambda, aggsLambda);
+    }
+
+    public void setThumbnailId_IpRange(String name, ConditionOptionCall<IpRangeAggregationBuilder> opLambda,
+            OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        IpRangeAggregationBuilder builder = regIpRangeA(name, "thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+        if (aggsLambda != null) {
+            ThumbnailQueueCA ca = new ThumbnailQueueCA();
+            aggsLambda.callback(ca);
+            ca.getAggregationBuilderList().forEach(builder::subAggregation);
+        }
+    }
+
+    public void setThumbnailId_Count() {
+        setThumbnailId_Count(null);
+    }
+
+    public void setThumbnailId_Count(ConditionOptionCall<ValueCountAggregationBuilder> opLambda) {
+        setThumbnailId_Count("thumbnail_id", opLambda);
+    }
+
+    public void setThumbnailId_Count(String name, ConditionOptionCall<ValueCountAggregationBuilder> opLambda) {
+        ValueCountAggregationBuilder builder = regCountA(name, "thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Cardinality() {
+        setThumbnailId_Cardinality(null);
+    }
+
+    public void setThumbnailId_Cardinality(ConditionOptionCall<CardinalityAggregationBuilder> opLambda) {
+        setThumbnailId_Cardinality("thumbnail_id", opLambda);
+    }
+
+    public void setThumbnailId_Cardinality(String name, ConditionOptionCall<CardinalityAggregationBuilder> opLambda) {
+        CardinalityAggregationBuilder builder = regCardinalityA(name, "thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Missing() {
+        setThumbnailId_Missing(null);
+    }
+
+    public void setThumbnailId_Missing(ConditionOptionCall<MissingAggregationBuilder> opLambda) {
+        setThumbnailId_Missing("thumbnail_id", opLambda, null);
+    }
+
+    public void setThumbnailId_Missing(ConditionOptionCall<MissingAggregationBuilder> opLambda, OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        setThumbnailId_Missing("thumbnail_id", opLambda, aggsLambda);
+    }
+
+    public void setThumbnailId_Missing(String name, ConditionOptionCall<MissingAggregationBuilder> opLambda,
+            OperatorCall<BsThumbnailQueueCA> aggsLambda) {
+        MissingAggregationBuilder builder = regMissingA(name, "thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+        if (aggsLambda != null) {
+            ThumbnailQueueCA ca = new ThumbnailQueueCA();
+            aggsLambda.callback(ca);
+            ca.getAggregationBuilderList().forEach(builder::subAggregation);
+        }
+    }
+
     public void setPath_Terms() {
         setPath_Terms(null);
     }

+ 222 - 0
src/main/java/org/codelibs/fess/es/config/cbean/cq/bs/BsThumbnailQueueCQ.java

@@ -1030,6 +1030,228 @@ public abstract class BsThumbnailQueueCQ extends EsAbstractConditionQuery {
         return this;
     }
 
+    public void setThumbnailId_Equal(String thumbnailId) {
+        setThumbnailId_Term(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Equal(String thumbnailId, ConditionOptionCall<TermQueryBuilder> opLambda) {
+        setThumbnailId_Term(thumbnailId, opLambda);
+    }
+
+    public void setThumbnailId_Term(String thumbnailId) {
+        setThumbnailId_Term(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Term(String thumbnailId, ConditionOptionCall<TermQueryBuilder> opLambda) {
+        TermQueryBuilder builder = regTermQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_NotEqual(String thumbnailId) {
+        setThumbnailId_NotTerm(thumbnailId, null);
+    }
+
+    public void setThumbnailId_NotTerm(String thumbnailId) {
+        setThumbnailId_NotTerm(thumbnailId, null);
+    }
+
+    public void setThumbnailId_NotEqual(String thumbnailId, ConditionOptionCall<BoolQueryBuilder> opLambda) {
+        setThumbnailId_NotTerm(thumbnailId, opLambda);
+    }
+
+    public void setThumbnailId_NotTerm(String thumbnailId, ConditionOptionCall<BoolQueryBuilder> opLambda) {
+        not(not -> not.setThumbnailId_Term(thumbnailId), opLambda);
+    }
+
+    public void setThumbnailId_Terms(Collection<String> thumbnailIdList) {
+        setThumbnailId_Terms(thumbnailIdList, null);
+    }
+
+    public void setThumbnailId_Terms(Collection<String> thumbnailIdList, ConditionOptionCall<TermsQueryBuilder> opLambda) {
+        TermsQueryBuilder builder = regTermsQ("thumbnail_id", thumbnailIdList);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_InScope(Collection<String> thumbnailIdList) {
+        setThumbnailId_Terms(thumbnailIdList, null);
+    }
+
+    public void setThumbnailId_InScope(Collection<String> thumbnailIdList, ConditionOptionCall<TermsQueryBuilder> opLambda) {
+        setThumbnailId_Terms(thumbnailIdList, opLambda);
+    }
+
+    public void setThumbnailId_Match(String thumbnailId) {
+        setThumbnailId_Match(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Match(String thumbnailId, ConditionOptionCall<MatchQueryBuilder> opLambda) {
+        MatchQueryBuilder builder = regMatchQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_MatchPhrase(String thumbnailId) {
+        setThumbnailId_MatchPhrase(thumbnailId, null);
+    }
+
+    public void setThumbnailId_MatchPhrase(String thumbnailId, ConditionOptionCall<MatchPhraseQueryBuilder> opLambda) {
+        MatchPhraseQueryBuilder builder = regMatchPhraseQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_MatchPhrasePrefix(String thumbnailId) {
+        setThumbnailId_MatchPhrasePrefix(thumbnailId, null);
+    }
+
+    public void setThumbnailId_MatchPhrasePrefix(String thumbnailId, ConditionOptionCall<MatchPhrasePrefixQueryBuilder> opLambda) {
+        MatchPhrasePrefixQueryBuilder builder = regMatchPhrasePrefixQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Fuzzy(String thumbnailId) {
+        setThumbnailId_Fuzzy(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Fuzzy(String thumbnailId, ConditionOptionCall<MatchQueryBuilder> opLambda) {
+        MatchQueryBuilder builder = regFuzzyQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Prefix(String thumbnailId) {
+        setThumbnailId_Prefix(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Prefix(String thumbnailId, ConditionOptionCall<PrefixQueryBuilder> opLambda) {
+        PrefixQueryBuilder builder = regPrefixQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Wildcard(String thumbnailId) {
+        setThumbnailId_Wildcard(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Wildcard(String thumbnailId, ConditionOptionCall<WildcardQueryBuilder> opLambda) {
+        WildcardQueryBuilder builder = regWildcardQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Regexp(String thumbnailId) {
+        setThumbnailId_Regexp(thumbnailId, null);
+    }
+
+    public void setThumbnailId_Regexp(String thumbnailId, ConditionOptionCall<RegexpQueryBuilder> opLambda) {
+        RegexpQueryBuilder builder = regRegexpQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_SpanTerm(String thumbnailId) {
+        setThumbnailId_SpanTerm("thumbnail_id", null);
+    }
+
+    public void setThumbnailId_SpanTerm(String thumbnailId, ConditionOptionCall<SpanTermQueryBuilder> opLambda) {
+        SpanTermQueryBuilder builder = regSpanTermQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_GreaterThan(String thumbnailId) {
+        setThumbnailId_GreaterThan(thumbnailId, null);
+    }
+
+    public void setThumbnailId_GreaterThan(String thumbnailId, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        final Object _value = thumbnailId;
+        RangeQueryBuilder builder = regRangeQ("thumbnail_id", ConditionKey.CK_GREATER_THAN, _value);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_LessThan(String thumbnailId) {
+        setThumbnailId_LessThan(thumbnailId, null);
+    }
+
+    public void setThumbnailId_LessThan(String thumbnailId, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        final Object _value = thumbnailId;
+        RangeQueryBuilder builder = regRangeQ("thumbnail_id", ConditionKey.CK_LESS_THAN, _value);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_GreaterEqual(String thumbnailId) {
+        setThumbnailId_GreaterEqual(thumbnailId, null);
+    }
+
+    public void setThumbnailId_GreaterEqual(String thumbnailId, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        final Object _value = thumbnailId;
+        RangeQueryBuilder builder = regRangeQ("thumbnail_id", ConditionKey.CK_GREATER_EQUAL, _value);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_LessEqual(String thumbnailId) {
+        setThumbnailId_LessEqual(thumbnailId, null);
+    }
+
+    public void setThumbnailId_LessEqual(String thumbnailId, ConditionOptionCall<RangeQueryBuilder> opLambda) {
+        final Object _value = thumbnailId;
+        RangeQueryBuilder builder = regRangeQ("thumbnail_id", ConditionKey.CK_LESS_EQUAL, _value);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_Exists() {
+        setThumbnailId_Exists(null);
+    }
+
+    public void setThumbnailId_Exists(ConditionOptionCall<ExistsQueryBuilder> opLambda) {
+        ExistsQueryBuilder builder = regExistsQ("thumbnail_id");
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public void setThumbnailId_CommonTerms(String thumbnailId) {
+        setThumbnailId_CommonTerms(thumbnailId, null);
+    }
+
+    public void setThumbnailId_CommonTerms(String thumbnailId, ConditionOptionCall<CommonTermsQueryBuilder> opLambda) {
+        CommonTermsQueryBuilder builder = regCommonTermsQ("thumbnail_id", thumbnailId);
+        if (opLambda != null) {
+            opLambda.callback(builder);
+        }
+    }
+
+    public BsThumbnailQueueCQ addOrderBy_ThumbnailId_Asc() {
+        regOBA("thumbnail_id");
+        return this;
+    }
+
+    public BsThumbnailQueueCQ addOrderBy_ThumbnailId_Desc() {
+        regOBD("thumbnail_id");
+        return this;
+    }
+
     public void setPath_Equal(String path) {
         setPath_Term(path, null);
     }

+ 12 - 12
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -735,10 +735,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. 800 */
     String THUMBNAIL_HTML_PHANTOMJS_WINDOW_HEIGHT = "thumbnail.html.phantomjs.window.height";
 
-    /** The key of the configuration. e.g. 160 */
+    /** The key of the configuration. e.g. 100 */
     String THUMBNAIL_HTML_PHANTOMJS_THUMBNAIL_WIDTH = "thumbnail.html.phantomjs.thumbnail.width";
 
-    /** The key of the configuration. e.g. 160 */
+    /** The key of the configuration. e.g. 100 */
     String THUMBNAIL_HTML_PHANTOMJS_THUMBNAIL_HEIGHT = "thumbnail.html.phantomjs.thumbnail.height";
 
     /** The key of the configuration. e.g. png */
@@ -759,10 +759,10 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. 800 */
     String THUMBNAIL_HTML_IMAGE_WINDOW_HEIGHT = "thumbnail.html.image.window.height";
 
-    /** The key of the configuration. e.g. 160 */
+    /** The key of the configuration. e.g. 100 */
     String THUMBNAIL_HTML_IMAGE_THUMBNAIL_WIDTH = "thumbnail.html.image.thumbnail.width";
 
-    /** The key of the configuration. e.g. 160 */
+    /** The key of the configuration. e.g. 100 */
     String THUMBNAIL_HTML_IMAGE_THUMBNAIL_HEIGHT = "thumbnail.html.image.thumbnail.height";
 
     /** The key of the configuration. e.g. png */
@@ -3624,14 +3624,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
     /**
      * Get the value for the key 'thumbnail.html.phantomjs.thumbnail.width'. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
     String getThumbnailHtmlPhantomjsThumbnailWidth();
 
     /**
      * Get the value for the key 'thumbnail.html.phantomjs.thumbnail.width' as {@link Integer}. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @throws NumberFormatException When the property is not integer.
      */
@@ -3639,14 +3639,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
     /**
      * Get the value for the key 'thumbnail.html.phantomjs.thumbnail.height'. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
     String getThumbnailHtmlPhantomjsThumbnailHeight();
 
     /**
      * Get the value for the key 'thumbnail.html.phantomjs.thumbnail.height' as {@link Integer}. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @throws NumberFormatException When the property is not integer.
      */
@@ -3736,14 +3736,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
     /**
      * Get the value for the key 'thumbnail.html.image.thumbnail.width'. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
     String getThumbnailHtmlImageThumbnailWidth();
 
     /**
      * Get the value for the key 'thumbnail.html.image.thumbnail.width' as {@link Integer}. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @throws NumberFormatException When the property is not integer.
      */
@@ -3751,14 +3751,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
     /**
      * Get the value for the key 'thumbnail.html.image.thumbnail.height'. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
     String getThumbnailHtmlImageThumbnailHeight();
 
     /**
      * Get the value for the key 'thumbnail.html.image.thumbnail.height' as {@link Integer}. <br>
-     * The value is, e.g. 160 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @throws NumberFormatException When the property is not integer.
      */

+ 3 - 3
src/main/java/org/codelibs/fess/thumbnail/ThumbnailGenerator.java

@@ -18,13 +18,13 @@ package org.codelibs.fess.thumbnail;
 import java.io.File;
 import java.util.Map;
 
-import org.codelibs.core.misc.Tuple3;
+import org.codelibs.core.misc.Tuple4;
 
 public interface ThumbnailGenerator {
 
     String getName();
 
-    boolean generate(String url, File outputFile);
+    boolean generate(String thumbnailId, String url, File outputFile);
 
     boolean isTarget(Map<String, Object> docMap);
 
@@ -32,5 +32,5 @@ public interface ThumbnailGenerator {
 
     void destroy();
 
-    Tuple3<String, String, String> createTask(String path, Map<String, Object> docMap);
+    Tuple4<String, String, String, String> createTask(String path, Map<String, Object> docMap);
 }

+ 32 - 29
src/main/java/org/codelibs/fess/thumbnail/ThumbnailManager.java

@@ -36,7 +36,7 @@ import javax.servlet.http.HttpSession;
 
 import org.codelibs.core.collection.LruHashMap;
 import org.codelibs.core.lang.StringUtil;
-import org.codelibs.core.misc.Tuple3;
+import org.codelibs.core.misc.Tuple4;
 import org.codelibs.fess.Constants;
 import org.codelibs.fess.es.config.exbhv.ThumbnailQueueBhv;
 import org.codelibs.fess.es.config.exentity.ThumbnailQueue;
@@ -66,7 +66,7 @@ public class ThumbnailManager {
 
     private final List<ThumbnailGenerator> generatorList = new ArrayList<>();
 
-    private BlockingQueue<Tuple3<String, String, String>> thumbnailTaskQueue;
+    private BlockingQueue<Tuple4<String, String, String, String>> thumbnailTaskQueue;
 
     private volatile boolean generating;
 
@@ -112,30 +112,32 @@ public class ThumbnailManager {
 
         thumbnailTaskQueue = new LinkedBlockingQueue<>(thumbnailTaskQueueSize);
         generating = true;
-        thumbnailQueueThread = new Thread((Runnable) () -> {
-            final List<Tuple3<String, String, String>> taskList = new ArrayList<>();
-            while (generating) {
-                try {
-                    final Tuple3<String, String, String> task = thumbnailTaskQueue.poll(thumbnailTaskQueueTimeout, TimeUnit.MILLISECONDS);
-                    if (task == null) {
-                        if (!taskList.isEmpty()) {
-                            storeQueue(taskList);
+        thumbnailQueueThread =
+                new Thread((Runnable) () -> {
+                    final List<Tuple4<String, String, String, String>> taskList = new ArrayList<>();
+                    while (generating) {
+                        try {
+                            final Tuple4<String, String, String, String> task =
+                                    thumbnailTaskQueue.poll(thumbnailTaskQueueTimeout, TimeUnit.MILLISECONDS);
+                            if (task == null) {
+                                if (!taskList.isEmpty()) {
+                                    storeQueue(taskList);
+                                }
+                            } else if (!taskList.contains(task)) {
+                                taskList.add(task);
+                                if (taskList.size() > thumbnailTaskBulkSize) {
+                                    storeQueue(taskList);
+                                }
+                            }
+                        } catch (final InterruptedException e) {
+                            logger.debug("Interupted task.", e);
+                        } catch (final Exception e) {
+                            if (generating) {
+                                logger.warn("Failed to generage a thumbnail.", e);
+                            }
                         }
-                    } else if (!taskList.contains(task)) {
-                        taskList.add(task);
-                        if (taskList.size() > thumbnailTaskBulkSize) {
-                            storeQueue(taskList);
-                        }
-                    }
-                } catch (final InterruptedException e) {
-                    logger.debug("Interupted task.", e);
-                } catch (final Exception e) {
-                    if (generating) {
-                        logger.warn("Failed to generage a thumbnail.", e);
                     }
-                }
-            }
-        }, "ThumbnailGenerator");
+                }, "ThumbnailGenerator");
         thumbnailQueueThread.start();
     }
 
@@ -161,7 +163,7 @@ public class ThumbnailManager {
         return "-D" + FESS_THUMBNAIL_PATH + "=" + baseDir.getAbsolutePath();
     }
 
-    protected void storeQueue(final List<Tuple3<String, String, String>> taskList) {
+    protected void storeQueue(final List<Tuple4<String, String, String, String>> taskList) {
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
         final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
         final String[] targets = fessConfig.getThumbnailGeneratorTargetsAsArray();
@@ -170,8 +172,9 @@ public class ThumbnailManager {
             for (final String target : targets) {
                 final ThumbnailQueue entity = new ThumbnailQueue();
                 entity.setGenerator(task.getValue1());
-                entity.setUrl(task.getValue2());
-                entity.setPath(task.getValue3());
+                entity.setThumbnailId(task.getValue2());
+                entity.setUrl(task.getValue3());
+                entity.setPath(task.getValue4());
                 entity.setTarget(target);
                 entity.setCreatedBy(Constants.SYSTEM_USER);
                 entity.setCreatedTime(systemHelper.getCurrentTimeAsLong());
@@ -206,7 +209,7 @@ public class ThumbnailManager {
                     if (noImageFile.isFile() && !noImageFile.delete()) {
                         logger.warn("Failed to delete " + noImageFile.getAbsolutePath());
                     }
-                    if (!generator.generate(entity.getUrl(), outputFile)) {
+                    if (!generator.generate(entity.getThumbnailId(), entity.getUrl(), outputFile)) {
                         new File(outputFile.getAbsolutePath() + NOIMAGE_FILE_SUFFIX).setLastModified(System.currentTimeMillis());
                     }
                 } else if (logger.isDebugEnabled()) {
@@ -229,7 +232,7 @@ public class ThumbnailManager {
         for (final ThumbnailGenerator generator : generatorList) {
             if (generator.isTarget(docMap)) {
                 final String path = getImageFilename(docMap);
-                final Tuple3<String, String, String> task = generator.createTask(path, docMap);
+                final Tuple4<String, String, String, String> task = generator.createTask(path, docMap);
                 if (task != null) {
                     thumbnailTaskQueue.offer(task);
                 }

+ 18 - 3
src/main/java/org/codelibs/fess/thumbnail/impl/BaseThumbnailGenerator.java

@@ -23,13 +23,16 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.codelibs.core.misc.Tuple3;
+import org.codelibs.core.misc.Tuple4;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.thumbnail.ThumbnailGenerator;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.DocumentUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public abstract class BaseThumbnailGenerator implements ThumbnailGenerator {
+    private static final Logger logger = LoggerFactory.getLogger(BaseThumbnailGenerator.class);
 
     protected final Map<String, String> conditionMap = new HashMap<>();
 
@@ -89,10 +92,11 @@ public abstract class BaseThumbnailGenerator implements ThumbnailGenerator {
     }
 
     @Override
-    public Tuple3<String, String, String> createTask(final String path, final Map<String, Object> docMap) {
+    public Tuple4<String, String, String, String> createTask(final String path, final Map<String, Object> docMap) {
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        final String thumbnailId = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldId(), String.class);
         final String url = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldUrl(), String.class);
-        return new Tuple3<>(getName(), url, path);
+        return new Tuple4<>(getName(), thumbnailId, url, path);
     }
 
     public void setDirectoryNameLength(final int directoryNameLength) {
@@ -106,6 +110,17 @@ public abstract class BaseThumbnailGenerator implements ThumbnailGenerator {
         return value;
     }
 
+    protected void updateThumbnailField(final String thumbnailId, final String url, final String value) {
+        // TODO bulk
+        final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        try {
+            ComponentUtil.getIndexingHelper().updateDocument(ComponentUtil.getFessEsClient(), thumbnailId,
+                    fessConfig.getIndexFieldThumbnail(), null);
+        } catch (Exception e) {
+            logger.warn("Failed to update thumbnail field at " + url, e);
+        }
+    }
+
     public void setGeneratorList(final List<String> generatorList) {
         this.generatorList = generatorList;
     }

+ 2 - 1
src/main/java/org/codelibs/fess/thumbnail/impl/CommandGenerator.java

@@ -61,7 +61,7 @@ public class CommandGenerator extends BaseThumbnailGenerator {
     }
 
     @Override
-    public boolean generate(final String url, final File outputFile) {
+    public boolean generate(final String thumbnailId, final String url, final File outputFile) {
         if (logger.isDebugEnabled()) {
             logger.debug("Generate Thumbnail: " + url);
         }
@@ -143,6 +143,7 @@ public class CommandGenerator extends BaseThumbnailGenerator {
         if (logger.isDebugEnabled()) {
             logger.debug("Thumbnail File: " + outputPath);
         }
+        updateThumbnailField(thumbnailId, url, url);
         return true;
     }
 

+ 1 - 1
src/main/java/org/codelibs/fess/thumbnail/impl/EmptyGenerator.java

@@ -20,7 +20,7 @@ import java.io.File;
 public class EmptyGenerator extends BaseThumbnailGenerator {
 
     @Override
-    public boolean generate(final String url, final File outputFile) {
+    public boolean generate(final String thumbnailId, final String url, final File outputFile) {
         return false;
     }
 

+ 6 - 4
src/main/java/org/codelibs/fess/thumbnail/impl/HtmlTagBasedGenerator.java

@@ -29,7 +29,7 @@ import javax.imageio.ImageReader;
 import javax.imageio.stream.ImageInputStream;
 
 import org.codelibs.core.lang.StringUtil;
-import org.codelibs.core.misc.Tuple3;
+import org.codelibs.core.misc.Tuple4;
 import org.codelibs.elasticsearch.runner.net.Curl;
 import org.codelibs.fess.mylasta.direction.FessConfig;
 import org.codelibs.fess.util.ComponentUtil;
@@ -46,17 +46,18 @@ public class HtmlTagBasedGenerator extends BaseThumbnailGenerator {
     }
 
     @Override
-    public Tuple3<String, String, String> createTask(final String path, final Map<String, Object> docMap) {
+    public Tuple4<String, String, String, String> createTask(final String path, final Map<String, Object> docMap) {
         final FessConfig fessConfig = ComponentUtil.getFessConfig();
+        final String thumbnailId = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldId(), String.class);
         final String url = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldThumbnail(), String.class);
         if (StringUtil.isBlank(url)) {
             return null;
         }
-        return new Tuple3<>(getName(), url, path);
+        return new Tuple4<>(getName(), thumbnailId, url, path);
     }
 
     @Override
-    public boolean generate(final String url, final File outputFile) {
+    public boolean generate(final String thumbnailId, final String url, final File outputFile) {
         if (logger.isDebugEnabled()) {
             logger.debug("Generate Thumbnail: " + url);
         }
@@ -82,6 +83,7 @@ public class HtmlTagBasedGenerator extends BaseThumbnailGenerator {
                 saveImage(input, outputFile);
             } catch (final Throwable t) {
                 logger.warn("Failed to convert " + url, t);
+                updateThumbnailField(thumbnailId, url, StringUtil.EMPTY);
             }
         });
 

+ 2 - 1
src/main/java/org/codelibs/fess/thumbnail/impl/WebDriverGenerator.java

@@ -117,7 +117,7 @@ public class WebDriverGenerator extends BaseThumbnailGenerator {
     }
 
     @Override
-    public boolean generate(final String url, final File outputFile) {
+    public boolean generate(final String thumbnailId, final String url, final File outputFile) {
         if (logger.isDebugEnabled()) {
             logger.debug("Generate Thumbnail: " + url);
         }
@@ -154,6 +154,7 @@ public class WebDriverGenerator extends BaseThumbnailGenerator {
                     }
                     final File thumbnail = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
                     convert(thumbnail, outputFile);
+                    updateThumbnailField(thumbnailId, url, url);
                     return true;
                 } catch (final UnreachableBrowserException | SessionNotFoundException e) {
                     if (logger.isDebugEnabled()) {

+ 4 - 4
src/main/resources/fess_config.properties

@@ -381,16 +381,16 @@ thumbnail.html.phantomjs.max.height=20000
 thumbnail.html.phantomjs.keep.alive=600000
 thumbnail.html.phantomjs.window.width=1200
 thumbnail.html.phantomjs.window.height=800
-thumbnail.html.phantomjs.thumbnail.width=160
-thumbnail.html.phantomjs.thumbnail.height=160
+thumbnail.html.phantomjs.thumbnail.width=100
+thumbnail.html.phantomjs.thumbnail.height=100
 thumbnail.html.phantomjs.format=png
 thumbnail.html.image.min.width=50
 thumbnail.html.image.min.height=50
 thumbnail.html.image.max.aspect.ratio=3.0
 thumbnail.html.image.window.width=1200
 thumbnail.html.image.window.height=800
-thumbnail.html.image.thumbnail.width=160
-thumbnail.html.image.thumbnail.height=160
+thumbnail.html.image.thumbnail.width=100
+thumbnail.html.image.thumbnail.height=100
 thumbnail.html.image.format=png
 thumbnail.generator.targets=all
 thumbnail.crawler.enabled=false

+ 3 - 0
src/main/resources/fess_indices/.fess_config/thumbnail_queue.json

@@ -7,6 +7,9 @@
       "enabled": false
     },
     "properties": {
+      "thumbnail_id": {
+        "type": "keyword"
+      },
       "url": {
         "type": "keyword"
       },

+ 14 - 13
src/main/webapp/WEB-INF/view/searchResults.jsp

@@ -33,24 +33,25 @@
 			<c:forEach var="doc" varStatus="s" items="${documentItems}">
 				<li id="result${s.index}">
 					<div class="media">
-						<c:if test="${thumbnailSupport}">
-							<div class="thumbnailBox media-left hidden-xs-down">
-								<a class="link" href="${doc.url_link}"
-									data-uri="${doc.url_link}" data-id="${doc.doc_id}"
-									data-order="${s.index}"> <img
-									src="${fe:url('/images/blank.png')}"
-									data-src="${fe:url('/thumbnail/')}?docId=${f:u(doc.doc_id)}&queryId=${f:u(queryId)}"
-									class="thumbnail">
-								</a>
-							</div>
-						</c:if>
-						<div class="media-body">
+						<div>
 							<h3 class="title ellipsis media-heading">
 								<a class="link" href="${doc.url_link}" data-uri="${doc.url_link}"
 									data-id="${doc.doc_id}" data-order="${s.index}">${f:h(doc.content_title)}</a>
 							</h3>
 							<div class="body">
-								<div class="description">${doc.content_description}</div>
+								<div>
+									<c:if test="${thumbnailSupport && !empty doc.thumbnail}">
+										<div class="thumbnailBox media-left hidden-xs-down">
+											<a class="link" href="${doc.url_link}" data-uri="${doc.url_link}" data-id="${doc.doc_id}"
+												data-order="${s.index}"
+											> <img src="${fe:url('/images/blank.png')}"
+												data-src="${fe:url('/thumbnail/')}?docId=${f:u(doc.doc_id)}&queryId=${f:u(queryId)}" class="thumbnail"
+											>
+											</a>
+										</div>
+									</c:if>
+									<div class="media-body description">${doc.content_description}</div>
+								</div>
 								<div class="site ellipsis">
 									<cite>${f:h(doc.site_path)}</cite>
 									<c:if test="${doc.has_cache=='true'}">

+ 0 - 2
src/main/webapp/css/style.css

@@ -251,8 +251,6 @@ ul.searchOptionLabels li {
 }
 
 .thumbnail {
-	width: 160px;
-	height: 160px;
 	background-position: 50% 50%;
 	background-repeat: no-repeat;
 }

BIN
src/main/webapp/images/noimage.png


+ 9 - 9
src/test/java/org/codelibs/fess/thumbnail/impl/HtmlTagBasedGeneratorTest.java

@@ -38,55 +38,55 @@ public class HtmlTagBasedGeneratorTest extends UnitFessTestCase {
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 106);
+        assertImageSize(outputFile, 100, 66);
 
         imagePath = "thumbnail/600x400.gif";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 106);
+        assertImageSize(outputFile, 100, 66);
 
         imagePath = "thumbnail/600x400.jpg";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 106);
+        assertImageSize(outputFile, 100, 66);
 
         imagePath = "thumbnail/400x400.png";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 160);
+        assertImageSize(outputFile, 100, 100);
 
         imagePath = "thumbnail/400x400.gif";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 160);
+        assertImageSize(outputFile, 100, 100);
 
         imagePath = "thumbnail/400x400.jpg";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 160);
+        assertImageSize(outputFile, 100, 100);
 
         imagePath = "thumbnail/400x600.png";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 160);
+        assertImageSize(outputFile, 100, 100);
 
         imagePath = "thumbnail/400x600.gif";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 160);
+        assertImageSize(outputFile, 100, 100);
 
         imagePath = "thumbnail/400x600.jpg";
         try (ImageInputStream input = ImageIO.createImageInputStream(classLoader.getResourceAsStream(imagePath))) {
             generator.saveImage(input, outputFile);
         }
-        assertImageSize(outputFile, 160, 160);
+        assertImageSize(outputFile, 100, 100);
 
     }