Merge branch '10.3.x'

This commit is contained in:
Shinsuke Sugaya 2016-11-04 06:50:32 +09:00
commit ca38ce3f64
25 changed files with 2347 additions and 77 deletions

View file

@ -962,6 +962,32 @@
"index" : "not_analyzed"
}
}
},
"thumbnail_queue" : {
"_all" : {
"enabled" : false
},
"properties" : {
"createdBy" : {
"type" : "string",
"index" : "not_analyzed"
},
"createdTime" : {
"type" : "long"
},
"generator" : {
"type" : "string",
"index" : "not_analyzed"
},
"path" : {
"type" : "string",
"index" : "not_analyzed"
},
"url" : {
"type" : "string",
"index" : "not_analyzed"
}
}
}
},
"settings" : {

View file

@ -71,7 +71,7 @@ public class ThumbnailAction extends FessSearchAction {
final File thumbnailFile = thumbnailManager.getThumbnailFile(form.queryId, form.docId);
if (thumbnailFile == null) {
// 404
thumbnailManager.generate(doc);
thumbnailManager.offer(doc);
throw responseManager.new404("Thumbnail for " + form.docId + " is under generating.");
}

View file

@ -0,0 +1,257 @@
/*
* Copyright 2012-2016 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.es.config.bsbhv;
import java.util.List;
import java.util.Map;
import org.codelibs.fess.es.config.allcommon.EsAbstractBehavior;
import org.codelibs.fess.es.config.allcommon.EsAbstractEntity.RequestOptionCall;
import org.codelibs.fess.es.config.bsentity.dbmeta.ThumbnailQueueDbm;
import org.codelibs.fess.es.config.cbean.ThumbnailQueueCB;
import org.codelibs.fess.es.config.exentity.ThumbnailQueue;
import org.dbflute.Entity;
import org.dbflute.bhv.readable.CBCall;
import org.dbflute.bhv.readable.EntityRowHandler;
import org.dbflute.cbean.ConditionBean;
import org.dbflute.cbean.result.ListResultBean;
import org.dbflute.cbean.result.PagingResultBean;
import org.dbflute.exception.IllegalBehaviorStateException;
import org.dbflute.optional.OptionalEntity;
import org.dbflute.util.DfTypeUtil;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.delete.DeleteRequestBuilder;
import org.elasticsearch.action.index.IndexRequestBuilder;
/**
* @author ESFlute (using FreeGen)
*/
public abstract class BsThumbnailQueueBhv extends EsAbstractBehavior<ThumbnailQueue, ThumbnailQueueCB> {
// ===================================================================================
// Control Override
// ================
@Override
public String asTableDbName() {
return asEsIndexType();
}
@Override
protected String asEsIndex() {
return ".fess_config";
}
@Override
public String asEsIndexType() {
return "thumbnail_queue";
}
@Override
public String asEsSearchType() {
return "thumbnail_queue";
}
@Override
public ThumbnailQueueDbm asDBMeta() {
return ThumbnailQueueDbm.getInstance();
}
@Override
protected <RESULT extends ThumbnailQueue> RESULT createEntity(Map<String, Object> source, Class<? extends RESULT> entityType) {
try {
final RESULT result = entityType.newInstance();
result.setCreatedBy(DfTypeUtil.toString(source.get("createdBy")));
result.setCreatedTime(DfTypeUtil.toLong(source.get("createdTime")));
result.setGenerator(DfTypeUtil.toString(source.get("generator")));
result.setPath(DfTypeUtil.toString(source.get("path")));
result.setUrl(DfTypeUtil.toString(source.get("url")));
return result;
} catch (InstantiationException | IllegalAccessException e) {
final String msg = "Cannot create a new instance: " + entityType.getName();
throw new IllegalBehaviorStateException(msg, e);
}
}
// ===================================================================================
// Select
// ======
public int selectCount(CBCall<ThumbnailQueueCB> cbLambda) {
return facadeSelectCount(createCB(cbLambda));
}
public OptionalEntity<ThumbnailQueue> selectEntity(CBCall<ThumbnailQueueCB> cbLambda) {
return facadeSelectEntity(createCB(cbLambda));
}
protected OptionalEntity<ThumbnailQueue> facadeSelectEntity(ThumbnailQueueCB cb) {
return doSelectOptionalEntity(cb, typeOfSelectedEntity());
}
protected <ENTITY extends ThumbnailQueue> OptionalEntity<ENTITY> doSelectOptionalEntity(ThumbnailQueueCB cb, Class<? extends ENTITY> tp) {
return createOptionalEntity(doSelectEntity(cb, tp), cb);
}
@Override
public ThumbnailQueueCB newConditionBean() {
return new ThumbnailQueueCB();
}
@Override
protected Entity doReadEntity(ConditionBean cb) {
return facadeSelectEntity(downcast(cb)).orElse(null);
}
public ThumbnailQueue selectEntityWithDeletedCheck(CBCall<ThumbnailQueueCB> cbLambda) {
return facadeSelectEntityWithDeletedCheck(createCB(cbLambda));
}
public OptionalEntity<ThumbnailQueue> selectByPK(String id) {
return facadeSelectByPK(id);
}
protected OptionalEntity<ThumbnailQueue> facadeSelectByPK(String id) {
return doSelectOptionalByPK(id, typeOfSelectedEntity());
}
protected <ENTITY extends ThumbnailQueue> ENTITY doSelectByPK(String id, Class<? extends ENTITY> tp) {
return doSelectEntity(xprepareCBAsPK(id), tp);
}
protected ThumbnailQueueCB xprepareCBAsPK(String id) {
assertObjectNotNull("id", id);
return newConditionBean().acceptPK(id);
}
protected <ENTITY extends ThumbnailQueue> OptionalEntity<ENTITY> doSelectOptionalByPK(String id, Class<? extends ENTITY> tp) {
return createOptionalEntity(doSelectByPK(id, tp), id);
}
@Override
protected Class<? extends ThumbnailQueue> typeOfSelectedEntity() {
return ThumbnailQueue.class;
}
@Override
protected Class<ThumbnailQueue> typeOfHandlingEntity() {
return ThumbnailQueue.class;
}
@Override
protected Class<ThumbnailQueueCB> typeOfHandlingConditionBean() {
return ThumbnailQueueCB.class;
}
public ListResultBean<ThumbnailQueue> selectList(CBCall<ThumbnailQueueCB> cbLambda) {
return facadeSelectList(createCB(cbLambda));
}
public PagingResultBean<ThumbnailQueue> selectPage(CBCall<ThumbnailQueueCB> cbLambda) {
// #pending same?
return (PagingResultBean<ThumbnailQueue>) facadeSelectList(createCB(cbLambda));
}
public void selectCursor(CBCall<ThumbnailQueueCB> cbLambda, EntityRowHandler<ThumbnailQueue> entityLambda) {
facadeSelectCursor(createCB(cbLambda), entityLambda);
}
public void selectBulk(CBCall<ThumbnailQueueCB> cbLambda, EntityRowHandler<List<ThumbnailQueue>> entityLambda) {
delegateSelectBulk(createCB(cbLambda), entityLambda, typeOfSelectedEntity());
}
// ===================================================================================
// Update
// ======
public void insert(ThumbnailQueue entity) {
doInsert(entity, null);
}
public void insert(ThumbnailQueue entity, RequestOptionCall<IndexRequestBuilder> opLambda) {
entity.asDocMeta().indexOption(opLambda);
doInsert(entity, null);
}
public void update(ThumbnailQueue entity) {
doUpdate(entity, null);
}
public void update(ThumbnailQueue entity, RequestOptionCall<IndexRequestBuilder> opLambda) {
entity.asDocMeta().indexOption(opLambda);
doUpdate(entity, null);
}
public void insertOrUpdate(ThumbnailQueue entity) {
doInsertOrUpdate(entity, null, null);
}
public void insertOrUpdate(ThumbnailQueue entity, RequestOptionCall<IndexRequestBuilder> opLambda) {
entity.asDocMeta().indexOption(opLambda);
doInsertOrUpdate(entity, null, null);
}
public void delete(ThumbnailQueue entity) {
doDelete(entity, null);
}
public void delete(ThumbnailQueue entity, RequestOptionCall<DeleteRequestBuilder> opLambda) {
entity.asDocMeta().deleteOption(opLambda);
doDelete(entity, null);
}
public int queryDelete(CBCall<ThumbnailQueueCB> cbLambda) {
return doQueryDelete(createCB(cbLambda), null);
}
public int[] batchInsert(List<ThumbnailQueue> list) {
return batchInsert(list, null, null);
}
public int[] batchInsert(List<ThumbnailQueue> list, RequestOptionCall<BulkRequestBuilder> call) {
return batchInsert(list, call, null);
}
public int[] batchInsert(List<ThumbnailQueue> list, RequestOptionCall<BulkRequestBuilder> call,
RequestOptionCall<IndexRequestBuilder> entityCall) {
return doBatchInsert(new BulkList<>(list, call, entityCall), null);
}
public int[] batchUpdate(List<ThumbnailQueue> list) {
return batchUpdate(list, null, null);
}
public int[] batchUpdate(List<ThumbnailQueue> list, RequestOptionCall<BulkRequestBuilder> call) {
return batchUpdate(list, call, null);
}
public int[] batchUpdate(List<ThumbnailQueue> list, RequestOptionCall<BulkRequestBuilder> call,
RequestOptionCall<IndexRequestBuilder> entityCall) {
return doBatchUpdate(new BulkList<>(list, call, entityCall), null);
}
public int[] batchDelete(List<ThumbnailQueue> list) {
return batchDelete(list, null, null);
}
public int[] batchDelete(List<ThumbnailQueue> list, RequestOptionCall<BulkRequestBuilder> call) {
return batchDelete(list, call, null);
}
public int[] batchDelete(List<ThumbnailQueue> list, RequestOptionCall<BulkRequestBuilder> call,
RequestOptionCall<IndexRequestBuilder> entityCall) {
return doBatchDelete(new BulkList<>(list, call, entityCall), null);
}
// #pending create, modify, remove
}

View file

@ -0,0 +1,164 @@
/*
* Copyright 2012-2016 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.es.config.bsentity;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import org.codelibs.fess.es.config.allcommon.EsAbstractEntity;
import org.codelibs.fess.es.config.bsentity.dbmeta.ThumbnailQueueDbm;
/**
* ${table.comment}
* @author ESFlute (using FreeGen)
*/
public class BsThumbnailQueue extends EsAbstractEntity {
// ===================================================================================
// Definition
// ==========
private static final long serialVersionUID = 1L;
protected static final Class<?> suppressUnusedImportLocalDateTime = LocalDateTime.class;
// ===================================================================================
// Attribute
// =========
/** createdBy */
protected String createdBy;
/** createdTime */
protected Long createdTime;
/** generator */
protected String generator;
/** path */
protected String path;
/** url */
protected String url;
// [Referrers] *comment only
// ===================================================================================
// DB Meta
// =======
@Override
public ThumbnailQueueDbm asDBMeta() {
return ThumbnailQueueDbm.getInstance();
}
@Override
public String asTableDbName() {
return "thumbnail_queue";
}
// ===================================================================================
// Source
// ======
@Override
public Map<String, Object> toSource() {
Map<String, Object> sourceMap = new HashMap<>();
if (createdBy != null) {
sourceMap.put("createdBy", createdBy);
}
if (createdTime != null) {
sourceMap.put("createdTime", createdTime);
}
if (generator != null) {
sourceMap.put("generator", generator);
}
if (path != null) {
sourceMap.put("path", path);
}
if (url != null) {
sourceMap.put("url", url);
}
return sourceMap;
}
// ===================================================================================
// Basic Override
// ==============
@Override
protected String doBuildColumnString(String dm) {
StringBuilder sb = new StringBuilder();
sb.append(dm).append(createdBy);
sb.append(dm).append(createdTime);
sb.append(dm).append(generator);
sb.append(dm).append(path);
sb.append(dm).append(url);
if (sb.length() > dm.length()) {
sb.delete(0, dm.length());
}
sb.insert(0, "{").append("}");
return sb.toString();
}
// ===================================================================================
// Accessor
// ========
public String getCreatedBy() {
checkSpecifiedProperty("createdBy");
return convertEmptyToNull(createdBy);
}
public void setCreatedBy(String value) {
registerModifiedProperty("createdBy");
this.createdBy = value;
}
public Long getCreatedTime() {
checkSpecifiedProperty("createdTime");
return createdTime;
}
public void setCreatedTime(Long value) {
registerModifiedProperty("createdTime");
this.createdTime = value;
}
public String getGenerator() {
checkSpecifiedProperty("generator");
return convertEmptyToNull(generator);
}
public void setGenerator(String value) {
registerModifiedProperty("generator");
this.generator = value;
}
public String getPath() {
checkSpecifiedProperty("path");
return convertEmptyToNull(path);
}
public void setPath(String value) {
registerModifiedProperty("path");
this.path = value;
}
public String getUrl() {
checkSpecifiedProperty("url");
return convertEmptyToNull(url);
}
public void setUrl(String value) {
registerModifiedProperty("url");
this.url = value;
}
}

View file

@ -0,0 +1,239 @@
/*
* Copyright 2012-2016 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.es.config.bsentity.dbmeta;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import org.codelibs.fess.es.config.exentity.ThumbnailQueue;
import org.dbflute.Entity;
import org.dbflute.dbmeta.AbstractDBMeta;
import org.dbflute.dbmeta.info.ColumnInfo;
import org.dbflute.dbmeta.info.UniqueInfo;
import org.dbflute.dbmeta.name.TableSqlName;
import org.dbflute.dbmeta.property.PropertyGateway;
import org.dbflute.dbway.DBDef;
import org.dbflute.util.DfTypeUtil;
/**
* @author ESFlute (using FreeGen)
*/
public class ThumbnailQueueDbm extends AbstractDBMeta {
protected static final Class<?> suppressUnusedImportLocalDateTime = LocalDateTime.class;
// ===================================================================================
// Singleton
// =========
private static final ThumbnailQueueDbm _instance = new ThumbnailQueueDbm();
private ThumbnailQueueDbm() {
}
public static ThumbnailQueueDbm getInstance() {
return _instance;
}
// ===================================================================================
// Current DBDef
// =============
@Override
public String getProjectName() {
return null;
}
@Override
public String getProjectPrefix() {
return null;
}
@Override
public String getGenerationGapBasePrefix() {
return null;
}
@Override
public DBDef getCurrentDBDef() {
return null;
}
// ===================================================================================
// Property Gateway
// ================
// -----------------------------------------------------
// Column Property
// ---------------
protected final Map<String, PropertyGateway> _epgMap = newHashMap();
{
setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getCreatedBy(),
(et, vl) -> ((ThumbnailQueue) et).setCreatedBy(DfTypeUtil.toString(vl)), "createdBy");
setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getCreatedTime(),
(et, vl) -> ((ThumbnailQueue) et).setCreatedTime(DfTypeUtil.toLong(vl)), "createdTime");
setupEpg(_epgMap, et -> ((ThumbnailQueue) et).getGenerator(),
(et, vl) -> ((ThumbnailQueue) et).setGenerator(DfTypeUtil.toString(vl)), "generator");
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");
}
@Override
public PropertyGateway findPropertyGateway(final String prop) {
return doFindEpg(_epgMap, prop);
}
// ===================================================================================
// Table Info
// ==========
protected final String _tableDbName = "thumbnail_queue";
protected final String _tableDispName = "thumbnail_queue";
protected final String _tablePropertyName = "ThumbnailQueue";
public String getTableDbName() {
return _tableDbName;
}
@Override
public String getTableDispName() {
return _tableDispName;
}
@Override
public String getTablePropertyName() {
return _tablePropertyName;
}
@Override
public TableSqlName getTableSqlName() {
return null;
}
// ===================================================================================
// Column Info
// ===========
protected final ColumnInfo _columnCreatedBy = cci("createdBy", "createdBy", null, null, String.class, "createdBy", null, false, false,
false, "String", 0, 0, null, false, null, null, null, null, null, false);
protected final ColumnInfo _columnCreatedTime = cci("createdTime", "createdTime", null, null, Long.class, "createdTime", null, false,
false, false, "Long", 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, "String", 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, "String", 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, "String", 0, 0,
null, false, null, null, null, null, null, false);
public ColumnInfo columnCreatedBy() {
return _columnCreatedBy;
}
public ColumnInfo columnCreatedTime() {
return _columnCreatedTime;
}
public ColumnInfo columnGenerator() {
return _columnGenerator;
}
public ColumnInfo columnPath() {
return _columnPath;
}
public ColumnInfo columnUrl() {
return _columnUrl;
}
protected List<ColumnInfo> ccil() {
List<ColumnInfo> ls = newArrayList();
ls.add(columnCreatedBy());
ls.add(columnCreatedTime());
ls.add(columnGenerator());
ls.add(columnPath());
ls.add(columnUrl());
return ls;
}
// ===================================================================================
// Unique Info
// ===========
@Override
public boolean hasPrimaryKey() {
return false;
}
@Override
public boolean hasCompoundPrimaryKey() {
return false;
}
@Override
protected UniqueInfo cpui() {
return null;
}
// ===================================================================================
// Type Name
// =========
@Override
public String getEntityTypeName() {
return "org.codelibs.fess.es.config.exentity.ThumbnailQueue";
}
@Override
public String getConditionBeanTypeName() {
return "org.codelibs.fess.es.config.cbean.ThumbnailQueueCB";
}
@Override
public String getBehaviorTypeName() {
return "org.codelibs.fess.es.config.exbhv.ThumbnailQueueBhv";
}
// ===================================================================================
// Object Type
// ===========
@Override
public Class<? extends Entity> getEntityType() {
return ThumbnailQueue.class;
}
// ===================================================================================
// Object Instance
// ===============
@Override
public Entity newEntity() {
return new ThumbnailQueue();
}
// ===================================================================================
// Map Communication
// =================
@Override
public void acceptPrimaryKeyMap(Entity entity, Map<String, ? extends Object> primaryKeyMap) {
}
@Override
public void acceptAllColumnMap(Entity entity, Map<String, ? extends Object> allColumnMap) {
}
@Override
public Map<String, Object> extractPrimaryKeyMap(Entity entity) {
return null;
}
@Override
public Map<String, Object> extractAllColumnMap(Entity entity) {
return null;
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright 2012-2016 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.es.config.cbean;
import org.codelibs.fess.es.config.cbean.bs.BsThumbnailQueueCB;
/**
* @author ESFlute (using FreeGen)
*/
public class ThumbnailQueueCB extends BsThumbnailQueueCB {
}

View file

@ -0,0 +1,170 @@
/*
* Copyright 2012-2016 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.es.config.cbean.bs;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.codelibs.fess.es.config.allcommon.EsAbstractConditionBean;
import org.codelibs.fess.es.config.bsentity.dbmeta.ThumbnailQueueDbm;
import org.codelibs.fess.es.config.cbean.ThumbnailQueueCB;
import org.codelibs.fess.es.config.cbean.cq.ThumbnailQueueCQ;
import org.codelibs.fess.es.config.cbean.cq.bs.BsThumbnailQueueCQ;
import org.dbflute.cbean.ConditionQuery;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.index.query.QueryBuilder;
/**
* @author ESFlute (using FreeGen)
*/
public class BsThumbnailQueueCB extends EsAbstractConditionBean {
// ===================================================================================
// Attribute
// =========
protected BsThumbnailQueueCQ _conditionQuery;
protected HpSpecification _specification;
// ===================================================================================
// Control
// =======
@Override
public ThumbnailQueueDbm asDBMeta() {
return ThumbnailQueueDbm.getInstance();
}
@Override
public String asTableDbName() {
return "thumbnail_queue";
}
@Override
public boolean hasSpecifiedColumn() {
return _specification != null;
}
@Override
public ConditionQuery localCQ() {
return doGetConditionQuery();
}
// ===================================================================================
// Primary Key
// ===========
public ThumbnailQueueCB acceptPK(String id) {
assertObjectNotNull("id", id);
BsThumbnailQueueCB cb = this;
cb.query().docMeta().setId_Equal(id);
return (ThumbnailQueueCB) this;
}
@Override
public void acceptPrimaryKeyMap(Map<String, ? extends Object> primaryKeyMap) {
acceptPK((String) primaryKeyMap.get("_id"));
}
// ===================================================================================
// Build
// =====
@Override
public SearchRequestBuilder build(SearchRequestBuilder builder) {
if (_conditionQuery != null) {
QueryBuilder queryBuilder = _conditionQuery.getQuery();
if (queryBuilder != null) {
builder.setQuery(queryBuilder);
}
_conditionQuery.getFieldSortBuilderList().forEach(sort -> {
builder.addSort(sort);
});
}
if (_specification != null) {
builder.setFetchSource(_specification.columnList.toArray(new String[_specification.columnList.size()]), null);
}
return builder;
}
// ===================================================================================
// Query
// =====
public BsThumbnailQueueCQ query() {
assertQueryPurpose();
return doGetConditionQuery();
}
protected BsThumbnailQueueCQ doGetConditionQuery() {
if (_conditionQuery == null) {
_conditionQuery = createLocalCQ();
}
return _conditionQuery;
}
protected BsThumbnailQueueCQ createLocalCQ() {
return new ThumbnailQueueCQ();
}
// ===================================================================================
// Specify
// =======
public HpSpecification specify() {
assertSpecifyPurpose();
if (_specification == null) {
_specification = new HpSpecification();
}
return _specification;
}
protected void assertQueryPurpose() {
}
protected void assertSpecifyPurpose() {
}
public static class HpSpecification {
private List<String> columnList = new ArrayList<>();
private void doColumn(String name) {
columnList.add(name);
}
public void columnId() {
doColumn("_id");
}
public void columnCreatedBy() {
doColumn("createdBy");
}
public void columnCreatedTime() {
doColumn("createdTime");
}
public void columnGenerator() {
doColumn("generator");
}
public void columnPath() {
doColumn("path");
}
public void columnUrl() {
doColumn("url");
}
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright 2012-2016 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.es.config.cbean.cq;
import org.codelibs.fess.es.config.cbean.cq.bs.BsThumbnailQueueCQ;
/**
* @author ESFlute (using FreeGen)
*/
public class ThumbnailQueueCQ extends BsThumbnailQueueCQ {
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
/*
* Copyright 2012-2016 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.es.config.exbhv;
import org.codelibs.fess.es.config.bsbhv.BsThumbnailQueueBhv;
/**
* @author FreeGen
*/
public class ThumbnailQueueBhv extends BsThumbnailQueueBhv {
}

View file

@ -0,0 +1,48 @@
/*
* Copyright 2012-2016 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.es.config.exentity;
import org.codelibs.fess.es.config.bsentity.BsThumbnailQueue;
/**
* @author ESFlute (using FreeGen)
*/
public class ThumbnailQueue extends BsThumbnailQueue {
private static final long serialVersionUID = 1L;
public String getId() {
return asDocMeta().id();
}
public void setId(final String id) {
asDocMeta().id(id);
}
public Long getVersionNo() {
return asDocMeta().version();
}
public void setVersionNo(final Long version) {
asDocMeta().version(version);
}
@Override
public String toString() {
return "ThumbnailQueue [createdBy=" + createdBy + ", createdTime=" + createdTime + ", generator=" + generator + ", path=" + path
+ ", url=" + url + "]";
}
}

View file

@ -0,0 +1,40 @@
/*
* Copyright 2012-2016 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.job;
import org.codelibs.fess.util.ComponentUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GenerateThumbnailJob {
private static final Logger logger = LoggerFactory.getLogger(GenerateThumbnailJob.class);
public String execute() {
int totalCount = 0;
int count = 1;
try {
while (count != 0) {
count = ComponentUtil.getThumbnailManager().generate();
totalCount += count;
}
return "Created " + totalCount + " thumbnail files.";
} catch (final Exception e) {
logger.error("Failed to purge user info.", e);
return e.getMessage();
}
}
}

View file

@ -637,6 +637,9 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
/** The key of the configuration. e.g. 1000 */
String PAGE_DICTIONARY_MAX_FETCH_SIZE = "page.dictionary.max.fetch.size";
/** The key of the configuration. e.g. 100 */
String PAGE_THUMBNAIL_QUEUE_MAX_FETCH_SIZE = "page.thumbnail.queue.max.fetch.size";
/** The key of the configuration. e.g. 0 */
String PAGING_SEARCH_PAGE_START = "paging.search.page.start";
@ -3084,6 +3087,21 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
*/
Integer getPageDictionaryMaxFetchSizeAsInteger();
/**
* Get the value for the key 'page.thumbnail.queue.max.fetch.size'. <br>
* The value is, e.g. 100 <br>
* @return The value of found property. (NotNull: if not found, exception but basically no way)
*/
String getPageThumbnailQueueMaxFetchSize();
/**
* Get the value for the key 'page.thumbnail.queue.max.fetch.size' as {@link Integer}. <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.
*/
Integer getPageThumbnailQueueMaxFetchSizeAsInteger();
/**
* Get the value for the key 'paging.search.page.start'. <br>
* The value is, e.g. 0 <br>
@ -5340,6 +5358,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
return getAsInteger(FessConfig.PAGE_DICTIONARY_MAX_FETCH_SIZE);
}
public String getPageThumbnailQueueMaxFetchSize() {
return get(FessConfig.PAGE_THUMBNAIL_QUEUE_MAX_FETCH_SIZE);
}
public Integer getPageThumbnailQueueMaxFetchSizeAsInteger() {
return getAsInteger(FessConfig.PAGE_THUMBNAIL_QUEUE_MAX_FETCH_SIZE);
}
public String getPagingSearchPageStart() {
return get(FessConfig.PAGING_SEARCH_PAGE_START);
}

View file

@ -20,6 +20,8 @@ import java.util.Map;
public interface ThumbnailGenerator {
String getName();
boolean generate(String url, File outputFile);
boolean isTarget(Map<String, Object> docMap);

View file

@ -28,6 +28,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@ -37,7 +39,10 @@ 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.fess.Constants;
import org.codelibs.fess.es.config.exbhv.ThumbnailQueueBhv;
import org.codelibs.fess.es.config.exentity.ThumbnailQueue;
import org.codelibs.fess.exception.FessSystemException;
import org.codelibs.fess.exception.JobProcessingException;
import org.codelibs.fess.mylasta.direction.FessConfig;
@ -61,7 +66,7 @@ public class ThumbnailManager {
private final List<ThumbnailGenerator> generatorList = new ArrayList<>();
private BlockingQueue<ThumbnailTask> thumbnailTaskQueue;
private BlockingQueue<Tuple3<String, String, String>> thumbnailTaskQueue;
private volatile boolean generating;
@ -75,6 +80,10 @@ public class ThumbnailManager {
protected int thumbnailTaskQueueSize = 10000;
protected int thumbnailTaskBulkSize = 100;
protected long thumbnailTaskQueueTimeout = 60 * 1000L;
protected long noImageExpired = 24 * 60 * 60 * 1000L; // 24 hours
@PostConstruct
@ -104,9 +113,20 @@ public class ThumbnailManager {
thumbnailTaskQueue = new LinkedBlockingQueue<>(thumbnailTaskQueueSize);
generating = true;
thumbnailGeneratorThread = new Thread((Runnable) () -> {
final List<Tuple3<String, String, String>> taskList = new ArrayList<>();
while (generating) {
try {
thumbnailTaskQueue.take().generate();
Tuple3<String, String, String> task = thumbnailTaskQueue.poll(thumbnailTaskQueueTimeout, TimeUnit.MILLISECONDS);
if (task == null) {
if (!taskList.isEmpty()) {
storeQueue(taskList);
}
} else {
taskList.add(task);
if (taskList.size() > thumbnailTaskBulkSize) {
storeQueue(taskList);
}
}
} catch (final InterruptedException e) {
logger.debug("Interupted task.", e);
} catch (final Exception e) {
@ -137,24 +157,64 @@ public class ThumbnailManager {
});
}
public void generate(final Map<String, Object> docMap) {
protected void storeQueue(final List<Tuple3<String, String, String>> taskList) {
List<ThumbnailQueue> list = taskList.stream().filter(entity -> entity != null).map(task -> {
ThumbnailQueue entity = new ThumbnailQueue();
entity.setGenerator(task.getValue1());
entity.setUrl(task.getValue2());
entity.setPath(task.getValue3());
return entity;
}).collect(Collectors.toList());
taskList.clear();
final ThumbnailQueueBhv thumbnailQueueBhv = ComponentUtil.getComponent(ThumbnailQueueBhv.class);
thumbnailQueueBhv.batchInsert(list);
}
public int generate() {
final FessConfig fessConfig = ComponentUtil.getFessConfig();
for (final ThumbnailGenerator generator : generatorList) {
if (generator.isTarget(docMap)) {
final String url = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldUrl(), String.class);
final String path = getImageFilename(docMap);
final File outputFile = new File(baseDir, path);
final List<String> idList = new ArrayList<>();
final ThumbnailQueueBhv thumbnailQueueBhv = ComponentUtil.getComponent(ThumbnailQueueBhv.class);
thumbnailQueueBhv.selectList(cb -> {
cb.query().addOrderBy_CreatedTime_Asc();
cb.fetchFirst(fessConfig.getPageThumbnailQueueMaxFetchSizeAsInteger());
}).forEach(entity -> {
idList.add(entity.getId());
final String generatorName = entity.getGenerator();
try {
final ThumbnailGenerator generator = ComponentUtil.getComponent(generatorName);
final File outputFile = new File(baseDir, entity.getPath());
final File noImageFile = new File(outputFile.getAbsolutePath() + NOIMAGE_FILE_SUFFIX);
if (!noImageFile.isFile() || System.currentTimeMillis() - noImageFile.lastModified() > noImageExpired) {
if (noImageFile.isFile() && !noImageFile.delete()) {
logger.warn("Failed to delete " + noImageFile.getAbsolutePath());
}
if (!thumbnailTaskQueue.offer(new ThumbnailTask(url, outputFile, generator))) {
logger.warn("Failed to offer a thumbnail task: " + url + " -> " + path);
if (!generator.generate(entity.getUrl(), outputFile)) {
new File(outputFile.getAbsolutePath() + NOIMAGE_FILE_SUFFIX).setLastModified(System.currentTimeMillis());
}
} else if (logger.isDebugEnabled()) {
logger.debug("No image file exists: " + noImageFile.getAbsolutePath());
}
} catch (final Exception e) {
logger.warn("Failed to create thumbnail for " + entity, e);
}
});
if (!idList.isEmpty()) {
thumbnailQueueBhv.queryDelete(cb -> {
cb.query().setId_InScope(idList);
});
thumbnailQueueBhv.refresh();
}
return idList.size();
}
public void offer(final Map<String, Object> docMap) {
final FessConfig fessConfig = ComponentUtil.getFessConfig();
for (final ThumbnailGenerator generator : generatorList) {
if (generator.isTarget(docMap)) {
final String url = DocumentUtil.getValue(docMap, fessConfig.getIndexFieldUrl(), String.class);
final String path = getImageFilename(docMap);
Tuple3<String, String, String> task = new Tuple3<String, String, String>(generator.getName(), url, path);
thumbnailTaskQueue.offer(task);
break;
}
}
@ -283,66 +343,6 @@ public class ThumbnailManager {
}
protected static class ThumbnailTask {
String url;
File outputFile;
ThumbnailGenerator generator;
protected ThumbnailTask(final String url, final File outputFile, final ThumbnailGenerator generator) {
this.url = url;
this.outputFile = outputFile;
this.generator = generator;
}
public void generate() {
if (!generator.generate(url, outputFile)) {
new File(outputFile.getAbsolutePath() + NOIMAGE_FILE_SUFFIX).setLastModified(System.currentTimeMillis());
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (outputFile == null ? 0 : outputFile.hashCode());
result = prime * result + (url == null ? 0 : url.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ThumbnailTask other = (ThumbnailTask) obj;
if (outputFile == null) {
if (other.outputFile != null) {
return false;
}
} else if (!outputFile.equals(other.outputFile)) {
return false;
}
if (url == null) {
if (other.url != null) {
return false;
}
} else if (!url.equals(other.url)) {
return false;
}
return true;
}
}
public void setThumbnailPathCacheSize(final int thumbnailPathCacheSize) {
this.thumbnailPathCacheSize = thumbnailPathCacheSize;
}

View file

@ -41,6 +41,8 @@ public abstract class BaseThumbnailGenerator implements ThumbnailGenerator {
protected Map<String, String> filePathMap = new HashMap<>();
protected String name;
public void addCondition(final String key, final String regex) {
conditionMap.put(key, regex);
}
@ -103,4 +105,12 @@ public abstract class BaseThumbnailGenerator implements ThumbnailGenerator {
this.generatorList = generatorList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View file

@ -204,6 +204,9 @@
<postConstruct name="addIndexConfig">
<arg>".fess_config/web_config_to_role"</arg>
</postConstruct>
<postConstruct name="addIndexConfig">
<arg>".fess_config/thumbnail_queue"</arg>
</postConstruct>
<!-- .fess_user index -->
<postConstruct name="addIndexConfig">
<arg>".fess_user/user"</arg>

View file

@ -9,6 +9,7 @@
<!-- The components of Behavior. -->
<component name="accessTokenBhv" class="org.codelibs.fess.es.config.exbhv.AccessTokenBhv"/>
<component name="badWordBhv" class="org.codelibs.fess.es.config.exbhv.BadWordBhv"/>
<component name="boostDocumentRuleBhv" class="org.codelibs.fess.es.config.exbhv.BoostDocumentRuleBhv"/>
<component name="crawlingInfoBhv" class="org.codelibs.fess.es.config.exbhv.CrawlingInfoBhv"/>
<component name="crawlingInfoParamBhv" class="org.codelibs.fess.es.config.exbhv.CrawlingInfoParamBhv"/>
@ -16,6 +17,8 @@
<component name="dataConfigToRoleBhv" class="org.codelibs.fess.es.config.exbhv.DataConfigToRoleBhv"/>
<component name="dataConfigBhv" class="org.codelibs.fess.es.config.exbhv.DataConfigBhv"/>
<component name="duplicateHostBhv" class="org.codelibs.fess.es.config.exbhv.DuplicateHostBhv"/>
<component name="elevateWordToLabelBhv" class="org.codelibs.fess.es.config.exbhv.ElevateWordToLabelBhv"/>
<component name="elevateWordBhv" class="org.codelibs.fess.es.config.exbhv.ElevateWordBhv"/>
<component name="failureUrlBhv" class="org.codelibs.fess.es.config.exbhv.FailureUrlBhv"/>
<component name="fileAuthenticationBhv" class="org.codelibs.fess.es.config.exbhv.FileAuthenticationBhv"/>
<component name="fileConfigToLabelBhv" class="org.codelibs.fess.es.config.exbhv.FileConfigToLabelBhv"/>
@ -29,9 +32,7 @@
<component name="requestHeaderBhv" class="org.codelibs.fess.es.config.exbhv.RequestHeaderBhv"/>
<component name="roleTypeBhv" class="org.codelibs.fess.es.config.exbhv.RoleTypeBhv"/>
<component name="scheduledJobBhv" class="org.codelibs.fess.es.config.exbhv.ScheduledJobBhv"/>
<component name="badWordBhv" class="org.codelibs.fess.es.config.exbhv.BadWordBhv"/>
<component name="elevateWordToLabelBhv" class="org.codelibs.fess.es.config.exbhv.ElevateWordToLabelBhv"/>
<component name="elevateWordBhv" class="org.codelibs.fess.es.config.exbhv.ElevateWordBhv"/>
<component name="thumbnailQueueBhv" class="org.codelibs.fess.es.config.exbhv.ThumbnailQueueBhv"/>
<component name="webAuthenticationBhv" class="org.codelibs.fess.es.config.exbhv.WebAuthenticationBhv"/>
<component name="webConfigToLabelBhv" class="org.codelibs.fess.es.config.exbhv.WebConfigToLabelBhv"/>
<component name="webConfigToRoleBhv" class="org.codelibs.fess.es.config.exbhv.WebConfigToRoleBhv"/>

View file

@ -341,6 +341,7 @@ page.search.field.log.max.fetch.size=100
page.elevate.word.max.fetch.size=1000
page.bad.word.max.fetch.size=1000
page.dictionary.max.fetch.size=1000
page.thumbnail.queue.max.fetch.size=100
# search page
paging.search.page.start=0

View file

@ -20,6 +20,11 @@
"type": {
"value": "job_log"
}
},
{
"type": {
"value": "thumbnail_queue"
}
}
]
}

View file

@ -8,7 +8,9 @@
{"name":"Log Purger","target":"all","cronExpression":"0 0 * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeLogJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":4,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"doc_purger"}}
{"name":"Doc Purger","target":"all","cronExpression":"* * * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeDocJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":5,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"thumbnail_generate"}}
{"name":"Thumbnail Generator","target":"all","cronExpression":"* * * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"generateThumbnailJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":6,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"thumbnail_purger"}}
{"name":"Thumbnail Purger","target":"all","cronExpression":"0 0 * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeThumbnailJob\").expiry(30 * 24 * 60 * 60 * 1000).execute();","jobLogging":true,"crawler":false,"available":true,"sortOrder":6,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"name":"Thumbnail Purger","target":"all","cronExpression":"0 0 * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"purgeThumbnailJob\").expiry(30 * 24 * 60 * 60 * 1000).execute();","jobLogging":true,"crawler":false,"available":true,"sortOrder":7,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"index":{"_index":".fess_config","_type":"scheduled_job","_id":"ping_es"}}
{"name":"Ping Elasticsearch","target":"all","cronExpression":"* * * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"pingEsJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":7,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}
{"name":"Ping Elasticsearch","target":"all","cronExpression":"* * * * *","scriptType":"groovy","scriptData":"return container.getComponent(\"pingEsJob\").execute();","jobLogging":false,"crawler":false,"available":true,"sortOrder":8,"createdBy":"system","createdTime":0,"updatedBy":"system","updatedTime":0}

View file

@ -0,0 +1,31 @@
{
"thumbnail_queue": {
"_source": {
"enabled": true
},
"_all": {
"enabled": false
},
"properties": {
"url": {
"type": "string",
"index": "not_analyzed"
},
"path": {
"type": "string",
"index": "not_analyzed"
},
"generator": {
"type": "string",
"index": "not_analyzed"
},
"createdTime": {
"type": "long"
},
"createdBy": {
"type": "string",
"index": "not_analyzed"
}
}
}
}

View file

@ -16,6 +16,8 @@
</component>
<component name="purgeLogJob" class="org.codelibs.fess.job.PurgeLogJob" instance="prototype">
</component>
<component name="generateThumbnailJob" class="org.codelibs.fess.job.GenerateThumbnailJob" instance="prototype">
</component>
<component name="purgeThumbnailJob" class="org.codelibs.fess.job.PurgeThumbnailJob" instance="prototype">
</component>
<component name="pingEsJob" class="org.codelibs.fess.job.PingEsJob" instance="prototype">

View file

@ -11,6 +11,7 @@
</postConstruct>
</component>
<component name="htmlThumbnailGenerator" class="org.codelibs.fess.thumbnail.impl.WebDriverGenerator">
<property name="name">"htmlThumbnailGenerator"</property>
<property name="generatorList">
["${path}/phantomjs"]
</property>
@ -29,6 +30,7 @@
</component>
<!--
<component name="htmlThumbnailGenerator" class="org.codelibs.fess.thumbnail.impl.CommandGenerator">
<property name="name">"htmlThumbnailGenerator"</property>
<property name="commandList">
["${path}/generate-thumbnail",
"html",
@ -45,6 +47,7 @@
</component>
-->
<component name="msofficeThumbnailGenerator" class="org.codelibs.fess.thumbnail.impl.CommandGenerator">
<property name="name">"msofficeThumbnailGenerator"</property>
<property name="commandList">
["${path}/generate-thumbnail",
"msoffice",

View file

@ -197,7 +197,7 @@ $(function() {
});
IMG_LOADING_DELAY = 200;
IMG_LOADING_MAX = 5;
IMG_LOADING_MAX = 0;
var loadImage = function(img, url, limit) {
var imgData = new Image();
$(imgData).on("load", function() {