【ProM编程3】如何创建一个复杂的Plug-in

2023-11-09 19:59
文章标签 创建 编程 复杂 plug prom

本文主要是介绍【ProM编程3】如何创建一个复杂的Plug-in,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本节在前两节的基础上,介绍如何创建一个复杂的Plug-in。

目录

1.本节介绍

2.基于非静态方法的插件

3.重载插件

3.1  可配置的输入

 3.2 多类型输入

4.总结


1.本节介绍

        到目前为止,本文介绍了简单的插件,其中所有的计算都是通过静态方法执行的。在本节中,我们将介绍两种更复杂的插件类型,即基于非静态方法的插件和重载插件

2.基于非静态方法的插件

        与基于静态方法的插件类似,您可以基于非静态方法定义插件。考虑以下代码, 这与早期的helloWorld示例非常相似,但现在helloworld方法不是静态的.

package org.processmining.plugins.gettingstarted;import org.processmining.contexts.uitopia.annotations.UITopiaVariant;
import org.processmining.framework.plugin.PluginContext;
import org.processmining.framework.plugin.annotations.Plugin;public class HelloWorld9 {@Plugin(name = "My 5th Hello World Plug-in", parameterLabels = {}, returnLabels = { "Hello world string" }, returnTypes = { String.class }, userAccessible = true, help = "Produces the string: 'Hello world'")@UITopiaVariant(affiliation = "My company", author = "My name", email = "My e-mail address")public String helloWorld(PluginContext context) {return "Hello World";}
}

        在ProM中使用此插件时,您会发现与静态版本在行为上没有任何区别。然而,存在一个重要的概念差异。如果用@Plugin注释注释的方法不是静态的,就像这里的情况一样,那么当被要求执行这个插件时,框架将调用该方法,就像在框架中的某个地方调用了以下代码一样:

HelloWorld9 hw9 = new HelloWorld9();
hw9.helloWorld(context);

        这里,首先创建类HelloWorld9的一个实例,并为此实例调用方法helloWorld。这意味着在方法主体中,类的所有私有成员都是可访问和实例化的。请注意,使用非静态方法作为插件需要存在默认构造函数,即不带参数的构造函数

3.重载插件

        到目前为止引入的基于方法的插件允许定义已知输入类型的插件。然而,在实践中,许多插件允许应用于多种类型的输入。例如,考虑一个构建Petri网可达性图的插件。这样的插件接受Petri网【a plug-in accepts Petri nets】,但也接受重置网(具有重置弧的Petri网)【Reset nets (Petri nets with reset arcs)】、约束网(具有约束弧的Petri网)【Inhibitor nets (Petri nets with inhibitor arcs)】和重置/约束网【Reset/Inhibitor nets】。

         此外,有时插件只需要m个参数中的n个。例如,考虑使用一个插件来打开一个文件。它的输入是文件名(可以是String、URI、File或FileInputStream类型)。然而,这个插件也可以在没有输入的情况下执行,在这种情况下,会向用户显示一个对话框,以提供指向要打开的文件的指针。但是请注意,只有在GUI中执行插件时,才能显示这样的对话框。

        过载的插件允许上面提到的场景。在本节中,我们将介绍带有变体的插件的概念,这就是这些场景的实现方式。在显示具有多种类型的参数之前,我们首先介绍了可选参数的概念。

3.1  可配置的输入

考虑以下代码:

package org.processmining.plugins.gettingstarted;import javax.swing.JOptionPane;import org.processmining.contexts.uitopia.UIPluginContext;
import org.processmining.contexts.uitopia.annotations.UITopiaVariant;
import org.processmining.framework.plugin.PluginContext;
import org.processmining.framework.plugin.annotations.Plugin;
import org.processmining.framework.plugin.annotations.PluginVariant;@Plugin(name = "My Overloaded Hello World Plugin", parameterLabels = { "First string", "Number", "Second string" }, returnLabels = { "Hello world string" }, returnTypes = { String.class }, userAccessible = true, help = "The plugin produces 'hello' concatenated with at least one world. If no world is given, it is requested from the user, provided that a GUI exists."
)
public class HelloWorld10 {private String getWorld(UIPluginContext context) {// Ask the user for his worldString w = JOptionPane.showInputDialog(null, "What's the name of your world?","Enter your world", JOptionPane.QUESTION_MESSAGE);// change your result labelcontext.getFutureResult(0).setLabel("Hello " + w + " string");return w;}@PluginVariant(variantLabel = "My original hello world", requiredParameterLabels = {})@UITopiaVariant(uiLabel = "My original hello world", affiliation = "My company", author = "My name", email = "My e-mail address")public String helloWorld(PluginContext context) {return "Hello World";}@PluginVariant(variantLabel = "My Hello unknown", requiredParameterLabels = {})@UITopiaVariant(uiLabel = "My Hello unknown", affiliation = "My company", author = "My name", email = "My e-mail address")public String helloUnknown(UIPluginContext context) {return "Hello " + getWorld(context);}@PluginVariant(variantLabel = "My Combine worlds", requiredParameterLabels = { 0, 1, 2 })@UITopiaVariant(uiLabel = "My Combine worlds", affiliation = "My company", author = "My name", email = "My e-mail address")public Object helloWorlds(PluginContext context, String first, Integer number, String second) {String s = first;for (int i = 0; i < number; i++) {s += "," + second;}return s;}@PluginVariant(variantLabel = "My Combine unknowns", requiredParameterLabels = { 0, 1 })@UITopiaVariant(uiLabel = "My Combine unknowns", affiliation = "My company", author = "My name", email = "My e-mail address")public Object helloWorlds(UIPluginContext context, String first, Integer number) {// return the combined string, after asking for the worldreturn helloWorlds(context, first, number, getWorld(context));}
}

