站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Eclipse 专题使用 XML: 创建项目

使用 XML: 创建项目

摘要: 本文继续讨论 Eclipse 与 XM 的集成,Eclipse 是 IBM 的开放源码项目,用于构建针对 Java 开发人员的可扩展集成开发环境(IDE);而 XM 是 Beno?t Marchal 的简单内容管理解决方案。在这篇专栏文章中,Beno?t 添加了初始化新项目的向导。在此期间,他把自己辛苦得来的有关 Eclipse 平台的发现与大家分享。

如果您从一开始就一直学习本项目,那么就会了解我非常热衷于 Eclipse。就像 Emacs 迷告诉您的那样,好的开发环境必须是可扩展 并且是可配置的。Eclipse 是在综合考虑了这两方面之后推出的,但是与其享有盛誉的“前辈”Emacs 不同的是,Eclipse 还提供了新式的用户界面。

SWT 的可移植性

Eclipse 的优点之一是它修正了 Java 技术中我所认为的一个最大败笔:用户界面库。正如我所说的那样,Eclipse 使用标准窗口构件工具箱(Standard Widget Toolkit,SWT),SWT 结合了抽象窗口工具箱(Abstract Windowing Toolkit,AWT)的最佳特性、本机控件的使用和 Swing 丰富的窗口构件集。最终有可能设计出与本机用户界面行为相似的成熟的用户界面。

SWT 受到的大多数批评都集中在可移植性方面。由于 SWT 不属于 JDK(Java 开发工具箱),因此它在某些平台上可能无法使用。幸运的是,Eclipse 团队似乎承诺要将 SWT 移植到尽量多的平台上,因此实际上这已不成问题了。

我很想测试 SWT 的可移植性,因此当出现了 Macintosh 构建时,我立刻下载了它。尽管 Mac 移植仍然处于开发过程中,但它还是相当稳定的。但是我印象最深的是 SWT 及其绘制本机 Aqua 控件的能力。


<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

关于文档

使用新项目并编写有关它们的文章是很有意思的,但是也有缺陷:新项目的文档编制往往不够完善。Eclipse 也不例外。撰写本文 - 或者更确切地说是为其编码 - 需要进行许多研究。其文档仅限于几篇有关原理的文章、API 文档和源代码(幸运的话才会有)。

开发过程通常要反复试验 - 编写修改代码直到它能做出点有意义的事情。遗憾的是,通常我认为自己了解了某些东西,转而开始新任务,结果才发现自己错了!直至最后,我才相信自己真的懂了。我所面临的问题单独来看没有一个是极为困难的,但这些问题合并在一起却成了难题了。随着越来越多文章的发表,(缺乏)文档的问题最终会不存在。

<table align="right" border="0" cellspacing="0" cellpadding="0" width="40%"><tr><td width="10"></td><td><table border="1" cellspacing="0" cellpadding="5" width="100%"><tr><td bgcolor="#eeeeee"> “使用 XML”论坛

我们有了一个更便于使用的新论坛软件,因此请您务必通过单击本文顶部或底部的 讨论来参与有关 XML、其它专栏项目或 Eclipse 的讨论。

</td></tr></table></td></tr></table>
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

XM 插件的发展

在前一篇专栏文章“ Integrating XM and Eclipse”的结束部分,我粗略地完成了 XM 和 Eclipse 的集成。我在上下文菜单中添加了一项,用户可以选择它来运行 XM。我知道这只是第一步,但是当我(和 Pineapplesoft 的其他成员)开始使用它,我觉得我需要做得更好。我特别不满意的是:

清楚了这些缺点,所以我决定在不久的将来 XM 插件应该包括 New Project向导并且包括在项目构建期间调用 XM 的能力。这两个特性通过扩展点(extension point)来实现(请参考 参考资料中的“Use Eclipse to build a user interface for XM”一文以获取有关扩展点的更多详细信息)。新向导的扩展点是 org.eclipse.ui.newWizards ,它使用接口 org.eclipse.ui.INewPlugin 。构建器的扩展点是 org.eclipse.core.resources.builders ,它使用接口 org.eclipse.core.resources.IncrementalProjectBuilder


<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

新建项目向导

新建项目(New Project)向导和构建器是相关的。例如,在创建新项目时 Eclipse 会自动调用构建器。如果您从在线资源库中下载了该代码,您会看到这两者都已经被实现了。本文讨论向导,而下个月的文章将讨论构建器。

文件和项目目录

让我们从一些定义开始。对于 Eclipse 而言, 项目(project)是项目目录中文件(源文件、配置文件、已编译文件及其它文件)的集合。在 Eclipse 术语中,文件和目录都称为 资源(resource)。不要把 Eclipse 资源(文件)和 Java 资源(用于本地化的字符串)搞混了。

用户可用的项目列表组成了 工作空间(workspace)。缺省情况下项目存储在 eclipse/workspace 目录中,但是用户可以在任何地方创建项目。

