[转载]在 IBM Rational Software Architect 中使用 Pluglet

在 IBM Rational Software Architect 中使用 Pluglet


2007 年 6 月 11 日

这篇文章介绍了 IBM Rational Software Architect 6.0 版本里包含的 pluglet 特性,向您展示了如何启用 pluglet ,并建议您在哪里使用 Pluglet 会更加有帮助。这篇文章是基于 Rational Software Architect 6.0.1 编写的,其目标读者是具有使用 Rational Software Architect 或 Eclipse for Java™ 进行开发经验的人。而文章中的某些部分还需要具有 Eclipse 插件开发方面的知识。

引言

IBM® Rational® Software Architect 中的 Pluglet 可能是您曾经忽略的一个特性。这个概念本身十分简单,然而当使用 Rational Software Architect 时,它是众多概念里一个可以提供很多有用工具的特性。这篇文章将描述 pluglet、它的用途以及使用方面的技巧。我们希望这将提高您对这一特性的认识并帮助您开始使用这一特性。

pluglet 是一个拥有主入口点的Java™类。它可以在R ational Software Architect 里像一个标准的 Java 类那样执行,可以访问所有标准的 Java API(应用程序编程接口)。与众不同的是 pluglet 可以访问 Eclipse Plug-in API ,因此通过运行时平台可以不用编写和测试插件程序就能够与 Rational Software Architect 里的资源进行交互。这使得 Rational Software Architect 能够尽可能更快地运行。使用 pluglet 您可以:

  • 在不需要编写插件程序并启动运行时平台的情况下,就可以测试和了解 Rational Software Architect API。
  • 使用 Java 编写简单的宏或脚本来扩展 Rational Software Architect 的功能
  • 编写交互和控制 Rational Software Architect 外部系统的宏或脚本(只要您有提供适当 API 的插件程序),或者使这些外部系统与 Rational Software Architect 及其工具进行无缝交互。
  • 在运行时平台上测试插件程序,而不是编写另一个单元测试插件程序。

可用的 pluglet 信息

Rational Software Architect 在各个地方都有关于 pluglet 的信息。Do and Learn部分下的 Tutorials Gallery 里有一个指南,教您如何创建第一个 pluglet。

Samples Gallery有几个 pluglet 的例子。如果您使用 Pluglet 向导来创建新的 Pluglet,您也可以从这个向导的样本里选择。这些样本教您如何来做:

  • 模型询问
  • 编辑器扩展

安 装这些样本以熟悉它们是很值得的。这篇文章不会对 Rational Software Architect 或 Eclipse API 代码编写进行细节探讨(尽管可能使用它们展示例子),但是会将重点放在编写 pluglet 常用的输入和输出上。更多的帮助和信息可以在 Help 内容中找到 (选择Help > Extending Rational Software Architect functionality > Extending your Java environment with pluglets).

为了生成 JavaDoc 以显示创建一个 pluglet 您可以使用哪些 API,遵循下面步骤。

  1. 点击Pluglets API
  2. 向下滚动至 Pluglets Packages ,并点击 com.ibm.xtools.pluglets。
  3. 在 class summary 中点击 Pluglet。这就产生了可以从 pluglet 中调用的方法列表。

blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


Pluglet 项目

我推荐您使用向导来创建 pluglet 项目和新的 pluglet 类。向导将为您创建一个包含基本输入的 pluglet.xml。

重要的部分是在为 pluglet 编码时确保项目中的 pluglet.xml 文件包含您所需要的 API 的所有插件程序。为了得到您可以导入的插件程序名称列表,选择Help > About IBM Rational Software Development Platform并点击Plug-in Details。在这里没有完成的代码来帮助您。因为它是一个 XML 文件,所以您能够获得创建元素和属性标记而不是导入属性的内容方面的帮助。

为 了确保您已经正确地为 pluglet 输入了 import 语句,并且插件程序都存在,您可以在 pluglet 项目里展开 Pluglet Plug-in dependencies ,并查看与这个插件程序相关的 JAR 文件。这些 JAR 文件的顺序必须遵循 plugin.xml 里指定的顺序,因此如果您添加一个 import 语句到底部,在 dependencies folder 的末尾进行核对。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


