Joget DX 8 Stable Released
The stable release for Joget DX 8 is now available, with a focus on UX and Governance.
在本教程中, 我们将会遵循 guideline for developing a plugin 来开发我们的 Bean Shell Hash Variable 插件.
哈希变量使用起来很方便,但有时我们想在显示一个值之前做一些条件检查。但是,哈希变量不提供条件检查的能力。
通过查看 Joget Workflow目前支持的 插件类型,我们可以开发一个 哈希变量插件,让我们编写脚本来检查条件。有相当多的Bean Shell插件作为几种插件类型的默认插件提供。我们也可以为哈希变量插件做一个。
哈希变量插件不提供用户配置界面,但要开发一个Bean Shell哈希变量插件,我们需要在某处放置我们的Bean Shell脚本。我们可以重新使用 环境变量 来存储我们的脚本。所以哈希变量语法将是一个环境变量键的前缀。
E.g. #beanshell.EnvironmentVariableKey#
但是,这可能还不够,我们可能还需要一些其他方法来传递一些变量。我们可以考虑使用一个URL查询参数语法来传递我们的变量,因为以后可以更容易解析。
E.g. #beanshell.EnvironmentVariableKey[name=Joget&email=info@joget.org&message={form.sample.message?url}]#
我们期望从这个Bean Shell Hash变量插件中得到什么?Bean Shell Hash变量插件适用于管理员/开发人员用户在构建/开发应用程序时使用。一旦使用,哈希变量将被来自Bean Shell解释器的输出返回替换。以便管理员用户在向普通用户显示内容之前可以进行条件检查。
例如,显示登录用户的欢迎消息,但在用户为匿名时不显示任何内容。
要开发Bean Shell Hash变量插件,我们可以参考 所有的Hash变量插件和Bean Shell插件的 源代码。尤其是,我们可以参考环境变量哈希变量插件如何使用变量键来检索环境变量。我们也可以参考Bean Shell Tool或者Bean Shell Form Binder插件来说明如何使用Bean Shell解释器来执行脚本。
我们可以使用StringUtil中的 getUrlParams方法 来帮助我们解析使用URL查询参数语法传入的参数。
我们需要始终准备好Joget Workflow Source Code,并按照这个指导方针建立起来。
以下教程是使用Macbook Pro和Joget源代码5.0.0版编写的。 其他平台命令请参阅 如何开发插件文章。
假设我们的文件夹目录如下所示。
- Home - joget - plugins - jw-community -5.0.0
“plugins”目录是我们要创建和存储我们所有插件的文件夹,“jw-community”目录是Joget Workflow源代码存储的地方。
运行以下命令在“plugins”目录下创建一个maven项目。
cd joget/plugins/ ~/joget/jw-community/5.0.0/wflow-plugin-archetype/create-plugin.sh org.joget.tutorial beanshell_hash_variable 5.0.0
然后,shell脚本会要求我们输入插件的版本号,并在生成maven项目之前要求我们确认。
Define value for property 'version': 1.0-SNAPSHOT: : 5.0.0 [INFO] Using property: package = org.joget.tutorial Confirm properties configuration: groupId: org.joget.tutorial artifactId: beanshell_hash_variable version: 5.0.0 package: org.joget.tutorial Y: : y
我们应该在终端上显示“BUILD SUCCESS”消息,在“plugins”文件夹中创建一个“beanshell_hash_variable”文件夹。
用你喜欢的IDE打开maven项目。我将使用 NetBeans。
在“org.joget.tutorial”包下创建一个“BeanShellHashVariable”类。
然后,基于 哈希变量插件文件,我们将不得不扩展 org.joget.apps.app.model.DefaultHashVariablePlugin抽象类。
让我们实现所有的抽象方法。我们将使用AppPluginUtil.getMessage方法来支持i18n,并将常量变量MESSAGE_PATH用于消息资源包目录。
现在,我们来关注我们的Hash变量插件的主要方法,它是processHashVariable。我们将参考环境变量哈希变量插件的源代码来了解如何检索环境变量。然后,参考Bean Shell Form Binder的源代码,了解如何执行一个bean shell脚本。
public String processHashVariable(String variableKey) { try { String environmentVariableKey = variableKey; //first check and retrieve parameters passed in with URL query parameters syntax wrapped in square bracket [] String queryParams = null; if (variableKey.contains("[") && variableKey.contains("]")) { queryParams = variableKey.substring(variableKey.indexOf("[") + 1, variableKey.indexOf("]")); environmentVariableKey = variableKey.substring(0, variableKey.indexOf("[")); } //Parse the query parameters to a map Map<String, String[]> parameters = null; if (queryParams != null && !queryParams.isEmpty()) { parameters = StringUtil.getUrlParams(queryParams); //put all parameters to plugin properties getProperties().putAll(parameters); } //Retrieve the environment variable based on environmentVariableKey AppDefinition appDef = (AppDefinition) getProperty("appDefinition"); if (appDef != null) { ApplicationContext appContext = AppUtil.getApplicationContext(); EnvironmentVariableDao environmentVariableDao = (EnvironmentVariableDao) appContext.getBean("environmentVariableDao"); EnvironmentVariable env = environmentVariableDao.loadById(environmentVariableKey, appDef); if (env != null) { String script = env.getValue(); //execute the script with all plugin properties return executeScript(script, getProperties()); } else { //environment variable not found, return empty value return ""; } } } catch (Exception e) { //log the exception using LogUtil LogUtil.error(getClassName(), e, "#beanshell."+variableKey+"# fail to parse."); } //return null to by pass the replacing return null; } protected String executeScript(String script, Map properties) throws Exception { Interpreter interpreter = new Interpreter(); interpreter.setClassLoader(getClass().getClassLoader()); for (Object key : properties.keySet()) { interpreter.set(key.toString(), properties.get(key)); } LogUtil.debug(getClass().getName(), "Executing script " + script); return (String) interpreter.eval(script); }
我们的插件类无法解析“bsh.Interpreter”。所以,我们必须将bean shell库添加到我们的POM文件中。
<!-- Change plugin specific dependencies here --> <dependency> <groupId>org.beanshell</groupId> <artifactId>bsh</artifactId> <version>2.0b4</version> </dependency> <!-- End change plugin specific dependencies here -->
我们使用AppPluginUtil.getMessage方法来显示我们的getLabel和getDescription方法的i18n值。我们将不得不为它创建一个消息资源包属性文件。在“beanshell_hash_variable / src / main”目录下创建目录“resources / messages”。然后,在该文件夹中创建一个“BeanShellHashVariable.properties”文件。
在我们的属性文件中,我们将需要添加我们已经使用的密钥。
org.joget.tutorial.BeanShellHashVariable.pluginLabel=Bean Shell Hash Variable org.joget.tutorial.BeanShellHashVariable.pluginDesc=Using environment variable to execute bean shell script.
我们将不得不在Activator类中注册我们的插件类,告诉Felix框架这是一个插件。
public void start(BundleContext context) { registrationList = new ArrayList<ServiceRegistration>(); //Register plugin here registrationList.add(context.registerService(BeanShellHashVariable.class.getName(), new BeanShellHashVariable(), null)); }
让我们建立我们的插件。构建过程完成后,我们将发现在“beanshell_hash_variable / target”目录下创建了“beanshell_hash_variable-5.0.0.jar”文件
然后,让我们上传插件jar到 管理插件。上传jar文件后,再次检查插件是否正确上传并激活。
现在,让我们测试我们的插件。
假设我们在一个用户视图中有一个HTML菜单页面,它想把下面的行显示给登录用户。通常,我们将使用“欢迎#currentUser,用户名#”来显示欢迎消息。
但是,在这个用例中存在一个问题,当用户是匿名用户时,显示“Welcome”,没有用户名。
现在,将整个消息更改为我们的Bean Shell哈希变量,并创建一个环境变量来放置我们的脚本。
更改:
Welcome #currentUser.username#,
以下。我们将需要传递当前用户的用户名作为我们的参数之一,不要忘记把它作为url转义。
#beanshell.welcome[username={currentUser.username?url}]?html#
然后,我们可以创建一个ID为“welcome”的环境变量,并使用下面的脚本。由于我们使用StringUtil的 getUrlParams方法 来解析参数,所以参数中的所有值都是String数组。
//all parameters passed in from Beanshell Hash Variable will converted to String array if (username != null && username.length == 1 && !username[0].isEmpty()) { return "Welcome " + username[0] + ","; } else { return ""; }
让我们回到我们的HTML菜单页面来查看结果。
当用户登录时,它显示正确的消息。
当没有用户登录时,欢迎消息不显示。
您可以从beanshell_hash_variable.zip下载源代码。
要下载现成的插件jar,请在http://marketplace.joget.org/上找到它