`
liugang594
  • 浏览: 978135 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Eclipse中的Builder与Nature

阅读更多

builder和nature是Eclipse中提供的两个扩展点。一般来说我们都是先有自己特定的project类型,然后在这类project上加上自定义的builder和nature。

 

其实所谓的特定的project通常都是由特有的nature来标识的;而又一般builder是建立在某类特定的project上,所以我们可以得出:Nature决定了project和builder。

 

下面简单介绍一下它们的使用。

 

一、扩展Nature

 

首先定义nature的扩展,如下:

   <extension
         id="nature"
         point="org.eclipse.core.resources.natures">
      <runtime>
         <run
               class="com.tibco.cdc.liugang.npb.LiugangProjectNature">
         </run>
      </runtime>
   </extension>

 

除此之处,nature还有一些其他的约束属性,具体的可以参见帮助。 

 

LiugangProjectNature的实现如下:

 

public class LiugangProjectNature implements IProjectNature {

	private IProject project;
	public static final String ID = "com.tibco.cdc.liugang.npb.nature";

	public void configure() throws CoreException {
	}

	public void deconfigure() throws CoreException {
	}

	public IProject getProject() {
		return project;
	}

	public void setProject(IProject project) {
		this.project = project;
	}
}

 

注意:nature的ID为plugin的ID加上nature扩展的ID. 

 

方法说明:

  • setProject()会在project.setDescription()的时候调用,如果那个project的description安了这个nature
  • configure()和deconfigure()方法会在nature安上和卸掉的时候调用,一会我们可以看到builder在其中是怎么用的。
  • setProject()和configure()的调用顺序是先调setProject()后调configure().

二、生成Project

 

有了nature,下面就可以创建一个project,并把这个nature加到这个project上,如下 :

 

			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IWorkspaceRoot root = workspace.getRoot();
			
			String projectName = "TestNPB";
			IProject project = root.getProject(projectName);
			if (!project.exists()) {
				project.create(null);
				project.open(null);
			}
			IProjectDescription description = project.getDescription();
			ProjectUtil.addNature2Project(description, new String[]{LiugangProjectNature.ID}, null);
			project.setDescription(description, null);

 

这里,我写了一个通用类来处理nature,builder的增加和删除,我们先看这个addNature2Project()方法:

	public static void addNature2Project(IProjectDescription description, String[] natureIds,
			IProgressMonitor monitor) throws CoreException {
		String[] prevNatures = description.getNatureIds();
		String[] newNatures = new String[prevNatures.length + natureIds.length];
		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
		for(int i = prevNatures.length;i<newNatures.length;i++){
			newNatures[i] = natureIds[i-prevNatures.length];
		}
		description.setNatureIds(newNatures);
	}

 

 

三、定义Builder

 

按最初我们说的,builder一般安装在具有某种特定nature的project上。这里我们定义一个builder的扩展,然后再修改一下nature的扩展。分别如下:

Nature:

<extension
         id="nature"
         point="org.eclipse.core.resources.natures">
      <runtime>
         <run
               class="com.tibco.cdc.liugang.npb.LiugangProjectNature">
         </run>
      </runtime>
      <builder
            id="com.tibco.cdc.liugang.npb.builder">
      </builder>
   </extension>

 Builder:

<extension
      id="builder"
      point="org.eclipse.core.resources.builders">
   <builder
         callOnEmptyDelta="true"
         hasNature="true"
         isConfigurable="false">
      <run
            class="com.tibco.cdc.liugang.npb.LiugangIncrementalProjectBuilder">
      </run>
   </builder>
</extension>

 

回到代码,这里假设builder由nature控制。所以builder的安装与卸载分别在nature的configure()方法和deconfigure()方法中实现,如下:

 

	public void configure() throws CoreException {
		IProjectDescription description = project.getDescription();
		ProjectUtil.addBuilderToProject(description,
				new String[] { LiugangIncrementalProjectBuilder.ID }, null);
		project.setDescription(description, null);
	}

	public void deconfigure() throws CoreException {
		IProjectDescription description = project.getDescription();
		ProjectUtil.removeBuilderFromProject(description,
				new String[] { LiugangIncrementalProjectBuilder.ID }, null);
		project.setDescription(description, null);
	}

 

 

其中ProjectUtil中的实现如下:

	public static void addBuilderToProject(IProjectDescription description,
			String[] builderIds, IProgressMonitor monitor) throws CoreException {
		ICommand[] buildSpec = description.getBuildSpec();
		ICommand[] newBuilders = new ICommand[buildSpec.length
				+ builderIds.length];
		System.arraycopy(buildSpec, 0, newBuilders, 0, buildSpec.length);
		for (int i = buildSpec.length; i < newBuilders.length; i++) {
			ICommand command = description.newCommand();
			command.setBuilderName(builderIds[i - buildSpec.length]);
			newBuilders[i] = command;
		}
		description.setBuildSpec(newBuilders);
	}

	public static void removeBuilderFromProject(
			IProjectDescription description, String[] builderIds,
			IProgressMonitor monitor) {
		ICommand[] buildSpec = description.getBuildSpec();
		List<ICommand> newBuilders = new ArrayList<ICommand>();
		for (ICommand command : buildSpec) {
			boolean find = false;
			for (String id : builderIds) {
				if (command.getBuilderName().equals(id)) {
					find = true;
					break;
				}
			}
			if (!find) {
				newBuilders.add(command);
			}
		}
		description.setBuildSpec(newBuilders.toArray(new ICommand[0]));
	}

 

这样完成了nature和builder的增加。最后,我们稍稍看一下builder的实现。

 

四、builder的实现

 

对于builder的实现来说,我们通常关心以下几个方法:

public class LiugangIncrementalProjectBuilder extends IncrementalProjectBuilder {

	public static final String ID = "com.tibco.cdc.liugang.npb.builder";
	
	public LiugangIncrementalProjectBuilder() {
	}

	@Override
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
			throws CoreException {
		return null;
	}

	@Override
	protected void clean(IProgressMonitor monitor) throws CoreException {
		super.clean(monitor);
	}

	@Override
	protected void startupOnInitialize() {
		super.startupOnInitialize();
	}

}

 

 

build()方法中,一般会根据不同的build类型,来实现不同的build策略,例如:

	@Override
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
			throws CoreException {

		switch (kind) {
		case FULL_BUILD:
			processFullBuild(monitor);
			break;

		default:
			IResourceDelta delta = getDelta(project);
			if (delta == null) {
				processFullBuild(monitor);
			} else {
				processIncrementalBuild(delta, monitor);
			}
			break;
		}

		return null;
	}

 

clean()方法,在clean动作执行时被调用,通常用于清理之前build的信息,然后build()方法会被调用。clean()方法通常可以如下实现:

	@Override
	protected void clean(IProgressMonitor monitor) throws CoreException {
		super.clean(monitor);

		/*
		 * remove all build files
		 */
		IFolder outputFiles = project.getFolder(FILES_OUTPUT_PATH);
		outputFiles .refreshLocal(IResource.DEPTH_INFINITE, monitor);
		if (outputFiles .exists()) {
			outputFiles .delete(true, monitor);
		}
	}

 

 startupOnInitialize()可以调用一些初始信息,或者初始变量,例如上面用到的project变量就可以如下:

	@Override
	protected void startupOnInitialize() {
		super.startupOnInitialize();
		this.project = getProject();
	}

 

这样,一个完整的nature,builder的添加处理过程就实现了。 

分享到:
评论
1 楼 china_volcano 2013-07-08  
请问:怎么创建一个web工程?

相关推荐

Global site tag (gtag.js) - Google Analytics