Skip to content

Commit

Permalink
add ServiceLoader for GroovyShellFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
baisui1981 committed May 28, 2024
1 parent 0c0acb8 commit e504d49
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
* <p>
* http:https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.qlangtech.tis.util.groovy;

import com.qlangtech.tis.extension.util.impl.DefaultGroovyShellFactory;
import com.qlangtech.tis.util.PluginItems;

/**
*
*/
public class ConsoleGroovyShellFactory extends DefaultGroovyShellFactory {

public ConsoleGroovyShellFactory() {
super(PluginItems.class.getClassLoader());
}

@Override
public boolean isInConsoleModule() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
##
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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:https://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.
#

com.qlangtech.tis.util.groovy.ConsoleGroovyShellFactory
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
* <p>
* http:https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.qlangtech.tis.util.groovy;

import com.qlangtech.tis.common.utils.Assert;
import com.qlangtech.tis.extension.util.GroovyShellFactory;
import com.qlangtech.tis.extension.util.GroovyShellUtil;
import junit.framework.TestCase;

public class TestConsoleGroovyShellFactory extends TestCase {

public void testGetInstance() {
GroovyShellFactory groovyShellFactory = GroovyShellUtil.getGroovyShellFactory();
Assert.assertEquals(true, groovyShellFactory.isInConsoleModule());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public Void process(Class<?> targetClass, Void v) {

if (StringUtils.isNotEmpty(help) && StringUtils.startsWith(help,
IMessageHandler.TSEARCH_PACKAGE)) {
props.put(PluginExtraProps.Props.KEY_HELP, GroovyShellUtil.eval(help));
props.put(PluginExtraProps.Props.KEY_HELP, GroovyShellEvaluate.eval(help));
}

if (dftVal != null && StringUtils.startsWith(String.valueOf(dftVal),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,16 @@ public DescriptorsJSON.IPropGetter getSubFormIdListGetter(IPropertyType.SubFormF
this.parentClazz.getSimpleName() + "_SubFormIdListGetter_" + subFormField.getName();
String pkg = this.parentClazz.getPackage().getName();
String script =
" package " + pkg + " ;" + "import java.util.Map;" + "import com.qlangtech" + ".tis" + ".coredefine.module.action.DataxAction; " + "import com.qlangtech.tis.util" + ".DescriptorsJSON.IPropGetter; " + "import com.qlangtech.tis.extension" + ".IPropertyType; " + "class " + className + " implements IPropGetter {" + " " + "@Override" + " public " + "Object build(IPropertyType.SubFormFilter filter)" + " " + "{" + this.getIdListGetScript() + " }" + "}";
" package " + pkg + " ;" //
+ "import java.util.Map;" //
+ "import com.qlangtech.tis.coredefine.module.action.DataxAction; " //
+ "import com.qlangtech.tis.util.DescriptorsJSON.IPropGetter; " //
+ "import com.qlangtech.tis.extension.IPropertyType; " //
+ "class " + className + " implements IPropGetter {" //
+ " " //
+ "@Override" //
+ " public Object build(IPropertyType.SubFormFilter filter)" + " " //
+ "{" + this.getIdListGetScript() + " }" + "}";
// //this.getIdListGetScript()
// loader.loadMyClass(className, script);
// Class<?> groovyClass = loader.loadClass(pkg + "." + className);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
* @author: 百岁([email protected]
* @create: 2024-01-12 10:02
**/
final class CustomerGroovyClassLoader extends GroovyClassLoader {
public CustomerGroovyClassLoader() {
super(new ClassLoader(GroovyShellEvaluate.class.getClassLoader()) {
public final class CustomerGroovyClassLoader extends GroovyClassLoader {
public CustomerGroovyClassLoader(ClassLoader parent) {
super(new ClassLoader(parent) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// return super.findClass(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

import com.qlangtech.tis.trigger.util.JsonUtil;
import com.qlangtech.tis.util.UploadPluginMeta;
import groovy.lang.Script;

import java.util.ServiceLoader;
import java.util.concurrent.Callable;
import java.util.function.Function;

Expand All @@ -38,20 +40,34 @@ public class GroovyShellEvaluate {
}
isInConsoleModule = loaded;
}
// private static GroovyShellEvaluateService getEvaluateService(){
//
// ServiceLoader<GroovyShellEvaluateService> evaluateServiceLoader = ServiceLoader.load(GroovyShellEvaluateService.class);
//
// for(GroovyShellEvaluateService eservie : evaluateServiceLoader){
// return eservie;
// }
// return new GroovyShellEvaluateService() {
// @Override
// public <T> T createParamizerScript(Class parentClazz, String className, String script) {
// return null;
// }
//
// @Override
// public Object scriptEval(String script, Function<Object, Object>... process) {
// return null;
// }
//
// @Override
// public <T> T eval(String javaScript) {
// return null;
// }
// };
// }

public static <T> T createParamizerScript(Class parentClazz, String className, String script) {
try {
// String className = parentClazz.getSimpleName() + "_SubFormIdListGetter_" + subFormField.getName();
String pkg = parentClazz.getPackage().getName();
// String script = " package " + pkg + " ;"
// + "import java.util.Map;"
// + "import com.qlangtech.tis.coredefine.module.action.DataxAction; "
// + "import com.qlangtech.tis.util.DescriptorsJSON.IPropGetter; "
// + "import com.qlangtech.tis.extension.IPropertyType; "
// + "class " + className + " implements IPropGetter {"
// + " @Override"
// + " public Object build(IPropertyType.SubFormFilter filter) {" + this.getIdListGetScript() + " }" + "}";
//this.getIdListGetScript()
GroovyShellUtil.loadMyClass(className, script);
Class<?> groovyClass = GroovyShellUtil.loadClass(pkg, className);
return (T) groovyClass.newInstance();
Expand All @@ -67,13 +83,13 @@ public static Object scriptEval(String script, Function<Object, Object>... proce

Callable<Object> valGetter = () -> {
for (Function<Object, Object> f : process) {
Object val = GroovyShellUtil.eval(meta.getName());
Object val = eval(meta.getName());
if (val == null) {
return null;
}
return f.apply(val);
}
return GroovyShellUtil.eval(meta.getName());
return eval(meta.getName());
};
return unCache ? new JsonUtil.UnCacheString(valGetter) : valGetter.call();
} catch (Exception e) {
Expand All @@ -82,15 +98,19 @@ public static Object scriptEval(String script, Function<Object, Object>... proce
}


// final static GroovyShell shell = new GroovyShell(new ClassLoader(GroovyShellEvaluate.class.getClassLoader()) {
// @Override
// protected Class<?> findClass(String name) throws ClassNotFoundException {
// // return super.findClass(name);
// return TIS.get().getPluginManager().uberClassLoader.findClass(name);
// }
// });

private GroovyShellEvaluate() {
}

public static <T> T eval(String javaScript) {
if (!GroovyShellUtil.getGroovyShellFactory().isInConsoleModule()) {
// 如果不在console中运行则返回空即可
return null;
}
try {
Script script = GroovyShellUtil.getScriptCache().get(javaScript);
return (T) script.run();
} catch (Throwable e) {
throw new RuntimeException(javaScript, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
* <p>
* http:https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.qlangtech.tis.extension.util;


import groovy.lang.GroovyShell;

/**
*
*/
public interface GroovyShellFactory {


CustomerGroovyClassLoader createGroovyLoader();

GroovyShell createGroovyShell();

boolean isInConsoleModule();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.qlangtech.tis.TIS;
import com.qlangtech.tis.extension.Describable;
import com.qlangtech.tis.extension.Descriptor;
import com.qlangtech.tis.extension.util.impl.DefaultGroovyShellFactory;
import groovy.lang.GroovyShell;
import groovy.lang.Script;

import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;

/**
Expand Down Expand Up @@ -55,7 +56,7 @@ public static void loadMyClass(String className, String script) {
}
}

private static LoadingCache<String, Script> getScriptCache() {
public static LoadingCache<String, Script> getScriptCache() {
if (scriptCache == null) {
synchronized (GroovyShellUtil.class) {
if (scriptCache == null) {
Expand All @@ -77,23 +78,40 @@ private static GroovyShell getGroovyShell() {
if (shell == null) {
synchronized (GroovyShellUtil.class) {
if (shell == null) {
shell = new GroovyShell(new ClassLoader(GroovyShellEvaluate.class.getClassLoader()) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return TIS.get().getPluginManager().uberClassLoader.findClass(name);
}
});
// shell = new GroovyShell(new ClassLoader(GroovyShellEvaluate.class.getClassLoader()) {
// @Override
// protected Class<?> findClass(String name) throws ClassNotFoundException {
// return TIS.get().getPluginManager().uberClassLoader.findClass(name);
// }
// });
shell = getGroovyShellFactory().createGroovyShell();
}
}
}
return shell;
}

private static GroovyShellFactory shellFactory;

public static GroovyShellFactory getGroovyShellFactory() {

if (shellFactory == null) {
ServiceLoader<GroovyShellFactory> shellFactoryLoader = ServiceLoader.load(GroovyShellFactory.class);
for (GroovyShellFactory f : shellFactoryLoader) {
return shellFactory = f;
}
return shellFactory = new DefaultGroovyShellFactory();
}


return shellFactory;
}

private static CustomerGroovyClassLoader getGroovyLoader() {
if (loader == null) {
synchronized (GroovyShellUtil.class) {
if (loader == null) {
loader = new CustomerGroovyClassLoader();
loader = getGroovyShellFactory().createGroovyLoader();
}
}
}
Expand All @@ -108,17 +126,4 @@ public static Class<?> loadClass(String pkg, String className) {
}
}

public static <T> T eval(String javaScript) {
if (!GroovyShellEvaluate.isInConsoleModule) {
// 如果不在console中运行则返回空即可
return null;
}
try {
Script script = getScriptCache().get(javaScript);
return (T) script.run();
} catch (Throwable e) {
throw new RuntimeException(javaScript, e);
}
}

}
Loading

0 comments on commit e504d49

Please sign in to comment.