        在本例中,@Plugin注释不再用于方法,而是用于类。这向框架发出信号,表明这是一个重载的插件,由几个变体组成。这意味着应该至少有一个方法带有@PluginVariant注释。在这种情况下有四个。
        这个类的@Plugin注释与我们之前使用过的方法相同。因此,这里必须指定参数的标签,以及所有变体的返回类型。因此,所有变体都必须返回相同类型的对象,即在本例中它们都应该返回一个String。复杂的返回类型是允许的,只要它们对于所有变体都是相同的。
        此示例代码提供的插件的四个变体由一个标签和该变体所需参数的列表定义。此外,它们需要执行不同的上下文。在下表中,对四种变体进行了简要概述:

 3.2 多类型输入

        在前面的例子中,插件变体都使用了相同类型的参数的不同组合,即“Combine”未知变量需要标记为“First string”和“Number”的参数,在方法定义中,这两个参数的类型分别为“string”和“Integer”。然而,这并不是框架强加的要求,如以下代码所示:

package org.processmining.plugins.gettingstarted;import javax.swing.JOptionPane;import org.processmining.contexts.uitopia.UIPluginContext;
import org.processmining.contexts.uitopia.annotations.UITopiaVariant;
import org.processmining.framework.plugin.PluginContext;
import org.processmining.framework.plugin.annotations.Plugin;
import org.processmining.framework.plugin.annotations.PluginVariant;@Plugin(name = "My Overloaded Hello Many Worlds", parameterLabels = { "First string", "Large Number", "Second string" }, returnLabels = { "Hello world string" }, returnTypes = { String.class }, userAccessible = true, help = "The plugin produces 'hello' concatenated with at least one world. If no world is given, it is requested from the user, provided that a GUI exists."
)
public class HelloWorld11 {private String getWorld(UIPluginContext context) {// Ask the user for his worldString w = JOptionPane.showInputDialog(null, "What's the name of your world?","Enter your world", JOptionPane.QUESTION_MESSAGE);// change your result labelcontext.getFutureResult(0).setLabel("Hello " + w + " string");return w;}@PluginVariant(variantLabel = "My Combine many worlds", requiredParameterLabels = { 0, 1, 2 })@UITopiaVariant(uiLabel = "My Combine many worlds", affiliation = "My company", author = "My name", email = "My e-mail address")public Object helloWorlds(PluginContext context, String first, Long number, String second) {String s = first;for (int i = 0; i < number; i++) {s += "," + second;}return s;}@PluginVariant(variantLabel = "My Combine few unknowns", requiredParameterLabels = { 0, 1 })@UITopiaVariant(uiLabel = "My Combine few unknowns", affiliation = "My company", author = "My name", email = "My e-mail address")public Object helloWorlds(UIPluginContext context, String first, Integer number) {// return the combined string, after asking for the worldreturn helloWorlds(context, first, Long.valueOf(number), getWorld(context));}@PluginVariant(variantLabel = "My Combine many unknowns", requiredParameterLabels = { 0, 1 })@UITopiaVariant(uiLabel = "My Combine many unknowns", affiliation = "My company", author = "My name", email = "My e-mail address")public Object helloWorlds(UIPluginContext context, String first, Long number) {// return the combined string, after asking for the worldreturn helloWorlds(context, first, number, getWorld(context));}
}

4.总结

        通过使用插件变体,可以定义复杂的插件来处理不同类型的参数。然而,有几点需要记住:
(1) 如果在确定上下文中不能执行任何变体,则该插件被框架忽略,
(2) 用@PluginVariant注释注释的插件变体的方法必须全部返回类的@Plugin注释中指定类型的对象。在执行插件之前,框架不会检查这一点,在这种情况下,如果返回类型不匹配,就会抛出异常。
(3) 插件变体既可以是静态的,也可以是非静态的
(4) 使用过多的插件变体可能会令人困惑(但有时是必要的)。通常,如果存在许多变体,那么将实际逻辑的实现推迟到(a)私有方法,并保持用@PluginVariant注释注释的方法代码尽可能干净,这是一种很好的编程实践。
(5) 插件变体可以在超类中定义,也就是说,可以定义一个包含许多变体的抽象类,这些变体都调用一个抽象保护方法,该方法在子类中实现。然而,@Plugin注释应该只在子类级别上使用,否则超类和子类都被视为插件。作为这种构造的一个例子,我们指的是以下各项的组合:
        org.processmining.plugins.abstractplugins.AbstractImportPlugin,它定义了打开由不同对象指定的文件的变体,但本身不是一个插件,以及
        org.processmining.plugins.etrinet.tpn.TpnImport,它实现了AbstractImportPlugin的抽象方法,并定义了@Plugin注释。
(6) 用@PluginVariant注释注释的类的方法也可以用@Plugin注释注释。在这种情况下,这些方法被框架视为单独的插件。然而,这种构造是不鼓励的,因为它会导致复杂的代码。
(7) @PluginVariant注释由子类继承。因此,任何用@Plugin注释注释的类都可以由另一个用@Plugine注释的类扩展。超类的变体也存在于子类中。这要求继承关系中的任何两个插件的结果类型都相同。同样,只有在执行了插件之后才会检查这一点。

这篇关于【ProM编程3】如何创建一个复杂的Plug-in的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/378210

相关文章

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择

java poi实现Excel多级表头导出方式(多级表头,复杂表头)

《javapoi实现Excel多级表头导出方式(多级表头,复杂表头)》文章介绍了使用javapoi库实现Excel多级表头导出的方法,通过主代码、合并单元格、设置表头单元格宽度、填充数据、web下载... 目录Java poi实现Excel多级表头导出(多级表头,复杂表头)上代码1.主代码2.合并单元格3.

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow