本教程的目的是使您轻松学习开发 NetBeans IDE 服务器插件的初级 阶段。它提供骨干服务器插件的代码,以及从头开始创建该插件的详细步骤及其每个部分的详细描述。由于这只是骨干 插件,因此,此处不涉及特定于服务器的活动(如启动和停止、部署、取消部署以及自定义)。但是,您创建和安装骨干服务器插件之后,您将有足够的功能在 Server Manager 中注册新服务器类型,并通过 New Project 向导和 Project Properties 对话框将其指定给应用程序。并且您将拥有一个工作框架,在该框架顶部您可以构建自己的 NetBeans IDE 服务器插件。
本教程将介绍以下主题:
有关使用 NetBeans 插件的详细信息,请参阅 NetBeans 网站上的 NetBeans Development Project 主页。如果有问题,请访问 NetBeans Developer FAQ 或使用本页顶部的反馈链接。
了解示例
开始编写插件之前,必须确保您具备所有必要的软件。此外,您可能想在亲自构建之前使用示例。了解示例介绍在本教程的其余部分您所要做的事项。
安装软件
开始之前,需要在您的计算机上安装以下软件:
安装示例
采用以下步骤来安装示例:
- 解压缩附加的文件。
- 在 IDE 中,选择 File > Open Project,然后浏览到包含已解压缩文件的文件夹。打开插件项目。其形式如下:
- 右键单击项目节点并在 Target Platform 中选择 Install/Reload。将打开目标平台并安装该插件。
介绍示例
- 选择 Tools > Server Manager,单击 Add Server 并注意到一个新的服务器可用:
- 单击 Next。显示安装窗体实现的基础:
有关详细信息,请参阅 MyInstantiatingIterator.java。
- 单击 Finish。一个新节点出现在 Servers 列表中并且自定义实现显示在该面板的主要部分中:
有关详细信息,请参阅 MyInstanceNode.java。
- 单击 Close。打开 Runtime 窗口 (Ctrl-5) 并注意 Servers 节点下的新节点。当您右键单击节点时,显示菜单实现的基础:
选择 Start/Stop Server 时,出现一个常规的 Server Status 对话框:
有关详细信息,请参阅 MyRegistryNodeFactory.java。
即使该插件服务器无法启动,您也可以将其指定为应用程序的目标服务器,如下一步所示。
- 采用以下一种或两种方法将服务器指定为应用程序的目标服务器:
- 选择 File > New Project (Ctrl-Shift-N)。在 Categories 下,选择 Web 并在 Projects 下选择 Web Application。单击 Next。在 Name and Location 面板中,注意 Server 下拉列表包括新的服务器类型:
- 右键单击项目并选择 Properties。将打开 Project Properties 对话框。在 Run 面板中,注意 Server 下拉列表包括新的服务器类型:
介绍源
该示例由工厂类、实现类和支持文件组成。
-
工厂类。 该插件使用工厂模式实例化实现类。该插件的工厂在下图中高亮显示:
按照字母顺序介绍工厂:
文件描述MyDeploymentFactory.java DeploymentFactory 接口的实现,它生成 DeploymentManager 接口实现的实例,如 MyDeploymentManager。 MyJ2eePlatformFactory.java J2eePlatformFactory 抽象类的实现,它生成 J2eePlatformImpl 抽象类实现的实例,如 MyJ2eePlatformImpl.java。 MyOptionalFactory.java OptionalDeploymentManagerFactory 抽象类的实现。尽管它的名称表示它是可选的,但实际上它不是。您至少需要为在 IDE 中启动、停止和注册服务器而实现其方法。因此,MyOptionalFactory 类生成 MyStartServer 和 MyInstantiatingIterator 实现类的实例。 MyRegistryNodeFactory.java RegistryNodeFactory 接口的实现。该工厂的作用是生成一个或多个注册表节点(在本例中为 MyInstanceNode)作为 Runtime 窗口中的用户界面表示。 -
实现类。 实现类由工厂实例化。该插件的实现类在下图中高亮显示:
按照字母顺序介绍实现类:
文件描述MyDeploymentManager.java DeploymentManager 接口的虚拟实现,它不执行任何操作,由您决定提供其特定于服务器的实现。 MyDeploymentPlanSplitter.java DeploymentPlanSplitter 的实现,它允许您通过 writeDeploymentPlanFiles() 和 readDeploymentPlanFiles() 方法从多个文件还原 DeploymentConfiguration 并将其存储到多个文件。 MyInstantiatingIterator.java 创建一个向导,用于在 IDE 中注册新服务器类型实例。当前实现让用户仅指定 Display Name;对其他属性进行硬编码以便使实现尽可能简单。 MyJ2eePlatformImpl.java J2eePlatformImpl 的实现,它用于描述构建 J2EE 应用程序并随后将其部署到的目标环境。它提供一组服务器库、支持的模块类型和 J2EE 规范版本。 MyStartServer.java StartServer 抽象类的实现。它的目的是提供启动、停止以及确定服务器状态的能力。 MyInstanceNode.java 代表 Runtime 窗口中的新服务器。j2eeserver 模块,但是向每个节点添加了一组默认的功能,如显示运行状态和默认菜单项组的功能。 -
支持资源。 该插件的支持资源在下图中高亮显示:
下面按照字母顺序介绍 Java 包中的支持资源:
文件描述Bundle.properties 这是标准 Java 属性文件,它使用语法 Key=Value。键是出现在源代码中内容的代码名称,它的值表示将向用户显示的内容。该文件对于本地化特别有用。例如,通过创建 Bundle_ja.properties 之类的属性文件并用日语填写所有值,该插件在用户以日语模式运行 IDE 时将自动用日语显示所有内容。 layer.xml 在 NetBeans 文件系统中注册新服务器类型。 nbdep.xml 指定将在 Runtime 窗口中使用的图标、用于获得断开的 DeploymentManager 实例的 URL、指定支持的部署种类的 container-limitation element 以及上下文路径。 server.gif IDE 中新服务器类型的节点的图标。 有关每个 Important Files 的基本信息,请参阅 NetBeans 插件的快速入门指南。
设置插件项目
开始编写插件前,必须确保正确地设置了项目。NetBeans IDE Dev 提供一个向导,用于设置插件所需的所有基本文件。
创建插件项目
- 选择 File > New Project。在 Categories 下,选择 NetBeans Plug-in Modules。在 Projects 下,选择 Module Project 并单击 Next。
- 在 Name and Location 面板中,在 Project Name 中键入 My Server Plugin。将 Project Location 更改为您计算机上的任何目录,如 c:/mymodules。选中 Standalone Module 单选按钮。选中 Set as Main Project 复选框。单击 Next。
- 在 Basic Module Configuration 面板中,用 netbeans 替换 Code Name Base 中的 yourorghere,追加 .modules.j2ee 并将“My Server Plugin”更改为 .myserver,从而整个 Code Name Base 为 org.netbeans.modules.j2ee.myserver。在 Module Display Name 中填入 My Server Plugin。更改本地化资源包和 XML 层的位置,以便将它们存储在名为 org.netbeans.modules.j2ee.myserver.resources 的包中。单击 Finish。
IDE 创建 My Server Plugin 项目。该项目包含所有资源和项目元数据,如该项目的 Ant 构建脚本。该项目在 IDE 中打开。您可以在 Projects 窗口 (Ctrl-1) 中查看其逻辑结构,在 Files 窗口 (Ctrl-2) 中查看其文件结构。例如,现在 Projects 窗口应该如下所示:
有关以上每个文件的基本信息,请参阅 NetBeans 插件模块的快速入门指南。
指定插件的依存关系
您需要将几个属于 NetBeans API 的类设为子类。每个类都将被声明为插件依存关系。使用 Project Properties 对话框来执行此操作。
- 在 Projects 窗口中,右键单击 My Server Plugin 项目并选择 Properties。在 Project Properties 对话框中单击 Libraries。
- 对于以下列表中显示的每个 API,在 Libraries 面板中,单击“Add...”,从 Module 列表中选择名称,然后单击 OK 确认:
- 单击 OK,退出 Project Properties 对话框。
- 在 Projects 窗口中,双击 Project Metadata 并注意您选择的 API 是否声明为插件依存关系:
创建工厂类
实现类由工厂实现。在本部分中您将创建并检查它们:
- MyDeploymentFactory.java
- MyJ2eePlatformFactory.java
- MyOptionalFactory.java
- MyRegistryNodeFactory.java
MyDeploymentFactory.java
MyDeploymentFactory 类是 DeploymentFactory 的实现,它生成 MyDeploymentManager 实现类的实例。
以下是该类中需要注意的方法:
- handlesURI()。确定给定的 MyDeploymentFactory 是否可以处理指定的 URI。
- getDeploymentManager()。创建一个连接的 DeploymentManager 实例。该实例提供对 J2EE 资源的访问。
- getDisconnectedDeploymentManager()。创建一个非连接的 DeploymentManager 实例。该实例提供对配置支持的访问。
新服务器实例将使用 deployer:myserver 前缀,以便用来获得连接的部署管理器的 URL 如下:deployer:myserver:localhost:8080。
执行以下操作以创建 MyDeploymentFactory 类:
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > File/Folder。在 Categories 下选择 Java Classes。在 File Types 下,选择 Java Class。单击 Next 并在 Class Name 中键入 MyDeploymentFactory。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import javax.enterprise.deploy.shared.factories.DeploymentFactoryManager; import javax.enterprise.deploy.spi.DeploymentManager; import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException; import javax.enterprise.deploy.spi.factories.DeploymentFactory; import org.openide.ErrorManager; import org.openide.util.NbBundle; public class MyDeploymentFactory implements DeploymentFactory { public static final String URI_PREFIX = "deployer:myserver"; // NOI18N private static DeploymentFactory instance; public static synchronized DeploymentFactory create() { if (instance == null) { instance = new MyDeploymentFactory(); DeploymentFactoryManager.getInstance().registerDeploymentFactory(instance); } return instance; } public boolean handlesURI(String uri) { return uri != null && uri.startsWith(URI_PREFIX); } public DeploymentManager getDeploymentManager(String uri, String uname, String passwd) throws DeploymentManagerCreationException { if (!handlesURI(uri)) { throw new DeploymentManagerCreationException("Invalid URI:" + uri); // NOI18N } return new MyDeploymentManager(); } public DeploymentManager getDisconnectedDeploymentManager(String uri) throws DeploymentManagerCreationException { if (!handlesURI(uri)) { throw new DeploymentManagerCreationException("Invalid URI:" + uri); // NOI18N } return new MyDeploymentManager(); } public String getProductVersion() { return "0.1"; // NOI18N } public String getDisplayName() { return NbBundle.getMessage(MyDeploymentFactory.class, "TXT_DisplayName"); // NOI18N } }
MyJ2eePlatformFactory.java
MyJ2eePlatformFactory 类是 J2eePlatformFactory 类的实现。该实现非常简单,它生成 MyJ2eePlatformImpl 类的实例。
执行以下操作以创建 MyJ2eePlatformFactory 类:
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyJ2eePlatformFactory。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import javax.enterprise.deploy.spi.DeploymentManager; import org.netbeans.modules.j2ee.deployment.plugins.api.J2eePlatformFactory; import org.netbeans.modules.j2ee.deployment.plugins.api.J2eePlatformImpl; public class MyJ2eePlatformFactory extends J2eePlatformFactory { public J2eePlatformImpl getJ2eePlatformImpl(DeploymentManager dm) { return new MyJ2eePlatformImpl(); } }
MyOptionalFactory.java
MyOptionalFactory 类是 OptionalDeploymentManagerFactory 的实现。尽管它的名称可能暗示它是可选的,但是该工厂类不是 可选的。至少需要实现两种方法:
- getStartServer()。启动和停止服务器。
- getAddInstanceIterator()。创建向导,用于在 IDE 中注册服务器。
此处不实现其他两种方法:
- getIncrementalDeployment()。创建 IncrementalDeployment,它提供更便于部署的可选方法。
- getFindJSPServlet()。创建 FindJSPServlet,它允许插件指定为 JSP 生成的 Servlet 位置。
执行以下操作创建 MyOptionalFactory 类:
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyOptionalFactory。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import javax.enterprise.deploy.spi.DeploymentManager; import org.netbeans.modules.j2ee.deployment.plugins.api.FindJSPServlet; import org.netbeans.modules.j2ee.deployment.plugins.api.IncrementalDeployment; import org.netbeans.modules.j2ee.deployment.plugins.api.OptionalDeploymentManagerFactory; import org.netbeans.modules.j2ee.deployment.plugins.api.StartServer; import org.openide.WizardDescriptor.InstantiatingIterator; public class MyOptionalFactory extends OptionalDeploymentManagerFactory { public StartServer getStartServer(DeploymentManager dm) { return new MyStartServer(); } public IncrementalDeployment getIncrementalDeployment(DeploymentManager dm) { return null; } public FindJSPServlet getFindJSPServlet(DeploymentManager dm) { return null; } public InstantiatingIterator getAddInstanceIterator() { return new MyInstantiatingIterator(); } }
MyRegistryNodeFactory.java
MyRegistryNodeFactory 类是 RegistryNodeFactory 的实现。该工厂的作用是生成服务器和目标节点,它们用作 Runtime 窗口中的用户界面表示。由于新的服务器类型只有一个目标,因此它的 Admin Server 也是目标服务器,您不需要实现目标节点。
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyRegistryNodeFactory。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver.nodes; import org.netbeans.modules.j2ee.deployment.plugins.api.RegistryNodeFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.Lookup; public class MyRegistryNodeFactory implements RegistryNodeFactory { public Node getTargetNode(Lookup lookup) { return null; } public Node getManagerNode(Lookup lookup) { return new MyInstanceNode(lookup); } }
创建实现类
实现类由工厂实现。在本部分中您将创建并检查它们:
- MyDeploymentManager.java
- MyDeploymentPlanSplitter.java
- MyInstantiatingIterator.java
- MyJ2eePlatformImpl.java
- MyStartServer.java
- MyInstanceNode.java
MyDeploymentManager.java
DeploymentManager 接口的虚拟实现,它不执行任何操作,由您决定提供其特定于服务器的实现。
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > File/Folder。在 Categories 下选择 Java Classes。在 File Types 下,选择 Java Class。单击 Next 并在 Class Name 中键入 MyDeploymentManager。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import java.io.File; import java.io.InputStream; import javax.enterprise.deploy.model.DeployableObject; import javax.enterprise.deploy.shared.DConfigBeanVersionType; import javax.enterprise.deploy.shared.ModuleType; import javax.enterprise.deploy.spi.DeploymentConfiguration; import javax.enterprise.deploy.spi.DeploymentManager; import javax.enterprise.deploy.spi.Target; import javax.enterprise.deploy.spi.TargetModuleID; import javax.enterprise.deploy.spi.exceptions.DConfigBeanVersionUnsupportedException; import javax.enterprise.deploy.spi.exceptions.InvalidModuleException; import javax.enterprise.deploy.spi.exceptions.TargetException; import javax.enterprise.deploy.spi.status.ProgressObject; public class MyDeploymentManager implements DeploymentManager { public ProgressObject distribute(Target[] target, File file, File file2) throws IllegalStateException { return null; } public DeploymentConfiguration createConfiguration(DeployableObject deployableObject) throws InvalidModuleException { return null; } public ProgressObject redeploy(TargetModuleID[] targetModuleID, InputStream inputStream, InputStream inputStream2) throws UnsupportedOperationException, IllegalStateException { return null; } public ProgressObject distribute(Target[] target, InputStream inputStream, InputStream inputStream2) throws IllegalStateException { return null; } public ProgressObject undeploy(TargetModuleID[] targetModuleID) throws IllegalStateException { return null; } public ProgressObject stop(TargetModuleID[] targetModuleID) throws IllegalStateException { return null; } public ProgressObject start(TargetModuleID[] targetModuleID) throws IllegalStateException { return null; } public void setLocale(java.util.Locale locale) throws UnsupportedOperationException { } public boolean isLocaleSupported(java.util.Locale locale) { return false; } public TargetModuleID[] getAvailableModules(ModuleType moduleType, Target[] target) throws TargetException, IllegalStateException { return null; } public TargetModuleID[] getNonRunningModules(ModuleType moduleType, Target[] target) throws TargetException, IllegalStateException { return null; } public TargetModuleID[] getRunningModules(ModuleType moduleType, Target[] target) throws TargetException, IllegalStateException { return null; } public ProgressObject redeploy(TargetModuleID[] targetModuleID, File file, File file2) throws UnsupportedOperationException, IllegalStateException { return null; } public void setDConfigBeanVersion(DConfigBeanVersionType dConfigBeanVersionType) throws DConfigBeanVersionUnsupportedException { } public boolean isDConfigBeanVersionSupported(DConfigBeanVersionType dConfigBeanVersionType) { return false; } public void release() { } public boolean isRedeploySupported() { return false; } public java.util.Locale getCurrentLocale() { return null; } public DConfigBeanVersionType getDConfigBeanVersion() { return null; } public java.util.Locale getDefaultLocale() { return null; } public java.util.Locale[] getSupportedLocales() { return null; } public Target[] getTargets() throws IllegalStateException { return null; } }
MyDeploymentPlanSplitter.java
原则上使用一个“deployment plan file”保存和加载 DeploymentConfiguration。但是很多服务器使用多个 文件来排序配置,如 Sun Java 系统应用程序服务器上 EJB 模块的 sun-ejb-jar.xml 和 sun-cmp-mappings.xml。因此,MyDeploymentPlanSplitter 是 DeploymentPlanSplitter 的实现,允许我们从多个 文件还原 DeploymentConfiguration 并将其存储到多个文件。这通过方法 writeDeploymentPlanFiles() 和 readDeploymentPlanFiles() 完成。getDeploymentPlanFileNames() 方法用来为给定模块类型定义特定于服务器的配置文件。但是不赞成这种方法,配置文件的声明通过 layer.xml 完成。
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyDeploymentPlanSplitter。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import java.io.File; import javax.enterprise.deploy.model.DeployableObject; import javax.enterprise.deploy.shared.ModuleType; import javax.enterprise.deploy.spi.DeploymentConfiguration; import javax.enterprise.deploy.spi.exceptions.ConfigurationException; import org.netbeans.modules.j2ee.deployment.plugins.api.DeploymentPlanSplitter; public class MyDeploymentPlanSplitter implements DeploymentPlanSplitter { public void writeDeploymentPlanFiles(DeploymentConfiguration config, DeployableObject module, File[] files) throws ConfigurationException { } public void readDeploymentPlanFiles(DeploymentConfiguration config, DeployableObject module, File[] files) throws ConfigurationException { } public String[] getDeploymentPlanFileNames(ModuleType type) { return new String[0]; } }
MyInstantiatingIterator.java
MyInstantiatingIterator 类用来创建在 IDE 中注册新服务器的向导。当前实现让您仅指定显示名称;对其他属性进行硬编码以便使实现尽可能简单。
注意在 instantiate() 方法中使用的 URL 变量。它传递给 InstanceProperties.createInstanceProperties() 方法,该方法进行实际的服务器注册。URL 参数与 DeploymenManager 使用的参数相同。用这种方法我们确保服务器控制新创建的服务器实例。
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyInstantiatingIterator。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import java.awt.Component; import java.awt.Label; import java.io.IOException; import java.util.HashSet; import java.util.Set; import javax.swing.JPanel; import javax.swing.event.ChangeListener; import org.openide.WizardDescriptor; import org.openide.WizardDescriptor.Panel; import org.openide.util.HelpCtx; import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties; import org.openide.DialogDisplayer; import org.openide.ErrorManager; import org.openide.NotifyDescriptor; import org.openide.util.NbBundle; public class MyInstantiatingIterator implements WizardDescriptor.InstantiatingIterator { private final static String PROP_DISPLAY_NAME = "ServInstWizard_displayName"; // NOI18N private InstallPanel panel; private WizardDescriptor wizard; public void removeChangeListener(ChangeListener l) { } public void addChangeListener(ChangeListener l) { } public void uninitialize(WizardDescriptor wizard) { } public void initialize(WizardDescriptor wizard) { this.wizard = wizard; } public void previousPanel() { } public void nextPanel() { } public String name() { return NbBundle.getMessage(MyInstantiatingIterator.class, "MSG_InstallerName"); } public Set instantiate() throws IOException { Set result = new HashSet(); String displayName = getDisplayName(); String url = "deployer:myserver:localhost:8080"; // NOI18N String username = "username"; // NOI18N String password = "password"; // NOI18N try { InstanceProperties ip = InstanceProperties.createInstanceProperties( url, username, password, displayName); result.add(ip); } catch (Exception ex) { DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( NbBundle.getMessage(MyInstantiatingIterator.class, "MSG_CreateFailed", displayName), NotifyDescriptor.ERROR_MESSAGE)); } return result; } public boolean hasPrevious() { return false; } public boolean hasNext() { return false; } public Panel current() { if (panel == null) { panel = new InstallPanel(); } return panel; } private String getDisplayName() { return (String)wizard.getProperty(PROP_DISPLAY_NAME); } private static class InstallPanel implements WizardDescriptor.Panel { public void removeChangeListener(ChangeListener l) { } public void addChangeListener(ChangeListener l) { } public void storeSettings(Object settings) { } public void readSettings(Object settings) { } public boolean isValid() { return true; } public HelpCtx getHelp() { return HelpCtx.DEFAULT_HELP; } public Component getComponent() { JPanel panel = new JPanel(); panel.add(new Label("< Put your installation form implementation here! >")); // NOI18N return panel; } } }
MyJ2eePlatformImpl.java
MyJ2eePlatformImpl 类是 J2eePlatformImpl 的实现,它用于描述构建 J2EE 应用程序并随后将其部署到的目标环境。它提供一组服务器库、支持的模块类型和 J2EE 规范版本。
注意:由于 MyJ2eePlatformImpl.java 的当前实现不提供 J2EE API 库,您的 Web 或 EJB 项目将不会编译,除非您在 Project Properties 对话框的 Libraries 面板中显式提供这些库。
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyJ2eePlatformImpl。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import java.io.File; import java.util.HashSet; import java.util.Set; import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; import org.netbeans.modules.j2ee.deployment.plugins.api.J2eePlatformImpl; import org.netbeans.spi.project.libraries.LibraryImplementation; import org.openide.util.NbBundle; import org.openide.util.Utilities; public class MyJ2eePlatformImpl extends J2eePlatformImpl { public boolean isToolSupported(String toolName) { return false; } public File[] getToolClasspathEntries(String toolName) { return new File[0]; } public Set getSupportedSpecVersions() { Set result = new HashSet(); result.add(J2eeModule.J2EE_14); return result; } public java.util.Set getSupportedModuleTypes() { Set result = new HashSet(); result.add(J2eeModule.EAR); result.add(J2eeModule.WAR); result.add(J2eeModule.EJB); return result; } public java.io.File[] getPlatformRoots() { return new File[0]; } public LibraryImplementation[] getLibraries() { return new LibraryImplementation[0]; } public java.awt.Image getIcon() { return Utilities.loadImage("org/netbeans/modules/j2ee/myserver/resources/server.gif"); // NOI18N } public String getDisplayName() { return NbBundle.getMessage(MyJ2eePlatformImpl.class, "MSG_MyServerPlatform"); } }
MyStartServer.java
MyStartServer 类是 StartServer 接口的实现。它的目的是提供启动、停止以及确定服务器状态的能力。当前实现内容是服务器始终停止并且不能启动。由您决定为使用的服务器完成特定于服务器的实现。
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > Java Class,在 Class Name 中键入 MyStartServer。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver; import javax.enterprise.deploy.spi.Target; import javax.enterprise.deploy.spi.status.ProgressObject; import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo; import org.netbeans.modules.j2ee.deployment.plugins.api.StartServer; public class MyStartServer extends StartServer { public ProgressObject startDebugging(Target target) { return null; } public boolean isDebuggable(Target target) { return false; } public boolean isAlsoTargetServer(Target target) { return true; } public ServerDebugInfo getDebugInfo(Target target) { return null; } public boolean supportsStartDeploymentManager() { return false; } public ProgressObject stopDeploymentManager() { return null; } public ProgressObject startDeploymentManager() { return null; } public boolean needsStartForTargetList() { return false; } public boolean needsStartForConfigure() { return false; } public boolean needsStartForAdminConfig() { return false; } public boolean isRunning() { return false; } }
MyInstanceNode.java
MyInstanceNode 类代表 Runtime 窗口中作为节点的新服务器类型的实例。向该节点添加一组默认的功能,这些功能显示服务器的状态并提供默认的菜单项,如 Start/Stop Server...、Refresh 和 Remove。该操作由位于该插件提供的节点顶部的标准过滤器节点来完成。MyInstanceNode 类定义在 Tools 菜单的 Server Manager 中显示的虚拟自定义实现。
- 右键单击 org.netbeans.modules.j2ee.myserver.nodes 节点并选择 New > Java Class,在 Class Name 中键入 MyInstanceNode。单击 Finish。新 Java 类将在 Source Editor 中打开。
- 用以下代码替换默认代码:
package org.netbeans.modules.j2ee.myserver.nodes; import java.awt.Component; import java.awt.Label; import javax.swing.JPanel; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.Lookup; import org.openide.util.NbBundle; public class MyInstanceNode extends AbstractNode implements Node.Cookie { private static String ICON_BASE = "org/netbeans/modules/j2ee/myserver/resources/server.gif"; // NOI18N public MyInstanceNode(Lookup lookup) { super(new Children.Array()); getCookieSet().add(this); setIconBaseWithExtension(ICON_BASE); } public String getDisplayName() { return NbBundle.getMessage(MyInstanceNode.class, "TXT_MyInstanceNode"); } public javax.swing.Action[] getActions(boolean context) { return new javax.swing.Action[]{}; } public boolean hasCustomizer() { return true; } public Component getCustomizer() { JPanel panel = new JPanel(); panel.add(new Label("< Put your customizer implementation here! >")); // NOI18N return panel; } }
设置支持文件
已经对主文件进行编码之后,必须在 layer.xml 文件和 nbdep.xml 文件中注册您的插件。您还必须使用 Bundle.properties 文件定义希望向用户显示的标签和文本。
在 NetBeans 文件系统中注册新服务器
- 在 layer.xml 文件中的 <filesystem> 标记之间添加以下条目:
<folder name="J2EE"> <folder name="DeploymentPlugins"> <folder name="MyServer"> <file name="Descriptor" url="nbdep.xml"/> <file name="Factory.instance"> <attr name="instanceCreate" methodvalue="org.netbeans.modules.j2ee.myserver.MyDeploymentFactory.create"/> <attr name="instanceClass" stringvalue="org.netbeans.modules.j2ee.myserver.MyDeploymentFactory"/> <attr name="instanceOf" stringvalue="javax.enterprise.deploy.spi.factories.DeploymentFactory"/> </file> <file name="RegistryNodeFactory.instance"> <attr name="instanceClass" stringvalue="org.netbeans.modules.j2ee.myserver.nodes.MyRegistryNodeFactory"/> <attr name="instanceOf" stringvalue="org.netbeans.modules.j2ee.deployment.plugins.api.RegistryNodeFactory"/> </file> <file name="ConfigurationSupport.instance"> <attr name="instanceClass" stringvalue="org.netbeans.modules.j2ee.myserver.MyConfigurationSupport"/> <attr name="instanceOf" stringvalue="org.netbeans.modules.j2ee.deployment.plugins.api.ConfigurationSupport"/> </file> <file name="J2eePlatformFactory.instance"> <attr name="instanceCreate" newvalue="org.netbeans.modules.j2ee.myserver.MyJ2eePlatformFactory"/> <attr name="instanceClass" stringvalue="org.netbeans.modules.j2ee.myserver.MyJ2eePlatformFactory"/> <attr name="instanceOf" stringvalue="org.netbeans.modules.j2ee.deployment.plugins.api.J2eePlatformFactory"/> </file> <file name="OptionalFactory.instance"> <attr name="instanceCreate" newvalue="org.netbeans.modules.j2ee.myserver.MyOptionalFactory"/> <attr name="instanceClass" stringvalue="org.netbeans.modules.j2ee.myserver.MyOptionalFactory"/> <attr name="instanceOf" stringvalue="org.netbeans.modules.j2ee.deployment.plugins.api.OptionalDeploymentManagerFactory"/> </file> <file name="DeploymentPlanSplitter.instance"> <attr name="instanceCreate" newvalue="org.netbeans.modules.j2ee.myserver.MyDeploymentPlanSplitter"/> <attr name="instanceClass" stringvalue="org.netbeans.modules.j2ee.myserver.MyDeploymentPlanSplitter"/> <attr name="instanceOf" stringvalue="org.netbeans.modules.j2ee.deployment.plugins.api.DeploymentPlanSplitter"/> </file> </folder> </folder> <folder name="DeploymentFileNames"> <folder name="WAR"> <file name="META-INF/myserver-web.xml"/> </folder> </folder> </folder>
- 右键单击 org.netbeans.modules.j2ee.myserver.resources 节点并选择 New > File/Folder。在 Categories 下,选择 XML。在 File Types 下,选择 XML Document。单击 Next。在 File Name 中键入 nbdep,单击 Next,然后单击 Finish。用以下代码替换 nbdep.xml 的内容:
<netbeans-deployment> <icon>org/netbeans/modules/j2ee/myserver/resources/server</icon> <disconnected-string>deployer:myserver</disconnected-string> <container-limitation> <ear-deploy/> <war-deploy/> <ejbjar-deploy/> </container-limitation> <web-context-root> <xpath>/</xpath> <prop-name>contextRoot</prop-name> </web-context-root> </netbeans-deployment>
本地化插件
使用 Bundle.properties 文件本地化插件。Bundle.properties 为包中其他文件提供的用户界面提供特定于语言的字符串。当您使用 New Project 向导创建插件时,IDE 在 org.netbeans.modules.j2ee.myserver.resources 包中创建 Bundle.properties 文件。现在您将 key=value 对添加到 IDE 生成的 Bundle.properties 文件中并为其他包创建两个附加的 Bundle.properties 文件。
- 在 org.netbeans.modules.j2ee.myserver.resources 中,将以下属性添加到 Bundle.properties 文件:
OpenIDE-Module-Name=My Server Plugin OpenIDE-Module-Display-Category=Database OpenIDE-Module-Short-Description=My Server Plugin OpenIDE-Module-Long-Description=My Server Plugin
- 右键单击 org.netbeans.modules.j2ee.myserver 节点并选择 New > File/Folder。在 Categories 下选择 Other。在 File Types 下,选择 Properties File。单击 Next。在 File Name 中键入 Bundle,然后单击 Finish。将以下属性添加到 Bundle.properties 文件:
TXT_DisplayName=My Server MSG_InstallerName=My Server Installer MSG_CreateFailed=Cannot create {0} server instance. MSG_MyServerPlatform=My Server Platform
- 在 org.netbeans.modules.j2ee.myserver.nodes 包中创建 Bundle.properties 文件并向它添加以下属性:
TXT_MyInstanceNode=My Server Instance TXT_MyTargetNode=My Target Instance
获得图标
确保您在 org.netbeans.modules.j2ee.myserver.resources 包中具有名为 server.gif 的 16x16 图标。例如,您可以在 NetBeans IDE Dev 安装目录中的以下位置找到一些 16x16 像素图标:
enterprise1/jakarta-tomcat-5.5.7/server/webapps/admin/images
构建和安装插件
IDE 使用 Ant 构建脚本来构建和安装您的插件模块。构建脚本是在您创建 Plug-in 项目时为您创建的。
安装 NetBeans 插件
- 在 Projects 窗口,右键单击 My Server Plugin 项目并在 Target Platform 中选择 Install/Reload。
插件即在目标 IDE 或 Platform 中构建和安装。打开目标 IDE 或 Platform 以便您可以试用新插件。默认目标 IDE 或 Platform 是由开发 IDE 的当前实例使用的安装平台。注意到当您运行插件时,您将使用临时测试用户目录,而不是开发 IDE 的用户目录。
使用 NetBeans 插件
- 选择 Tools > Server Manager,单击 Add Server 并注意到一个新的服务器可用:
- 按照介绍示例所述使用插件。
添加特定于服务器的代码
添加特定于服务器的代码之前,看一看其他人如何完成该操作。
- 按照服务器插件项目页面上的说明,下载 JBoss、WebLogic 和 WebSphere 的开放源码服务器插件。
- 在 IDE 中打开一个或多个下载的服务器插件的源码并浏览它们。例如,如果您打开 JBoss 插件的源码,则 Projects 窗口将如下所示:
注意上图,选中的文件就是本教程中要讨论的文件。
- 使用本教程和 NetBeans API 列表(当前开发版本)来帮助您检查源码。
- 创建您自己的服务器插件!