编写 pluglet

Pluglet 与标准的 Java 程序十分相似:您拥有一个实现了主入口点的主类。下面的代码展示了是一个 pluglet 的例子:hello world

import com.ibm.xtools.pluglets.Pluglet;

public class Simple extends Pluglet {

public void plugletmain(String[] args) {

out.println(

"Pluglet "Simple" is not yet implemented."); //$NON-NLS-1$

}

}


在这里通过使用类的输出(out)特性,我们可以解如何将信息输出至 Rational Software Architect 控制台。

这个类将有一些其他的工具提供给您。这些工具的说明可以在 pluglet API 的文档中找到。除了与 System.out 相同的方法外,有可能使用的其他方法是告知、提示、询问、确认、出错和警告的对话框方法。这提供了一些标准的易于使用的对话框。例如,要展示图1中显示的 对话框,需要编码如下:

Inform("press OK to continue");



图1. 带有 OK按钮的 TestTasks 对话框
TestTasks dialog says

此外,要出现图2中所显示的提示,需要创建以下编码:

String info = prompt("Enter some information");



图2. 字符串信息的提示对话框
Dialog prompts

处理异常

在 Rational Software Architect 6.0 的第一个版本里,没有被抛出的任何运行时异常或错误将不会显示出来,因此您无法容易的判定为什么 pluglet 不起作用。Rational Software Architect 6.0.1已经注意到这一点。任何一个没有被抛出的异常会在用户面前弹出,同时也被添加至 pluglet 控制台。

如下面的代码所示,发现所有的异常并正确的处理他们仍是明智之举。

 
try {



try {



}

catch(IOException ioe) {

// do something specific with an IOException

}

}

catch (Throwable e) {

// inform of the exception

inform("Exception occured: " + e.getMessage());

// output the stack trace for it, plus any nested exceptions

e.printStackTrace(out);

while (e.getCause() != null) {

out.println(" caused by: ");

e = e.getCause();

e.printStackTrace(out);

}

}



blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


运行和调试 pluglet

在运行 pluglet 之前,它需要被注册成为 Run菜单里的 Internal Tools部分的一个条目。Pluglet 环境提供了一步注册和运行 pluglet 的机制(如果还没有注册)。为了以这样的方式运行 pluglet,右击 pluglet 上下文菜单,然后选择 Run > Pluglet,如图3所示。


图3.注册并运行 pluglet
Executing the pluglet registers it automatically

这 将注册并运行 pluglet。尽管如此,有时候这可能不是您想要启动 pluglet 的方式。例如,如果一个 pluglet 在视图里被选中,那么它就可以被运行,但是如果您已经选中了您想要运行的 pluglet,那么此刻您之前选中的 pluglet 将不能够被运行。

为了能够运行在视图里运行被选中的 pluglet,首先您需要注册这个 pluglet,然后使用菜单指令来运行它。这使得您能保持视图容易看见,并确保在视图里无论什么被选中都会一直保持选中状态。

注册 pluglet

为了注册 pluglet,遵循下述步骤。

  1. 点击Run > Internal Tools > Internal Tools 显示出图4所示对话框。

图4.使用 Internal Tools 对话框来注册并运行一个新的 pluglet
Provide a Name and Location for the pluglet
  1. 点击New定义新的 pluglet 注册并给它命名。
  2. 然后,如图5所示,点击Browse Workspace,提供一个 pluglet 项目的列表及其包含的 pluglet。

图5.选择一个 workplace pluglet
Select the pluglet project from the left pane, then a pluglet from the right
  1. 选择 pluglet 并点击 OK
  2. 最后,点击Apply and Close

现在您已经注册了 pluglet。

通过菜单运行 pluglet

  1. 现在选择Run > Internal Tools并选择您已经注册的 pluglet 来运行它。

调试

这里没有调试器,因此您应该使用通过 out.println 编码的旧的调试方法。也要注意没有与err同样的特性。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


在不同的线程上运行 pluglet 代码

当 运行 pluglet 时,它在 Rational Software Architect(用户界面)UI 线程上运行。如果您的 pluglet 运行非常快,这样做没问题,但是如果它是一个漫长的运行过程(或者与外部资源相互交互,比如说在网络上),那么您也许不想在 UI 线程上执行。

另 一个对我们来说看似不可能发生但却真实发生的问题是,会出现使得 Rational Rational Software Architect 挂起的僵局。在 UI 线程上运行的 pluglet 调用了阻塞等待结果的 API。这个 API(调用其他不同的组件)创建了一个新的线程,反过来想要在 UI 线程上进行同步调用。这导致了这样的僵局,因为 UI 线程不再等待 API 的返回。这是不在 UI 线程上运行 pluglet 的另一个不错的理由。

对于将 pluglet 代码从 UI 线程上去掉有两种选择:

  • 在 pluglet 里创建一个新的线程并在那里执行代码
  • 在一个不同的线程上使用 Rational Software Architect 提供的工具来执行代码

使用线程快捷简单。而且,如果您想调用 pluglet 类提供的任何一个对话框,您都可以这样做,因为事实上他们就在 UI 线程上执行。

 
import com.ibm.xtools.pluglets.Pluglet;

public class SimpleThread extends Pluglet implements Runnable {

public void plugletmain(String[] args) {

Thread t = new Thread(this);

t.run();

out.println("This may not appear until the other thread has

ended");

out.println("main thread ended");

out.flush();

}



/* (non-Javadoc) @see java.lang.Runnable#run() */

public void run() {

out.println("This could be be output first");

inform("press ok to continue");

out.println("Hi there from the other thread");

}

}


注意 pluglet 控制台上的输出:

This could be be output first (Ok on the prompt is now pressed)

Hi there from the other thread

This may not appear until the other thread has ended

main thread ended


这不是我们所期待的。主线程的输出直到 pluglet 结束之后才能被看到,甚至在您有机会点击提示对话框的OK按钮之前主线程应该已经结束。因此,让我们尝试另一个程序。

import com.ibm.xtools.pluglets.Pluglet;

public class Delay1 extends Pluglet {

public void plugletmain(String[] args) {

out.println(

"Pluglet "Delay1" issuing a message."); //$NON-NLS-1$

out.flush();

try {

synchronized (this) {

wait(5000);

}

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace(out);

}

}

}


在这个例子里,输出没有在控制台上出现5秒钟。因此我们发现了在 UI 线程上运行 pluglet 并输出信息到控制台上的另一个问题:整个 pluglet 必须在主线程的任何一个输出被发送到控制台之前结束。此外,解决方案是在另一个不同线程上运行每一件事情。

在 非 UI 线程上运行 pluglet 代码的另一个方法是使用 IProgressService.busyCursorWhile 工具。这阻塞了主线程但是在另一个线程上执行代码。它在短时间内显示了一个忙碌的光标,之后显示一个进度栏,您可以从 pluglet 代码来控制他们。如果您愿意,您也可以(在代码里)使用对话框将进度栏覆盖掉。

为了使用这一点,在 pluglet.xml 中首先需要下面的输入:








下面的代码显示了使用 busyCursorWhile 的例子:

public class ShowAProgress extends Pluglet {

public void plugletmain(String[] args) {

IProgressService progressService =

PlatformUI.getWorkbench().getProgressService();

try {

progressService.busyCursorWhile(new IRunnableWithProgress() {

public void run(IProgressMonitor monitor) {

performAction(monitor);

}

});

}

catch (InvocationTargetException e) {

}

catch (InterruptedException e) {

}

}



protected void performAction(IProgressMonitor monitor) {

monitor.beginTask("The main task", 3);

monitor.subTask("Waiting for the First Second");

waitASecond();

monitor.worked(1);

monitor.subTask("Waiting for the Second Second");

waitASecond();

monitor.worked(1);

monitor.subTask("Waiting for the Third Second");

waitASecond();

monitor.worked(1);

inform("All Seconds done");

monitor.done();

}



private void waitASecond() {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

}

}


从 pluglet 访问外部的JAR 文件和项目类

如 果您选择 pluglet 项目的属性,您会发现一个 Java 项目可以做的全部事情它都可以做到。既然是这样,您也可能会需要为项目添加一些到内部和外部 JAR 文件的引用。如果您这样做,您将发现您可以在 pluglet 的代码中引用这些外部包中的类和 API,而且它将可以编译甚至提供完成的代码。

尽管如此,只要您尝试运行代码,它将失败并提示 "java.lang.NoClassDefFoundError"。最佳的解决方案是为您要访问的外部 JAR 文件创建插件程序。

使用 System.ou 或 System.err 捕获来自与 API 的输出

如 果您真的调用一个发送其数据输出至 System.out 或 System.err 的 API(事实上,我在一个创建自身控制台的插件程序中碰到过这种情况),您可能希望获取返回的信息。如下面代码所示,通过将 System.out 或 System.err 的输出重新定向到 ByteArrayOutputStream 可以很容易做到:

 
ByteArrayOutputStream baos = new ByteArrayOutputStream();

PrintStream savedOut = System.out;

System.setOut(new PrintStream(baos));



// Invoke the API



System.setOut(savedOut);

out.println(baos.toString());

baos.reset();



blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


例1:使用 pluglet 来测试您的插件程序(plugin )

好 的,这样看来您已经编写出了插件程序并想试验一下。Pluglet 将是一个显然的选择,但是在您的运行时平台已经启动并且已经创建了一个 Pluglet 项目后,您会发现您不能将插件程序添加到 pluglet.xml 文件里。当您将入口添加到 pluglet.xml 时,您仍然不能访问插件程序代码。如果您查看错误日志,您会发现以下类似的信息:

 IRJP0001E Workspace deployed plug-in "TestPlugletPlugin" is missing its runtime 
library "TestPlugletPlugin.JAR"。

事实上这是因为 pluglet 引擎正在为插件程序寻找 JAR 文件。正如插件程序项目里 plugin.xml 所定义的,您可以通过将插件程序打包到一个 JAR 文件并将它放在合适的位置来解决这一问题。最简单的方法是使用Export to JAR工具。

这 也允许您保存 JAR 文件创建描述,使得您很容易根据需要创建和再创建 JAR 文件。当您创建 JAR 文件时,它只包括产生的类文件和资源。一旦您有了 JAR 文件并将插件程序添加到 pluglet.xml,通过在 pluglet 项目里扩展 Pluglet 插件程序依赖关系树以保证 JAR 文件的存在并一切都是正确的。

调试和紧急代码修复

您可以按常规的方式调试插件程序代码,但是您也可能需要对代码进行紧急替换。也就是说,您不必重新启动就能做到下面几点:

  • 修改方法的行为
  • 改变方法签名
  • 添加一个新的方法并在运行时工作台中修改 pluglet

如图6所示,为了使紧急修复的代码工作,您需要启动运行时工作台,并在 Command Line Settings 中为 VM arguments 输入 -Xj9。


图6. 将 VM arguments 设置为 -Xj9
Providing the command line settings

为 了理解如何实现完全的紧急代码修复,您需要了解环境的工作方式。Pluglet 引擎在编辑器中为 pluglet 代码使用 JAR 文件。它用来为 pluglet 代码检查错误,并完成代码。它并不用来执行 pluglet。Pluglet 通过插件程序项目里的二进制文件来执行。

如果您想改变方法的行为,您需要做的全部事情就是修改插件程序的源代码(甚至在运行 pluglet 时),如果可能的话代码将被立即替换掉。

如 果您想改变方法签名或者添加一个方法,您要修改您的插件程序的源代码,但是一旦您将其保存您必须重新构建您的 JAR 文件。为了使 pluglet 里的变化生效,您将需要修改 pluglet 并保存(或者更新pluglet项目)使得环境发现 JAR 文件的变化。


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


例2:将 pluglet 作为一个宏环境使用

c.gif
MODELWARE 是由 "Information Society Technologies" Sixth Framework Programme (2002-2006) 下的 European Commission 共同投资的一个项目。本文中所包含的信息仅仅反映了作者的观点。European Commission 对在这里可能包含的信息的任何使用不负责任。

作为我研究 Modelware 项目的一部分(http://www.modelware-ist.org ),我们需要一个方法来与 Rational Software Architect 资源进行交互:项目、文件、模型、模型中的元素和图象。此外,我们必须在 Rational Software Architect 工作区内构造一些简单的宏来访问这些资源并将它们传递给外部工具(和其他内部机制、如转换引擎)来处理和创建的资源。

为 了促进这一点,我们创建了一个插件程序,明确目标为 pluglet 提供高水平的任务。这些任务提供了一个简单的 API,使得编写 pluglet 脚本变得快捷简单。这些 API 不是为了性能而设计的,而是为了便于使用。它也以确保特定环境正常工作的方式运转。例如,ModelManager 任务创建了模型的副本,而不是引用内存中原始模型。

Rational Software Architect Tasks 包被分成五个独立的部分,如表1所示。


表1.将 Rational Software Architect 任务分成独立的部分
任务描述
资源任务与 Rational Software Architect 资源进行交互:项目、文件夹和文件
模型管理器任务在内存中获取 Rational Software Architect UML2 模型的对象、概要文件、已选模型的内部元素和储存在模型和工作区概要文件中的图
Rational Software Architect 模型任务从内存中得到图和纯 UML2(没有图表信息)模型
Rational Software Architect 模型转换任务调用标准的 Rational Software Architect 转换
Pluglet 任务为 pluglet 提供有用的常规工具,例如,更多的对话框和在不同的线程上运行 pluglet 代码的简单机制

Tasks 包并不为操作模型提供任何简单的方法。这一点通过使用转换或者 UML2 API 可以很好的实现。

Tasks 插件程序包在本文中可以找到(查阅 下载 部分),由一个代码插件程序和一个文档插件程序组成,可以安装在 Rational Software Architect 中(如,在 eclipse 目录中)。同时包括带有使用任务包例子的样本项目。

下面的代码实例显示的是如何编写一个可以从一个选定的 Rational Software Architect 模型中获取所有图然后将它们储存在项目里的宏。为了运行这个宏,遵循以下步骤。

  1. 在 Model Explorer 中打开模型。
  2. 选择模型元素。
  3. 通过选择Run > Internal Tools调用宏。
  4. 您将被提示提供保存结果的文件夹。
  5. 使用导航器找到保存的JPG文件,双击并查看它们。
 import org.eclipse.core.runtime.IProgressMonitor;


import org.eclipse.uml2.Model;

import com.ibm.mdbi.tasks.TaskException;

import com.ibm.mdbi.tasks.rsa.ModelManagerTasks;

import com.ibm.mdbi.tasks.rsa.PlugletTasks;

import com.ibm.mdbi.tasks.rsa.RSAModelTasks;

import com.ibm.mdbi.tasks.rsa.RunnablePluglet;

import com.ibm.xtools.pluglets.Pluglet;



public class EDiags extends Pluglet implements RunnablePluglet {

public void plugletmain(String[] args) {

try {

PlugletTasks.INSTANCE.runPlugletWithProgress(this);

}

catch (TaskException pe) {

pe.printStackTrace(out);

}

}



public void performAction(IProgressMonitor monitor) {

boolean beginTask = false;

try {

Model model = ModelManagerTasks.INSTANCE.getSelectedModel();

if (model != null) {

String[] location = getFolder();

if (location[0] != null) {

monitor.beginTask("Extracting Diagrams", 1);

beginTask = true;

monitor.subTask("retrieving JPG diagrams from model");

RSAModelTasks.INSTANCE.getAllDiagrams(model, "JPG",

location[0], "diagrams");

monitor.worked(1);

inform("Diagrams saved");

}

}

else {

inform("No Model Selected");

}

}

catch (Throwable e) {

inform("Exception '" + e.getClass().getName() + "' occurred.

See console for full details");

e.printStackTrace(out);

while (e.getCause() != null) {

out.println(" caused by: ");

e = e.getCause();

e.printStackTrace(out);

}

}

finally {

if (beginTask) {

monitor.done();

}

}

}



private String[] getFolder() {

return PlugletTasks.INSTANCE.allFolderSelectDialog("Select a

Folder to store diagrams");

}

}



blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


结束语

Rational Software Architect pluglet 为用户提供了一些很好的特性。希望这篇文章为您如何使用 pluglet 以及您可以使用它们做什么提供了一个良好的开始。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130062/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130062/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值