用户通过 导航器(navigator)面板和项目交互,如图 1 所示。此外,插件可以提供专门的导航器。图 1 是一个通用导航器,它列出了项目中的资源(文件)。




要创建新项目,您需要一个新目录和几个由 Eclipse 管理的配置文件。注:只在工作空间中创建一个新目录还不够 - Eclipse 无法将其识别为项目。

项目性质

项目的主配置文件称为 .project (在 UNIX 文件系统中,用点来标记隐藏文件)。它包含了有关如何构建项目以及项目性质的信息。

性质(nature)是项目类型的标识。例如,Java 项目具有 Java 性质。Eclipse 使用项目性质来控制与用户的交互。性质可以启用或禁用菜单项,因此具有 Java 性质的项目在菜单中含有特定于 Java 的项。

一个项目可以有多个性质。例如,插件项目既是 Java 项目(毕竟,插件是用 Java 语言编写的)又是插件项目。实际上,它具有这两种菜单项。

和其它 Eclipse 标识一样,性质标识从域名的倒序开始,这和包名没什么不同。例如,Java 性质标识是 org.eclipse.jdt.core.javanature 。注意别把该标识和类/包名搞混了。请参考 参考资料一节中的“Use Eclipse to build a user interface for XM”以获取有关标识的更多详细信息。

由于了解了这一点,所以我意识到正是项目的性质使空的 .xmp 文件(在前一篇专栏文章中做过介绍)变得多余了。如果我为 XM 项目定义特定性质,那么就有可能将 Integrating XM and Eclipse中所介绍的 Run XM菜单项与那些项目进行关联。

我将 org.ananas.xm.eclipse.xmnature 定义为 XM 的项目性质。清单 1 说明我是如何更改清单文件( plugin.xml )以反映这一点的。


清单 1. 新扩展点
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>





       
        






     
      
</td></tr></table>

如果将清单 1 和早先发布的代码作个比较,您会看到下列变化:


<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

新建 XM 项目向导

显然清单 1 中的清单文件只在项目已被声明为 XM 性质时才工作。通用向导创建的项目不带性质。因此要测试 清单 1中的代码,我首先得提供 XM 项目向导。

Eclipse 向导

Eclipse 的可扩展性是令人难以置信的,这一点在它如何处理向导中得到了体现。利用 Eclipse,有好几个插件可以用于向导。项目向导利用了这一特性。

当用户在菜单中选择 New Project时,就会显示如图 2 所示的向导。用户选择要创建的项目类型。尽管 XM 出现在列表中,但是 XM 插件还没有装入。该列表是根据清单文件( plugin.xml )填充的。




然而,在如图 3 所示的下一屏中,插件已经被装入并且控制了屏幕。这个转变对于用户来说是非常平滑的:向导没有任何闪动或更改。实际上,除非用户编写了插件,否则他可能永远都不会意识到已经装入了新插件。




为完成这一透明集成,Eclipse 将向导分成三组对象:

XM 实现

XM 用 NewXMProjectWizard 类实现向导。该类实现 INewWizard 接口。实际上,最简便的解决方案是从 Wizard 派生,因为该类是由 INewWizard 所定义的大多数方法的缺省实现。

往往在清单文件中将 NewXMProjectWizard 注册为扩展点。清单 2 是来自清单文件的有关摘录。请注意它为向导声明了类别。该类别组合了几个 XM 向导。


清单 2. 向导扩展点
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>




project="true"
id="org.ananas.xm.eclipse.newproject">
Create an XM project.



     
      
</td></tr></table>

wizard 是向导中的新标记,但是它与前一篇专栏文章中所介绍的 view 非常相似,因此熟悉它应该很容易。唯一的新东西是 project 属性:设置成 true 时,它会把向导添加到新项目列表中。若没有这个属性,则向导列入“Other”类别。

装入插件后,容器调用 init()NewXMProjectWizard 需要进行少量的初始化工作。首先它调用 setNeedsProgressMonitor() 来请求进度条。创建项目时,它让进度条逐渐变满,如清单 3 所示。


清单 3. init() 方法
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>


public void init(IWorkbench workbench,
IStructuredSelection selection)
{
setNeedsProgressMonitor(true);
}
</td></tr></table>

接下来,容器调用如清单 4 所示的 addPages() 。该方法注册向导页面。 NewXMProjectWizard 只需一个提示输入项目名和位置的页面。Eclipse 用类 WizardNewProjectCreationPage 方便地提供了这样一个页面(您可以在 图 2中看到该页面)。


清单 4. addPages() 方法
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>


public void addPages()
{
super.addPages();
namePage = new WizardNewProjectCreationPage("NewXMProjectWizard");
namePage.setTitle(Resources.getString("eclipse.newprojectname"));
namePage.setDescription(Resources.getString("eclipse.newprojectdescription"));
namePage.setImageDescriptor(ImageDescriptor.createFromFile(getClass(),
"/org/ananas/xm/eclipse/resources/newproject58.gif"));

       
        addPage(namePage);
}

     
      
</td></tr></table>

向导为其所注册的每个页面都调用 addPage() 。在本案例中,只有一个页面。

用户单击 Finish

当用户单击 Finish时, performFinish() 方法开始执行。清单 5 是该方法内容。该方法中并没有多少操作。 createProject() 中包含了创建项目的代码块, performFinish() 间接调用它。


清单 5. performFinish() 方法
<table bgcolor="#eeeeee" width="100%" cellpadding="5" cellspacing="0" border="1"><tr><td>


public boolean performFinish()
{
try
{
WorkspaceModifyOperation op =
new WorkspaceModifyOperation()
{
protected void execute(IProgressMonitor monitor)
{
createProject(monitor != null ?
monitor : new NullProgressMonitor());
}
});
getContainer().run(false,true,op);
}
catch(InvocationTargetException x)
{
reportError(x);
return false;
}
catch(InterruptedException x)
{
reportError(x);
return false;
}
return true;
}
</td></tr></table>

创建项目会更改工作空间,因为它添加了目录和文件。在整个更改过程中,向导都会与工作空间保持同步。最简便的解决方案就是用 WorkspaceModifyOperation 的子代执行项目创建。

更改工作空间的代码必须从 execute() 方法进行调用。在 清单 5中,它只调用 createProject()execute()IProgressMonitor 作为参数。如果项目创建要花一些时间,那么向导会通过该参数报告其进度。容器用它来更新进度条。

IProgressMonitor 中最有用的方法是:

项目创建和进度的长度是用工作单元进行报告的。定义单元所表示的内容则由您来决定。例如,处理文件时,每个单元就可以是一个文件。

要执行线程,请调用容器中的 run() 方法。该容器使自己的进度条与 IProgressMonitor 保持同步。

项目创建

真正的项目创建在 createProject() 中进行(请参阅 清单 6)。次序在该方法中非常重要:如果您的代码不按照正确的次序运行,则向导会失败(通常给出令人迷惑的错误消息)。

要创建新项目,请遵循以下这些步骤:

  1. 检索作为 IWorkspaceRoot 的实例的工作空间根。Eclipse 提供了一个便捷的插件( ResourcesPlugin ),通过该插件您可以访问包括工作空间在内的资源。再强调一次,这些是 Eclipse 资源,比如文件和目录。
  2. IWorkspaceRoot 上调用 getProject() (我个人认为该方法本应被称为 newProject() ,因为它创建了项目)。
  3. newProjectDescription() 方法创建一个空的项目描述。项目描述包含了有关项目的特定类型的信息,包括它在文件系统上的位置。
  4. 如果用户选择缺省位置(位于工作空间目录下),请转到 下一步。否则,请在描述对象上设置位置。出于一些原因,如果您将项目位置显式地设置成它的缺省值,那么项目创建就会失败。
  5. 注册项目性质(如果有的话)。这是一组字符串标识。
  6. 注册项目构建器(或编译器)。虽然我将在下一篇文章中才对此进行讨论,但是 XM 现在就可以用作构建器。
  7. create() 方法创建项目。
  8. 最后,打开新创建的项目。

一旦您创建并打开该项目,您就可以设置它的特性。它们用 Eclipse 特性进行存储。正如您在 清单 6中所看到的那样,向导为 XM 构建器设置了一些特性。您应当熟悉那些特性,因为它们与“ Integrating XM and Eclipse”中所介绍的 .xmp 文件一样。

除了上述之外,向导用缺省目录(通常是 srcrulespublish )、样本 XML 文档和简单的样式表填充该项目。这就为用户提供了方便。


<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

计划中

如果您从在线资源库(请参阅 参考资料)下载了源代码,您会发现插件也提供了一个构建器。该构建器就是我下篇专栏文章的主题。

本文演示了 Eclipse 给予作为插件开发人员的您以极大的自由来控制用户的操作过程。因此,您的插件几乎可以扩展用户界面的任何方面。


<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>


<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>

关于作者<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td colspan="3"></td></tr><tr align="left" valign="top"><td></td><td></td><td width="100%">

Beno?t Marchal 是住在比利时那幕尔的顾问和作家。他是 XML by Example 一书的作者,他还撰写了其它 XML 书籍,这些书籍讨论了 XML 标准的最新特性,包括最终的 XML Schema 建议书和最新的 XSL 开发。可以在 www.marchal.com上获取更多的详细信息。可以通过 bmarchal@pineapplesoft.com与 Beno?t 联系。

</td></tr></table>

<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td>
</td></tr></table><table class="no-print" cellspacing="0" cellpadding="0" align="right"><tr align="right"><td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td valign="middle">
</td><td valign="top" align="right"></td></tr></table></td></tr></table>


↑返回目录
前一篇: 使用 XML: Eclipse 中的布局、属性和首选项
后一篇: 使用 XML: 使用 XML:集成 XM 和 Eclipse