fix #2561 add scripnt engine
This commit is contained in:
parent
9c82b32e96
commit
999097a7b0
18 changed files with 236 additions and 64 deletions
13
pom.xml
13
pom.xml
|
@ -1445,13 +1445,6 @@
|
|||
<version>4.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- groovy -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Tomcat -->
|
||||
<dependency>
|
||||
<groupId>org.dbflute.tomcat</groupId>
|
||||
|
@ -1532,5 +1525,11 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -469,4 +469,6 @@ public class Constants extends CoreLibConstants {
|
|||
public static final String EXECUTE_TYPE_PYTHON = "python";
|
||||
|
||||
public static final String EXECUTE_TYPE_SUGGEST = "suggest";
|
||||
|
||||
public static final String DEFAULT_SCRIPT = "groovy";
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.codelibs.fess.crawler.entity.UrlQueue;
|
|||
import org.codelibs.fess.crawler.util.CrawlingParameterUtil;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.GroovyUtil;
|
||||
|
||||
public interface FessTransformer {
|
||||
|
||||
|
@ -158,7 +157,7 @@ public interface FessTransformer {
|
|||
return StringUtil.EMPTY;
|
||||
}
|
||||
|
||||
return GroovyUtil.evaluate(template, paramMap);
|
||||
return ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(template, paramMap);
|
||||
}
|
||||
|
||||
default int getMaxSiteLength() {
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.codelibs.fess.helper.CrawlingInfoHelper;
|
|||
import org.codelibs.fess.helper.SystemHelper;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.GroovyUtil;
|
||||
|
||||
public abstract class AbstractDataStore implements DataStore {
|
||||
|
||||
|
@ -130,7 +129,7 @@ public abstract class AbstractDataStore implements DataStore {
|
|||
return paramMap.get(template);
|
||||
}
|
||||
|
||||
return GroovyUtil.evaluate(template, paramMap);
|
||||
return ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(template, paramMap);
|
||||
}
|
||||
|
||||
protected long getReadInterval(final Map<String, String> paramMap) {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2012-2021 CodeLibs Project and the Others.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.codelibs.fess.exception;
|
||||
|
||||
public class ScriptEngineException extends FessSystemException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ScriptEngineException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ScriptEngineException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ import org.codelibs.fess.es.config.exbhv.PathMappingBhv;
|
|||
import org.codelibs.fess.es.config.exentity.PathMapping;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.codelibs.fess.util.DocumentUtil;
|
||||
import org.codelibs.fess.util.GroovyUtil;
|
||||
import org.lastaflute.di.core.exception.ComponentNotFoundException;
|
||||
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
|
@ -164,7 +163,8 @@ public class PathMappingHelper {
|
|||
final Map<String, Object> paramMap = new HashMap<>();
|
||||
paramMap.put("url", u);
|
||||
paramMap.put("matcher", m);
|
||||
final Object value = GroovyUtil.evaluate(template, paramMap);
|
||||
final Object value =
|
||||
ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(template, paramMap);
|
||||
if (value == null) {
|
||||
return u;
|
||||
}
|
||||
|
|
|
@ -374,7 +374,7 @@ public class PluginHelper {
|
|||
}
|
||||
|
||||
public enum ArtifactType {
|
||||
DATA_STORE("fess-ds"), THEME("fess-theme"), INGEST("fess-ingest"), UNKNOWN("jar");
|
||||
DATA_STORE("fess-ds"), THEME("fess-theme"), INGEST("fess-ingest"), SCRIPT("fess-script"), WEBAPP("fess-webapp"), UNKNOWN("jar");
|
||||
|
||||
private final String id;
|
||||
|
||||
|
@ -396,6 +396,12 @@ public class PluginHelper {
|
|||
if (name.startsWith(INGEST.getId())) {
|
||||
return INGEST;
|
||||
}
|
||||
if (name.startsWith(SCRIPT.getId())) {
|
||||
return SCRIPT;
|
||||
}
|
||||
if (name.startsWith(WEBAPP.getId())) {
|
||||
return WEBAPP;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,9 @@ package org.codelibs.fess.indexer;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.es.config.exentity.BoostDocumentRule;
|
||||
import org.codelibs.fess.util.GroovyUtil;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
|
||||
public class DocBoostMatcher {
|
||||
|
||||
|
@ -41,7 +42,8 @@ public class DocBoostMatcher {
|
|||
return false;
|
||||
}
|
||||
|
||||
final Object value = GroovyUtil.evaluate(matchExpression, map);
|
||||
final Object value =
|
||||
ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(matchExpression, map);
|
||||
if (value instanceof Boolean) {
|
||||
return ((Boolean) value);
|
||||
}
|
||||
|
@ -54,7 +56,8 @@ public class DocBoostMatcher {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
final Object value = GroovyUtil.evaluate(boostExpression, map);
|
||||
final Object value =
|
||||
ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(boostExpression, map);
|
||||
if (value instanceof Integer) {
|
||||
return ((Integer) value).floatValue();
|
||||
}
|
||||
|
|
|
@ -18,8 +18,9 @@ package org.codelibs.fess.job.impl;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.job.JobExecutor;
|
||||
import org.codelibs.fess.util.GroovyUtil;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
|
||||
public class GroovyExecutor extends JobExecutor {
|
||||
|
||||
|
@ -28,7 +29,7 @@ public class GroovyExecutor extends JobExecutor {
|
|||
final Map<String, Object> params = new HashMap<>();
|
||||
params.put("executor", this);
|
||||
|
||||
return GroovyUtil.evaluate(script, params);
|
||||
return ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(script, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2012-2021 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.script;
|
||||
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
|
||||
public abstract class AbstractScriptEngine implements ScriptEngine {
|
||||
|
||||
public void register() {
|
||||
ComponentUtil.getScriptEngineFactory().add(getName(), this);
|
||||
}
|
||||
|
||||
protected abstract String getName();
|
||||
}
|
|
@ -13,21 +13,10 @@
|
|||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.codelibs.fess.util;
|
||||
package org.codelibs.fess.script;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.fess.unit.UnitFessTestCase;
|
||||
|
||||
public class GroovyUtilTest extends UnitFessTestCase {
|
||||
public void test_evaluate() {
|
||||
final Map<String, Object> params = new HashMap<>();
|
||||
assertNull(GroovyUtil.evaluate("", params));
|
||||
assertEquals("", GroovyUtil.evaluate("return ''", params));
|
||||
assertEquals(1, GroovyUtil.evaluate("return 1", params));
|
||||
|
||||
params.put("test", "123");
|
||||
assertEquals("123", GroovyUtil.evaluate("return test", params));
|
||||
}
|
||||
public interface ScriptEngine {
|
||||
Object evaluate(final String template, final Map<String, Object> paramMap);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2012-2021 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.script;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.codelibs.fess.exception.ScriptEngineException;
|
||||
|
||||
public class ScriptEngineFactory {
|
||||
private static final Logger logger = LogManager.getLogger(ScriptEngineFactory.class);
|
||||
|
||||
protected Map<String, ScriptEngine> scriptEngineMap = new LinkedHashMap<>();
|
||||
|
||||
public void add(final String name, final ScriptEngine scriptEngine) {
|
||||
if (name == null || scriptEngine == null) {
|
||||
throw new IllegalArgumentException("name or scriptEngine is null.");
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loaded {}", name);
|
||||
}
|
||||
scriptEngineMap.put(name.toLowerCase(Locale.ROOT), scriptEngine);
|
||||
scriptEngineMap.put(scriptEngine.getClass().getSimpleName().toLowerCase(Locale.ROOT), scriptEngine);
|
||||
}
|
||||
|
||||
public ScriptEngine getScriptEngine(final String name) {
|
||||
if (name == null) {
|
||||
throw new ScriptEngineException("script name is null.");
|
||||
}
|
||||
final ScriptEngine scriptEngine = scriptEngineMap.get(name.toLowerCase(Locale.ROOT));
|
||||
if (scriptEngine != null) {
|
||||
return scriptEngine;
|
||||
}
|
||||
throw new ScriptEngineException(name + " is not found.");
|
||||
}
|
||||
}
|
|
@ -77,6 +77,7 @@ import org.codelibs.fess.job.JobExecutor;
|
|||
import org.codelibs.fess.ldap.LdapManager;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.mylasta.direction.FessProp;
|
||||
import org.codelibs.fess.script.ScriptEngineFactory;
|
||||
import org.codelibs.fess.sso.SsoManager;
|
||||
import org.codelibs.fess.thumbnail.ThumbnailManager;
|
||||
import org.lastaflute.core.message.MessageManager;
|
||||
|
@ -95,6 +96,8 @@ public final class ComponentUtil {
|
|||
|
||||
private static Map<String, Object> componentMap = new HashMap<>();
|
||||
|
||||
private static final String SCRIPT_ENGINE_FACTORY = "scriptEngineFactory";
|
||||
|
||||
private static final String INGEST_FACTORY = "ingestFactory";
|
||||
|
||||
private static final String NOTIFICATION_HELPER = "notificationHelper";
|
||||
|
@ -481,6 +484,10 @@ public final class ComponentUtil {
|
|||
return getComponent(INGEST_FACTORY);
|
||||
}
|
||||
|
||||
public static ScriptEngineFactory getScriptEngineFactory() {
|
||||
return getComponent(SCRIPT_ENGINE_FACTORY);
|
||||
}
|
||||
|
||||
public static <T> T getComponent(final Class<T> clazz) {
|
||||
try {
|
||||
return SingletonLaContainer.getComponent(clazz);
|
||||
|
|
|
@ -15,46 +15,18 @@
|
|||
*/
|
||||
package org.codelibs.fess.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.codelibs.fess.exception.JobProcessingException;
|
||||
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
|
||||
|
||||
import groovy.lang.Binding;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import groovy.lang.GroovyShell;
|
||||
import org.codelibs.fess.Constants;
|
||||
|
||||
@Deprecated
|
||||
public final class GroovyUtil {
|
||||
private static final Logger logger = LogManager.getLogger(GroovyUtil.class);
|
||||
|
||||
private GroovyUtil() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
public static Object evaluate(final String template, final Map<String, Object> paramMap) {
|
||||
final Map<String, Object> bindingMap = new HashMap<>(paramMap);
|
||||
bindingMap.put("container", SingletonLaContainerFactory.getContainer());
|
||||
final GroovyShell groovyShell = new GroovyShell(new Binding(bindingMap));
|
||||
try {
|
||||
return groovyShell.evaluate(template);
|
||||
} catch (final JobProcessingException e) {
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
logger.warn("Failed to evalue groovy script: {} => {}", template, paramMap, e);
|
||||
return null;
|
||||
} finally {
|
||||
final GroovyClassLoader loader = groovyShell.getClassLoader();
|
||||
// StreamUtil.of(loader.getLoadedClasses()).forEach(c -> {
|
||||
// try {
|
||||
// GroovySystem.getMetaClassRegistry().removeMetaClass(c);
|
||||
// } catch (Throwable t) {
|
||||
// logger.warn("Failed to delete " + c, t);
|
||||
// }
|
||||
// });
|
||||
loader.clearCache();
|
||||
}
|
||||
return ComponentUtil.getScriptEngineFactory().getScriptEngine(Constants.DEFAULT_SCRIPT).evaluate(template, paramMap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<components>
|
||||
<include path="fess_config.xml"/>
|
||||
<include path="fess_ds.xml"/>
|
||||
<include path="fess_se.xml"/>
|
||||
<include path="esflute_config.xml"/>
|
||||
<include path="esflute_user.xml"/>
|
||||
<include path="esflute_log.xml"/>
|
||||
|
|
7
src/main/resources/fess_se.xml
Normal file
7
src/main/resources/fess_se.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE components PUBLIC "-//DBFLUTE//DTD LastaDi 1.0//EN"
|
||||
"http://dbflute.org/meta/lastadi10.dtd">
|
||||
<components>
|
||||
<component name="scriptEngineFactory" class="org.codelibs.fess.script.ScriptEngineFactory">
|
||||
</component>
|
||||
</components>
|
|
@ -18,9 +18,19 @@ package org.codelibs.fess.ds;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.ds.callback.IndexUpdateCallback;
|
||||
import org.codelibs.fess.es.config.exentity.DataConfig;
|
||||
import org.codelibs.fess.exception.JobProcessingException;
|
||||
import org.codelibs.fess.script.AbstractScriptEngine;
|
||||
import org.codelibs.fess.script.ScriptEngineFactory;
|
||||
import org.codelibs.fess.unit.UnitFessTestCase;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
|
||||
|
||||
import groovy.lang.Binding;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import groovy.lang.GroovyShell;
|
||||
|
||||
public class AbstractDataStoreTest extends UnitFessTestCase {
|
||||
public AbstractDataStore dataStore;
|
||||
|
@ -40,6 +50,33 @@ public class AbstractDataStoreTest extends UnitFessTestCase {
|
|||
// TODO nothing
|
||||
}
|
||||
};
|
||||
|
||||
ScriptEngineFactory scriptEngineFactory = new ScriptEngineFactory();
|
||||
ComponentUtil.register(scriptEngineFactory, "scriptEngineFactory");
|
||||
new AbstractScriptEngine() {
|
||||
|
||||
@Override
|
||||
public Object evaluate(String template, Map<String, Object> paramMap) {
|
||||
final Map<String, Object> bindingMap = new HashMap<>(paramMap);
|
||||
bindingMap.put("container", SingletonLaContainerFactory.getContainer());
|
||||
final GroovyShell groovyShell = new GroovyShell(new Binding(bindingMap));
|
||||
try {
|
||||
return groovyShell.evaluate(template);
|
||||
} catch (final JobProcessingException e) {
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
} finally {
|
||||
final GroovyClassLoader loader = groovyShell.getClassLoader();
|
||||
loader.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return Constants.DEFAULT_SCRIPT;
|
||||
}
|
||||
}.register();
|
||||
}
|
||||
|
||||
public void test_convertValue() {
|
||||
|
|
|
@ -18,9 +18,51 @@ package org.codelibs.fess.indexer;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.fess.Constants;
|
||||
import org.codelibs.fess.exception.JobProcessingException;
|
||||
import org.codelibs.fess.script.AbstractScriptEngine;
|
||||
import org.codelibs.fess.script.ScriptEngineFactory;
|
||||
import org.codelibs.fess.unit.UnitFessTestCase;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
|
||||
|
||||
import groovy.lang.Binding;
|
||||
import groovy.lang.GroovyClassLoader;
|
||||
import groovy.lang.GroovyShell;
|
||||
|
||||
public class DocBoostMatcherTest extends UnitFessTestCase {
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
ScriptEngineFactory scriptEngineFactory = new ScriptEngineFactory();
|
||||
ComponentUtil.register(scriptEngineFactory, "scriptEngineFactory");
|
||||
new AbstractScriptEngine() {
|
||||
|
||||
@Override
|
||||
public Object evaluate(String template, Map<String, Object> paramMap) {
|
||||
final Map<String, Object> bindingMap = new HashMap<>(paramMap);
|
||||
bindingMap.put("container", SingletonLaContainerFactory.getContainer());
|
||||
final GroovyShell groovyShell = new GroovyShell(new Binding(bindingMap));
|
||||
try {
|
||||
return groovyShell.evaluate(template);
|
||||
} catch (final JobProcessingException e) {
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
} finally {
|
||||
final GroovyClassLoader loader = groovyShell.getClassLoader();
|
||||
loader.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return Constants.DEFAULT_SCRIPT;
|
||||
}
|
||||
}.register();
|
||||
}
|
||||
|
||||
public void test_integer() {
|
||||
final DocBoostMatcher docBoostMatcher = new DocBoostMatcher();
|
||||
docBoostMatcher.setBoostExpression("10");
|
||||
|
|
Loading…
Add table
Reference in a new issue