org.eclipse.core.resources.natures org.eclipse.core.resources.builders扩展点介绍
builder和nature是Eclipse中提供的两个扩展点。一般来说我们都是先有自己特定的project类型,然后在这类project上加上自定义的builder和nature。
其实所谓的特定的project通常都是由特有的nature来标识的;而又一般builder是建立在某类特定的project上,所以我们可以得出:Nature决定了project和builder。
1、创建nature扩展点
<extension id="nature" name="WorkFlow Project Nature" point="org.eclipse.core.resources.natures"> <runtime> <run class="com.workflow.nature.WorkflowProjectNature"> </run> </runtime> <builder id="MyDesigner.builder"><!--builder的扩展点ID为plugin的ID加上builder扩展的ID--> </builder> </extension>2、创建builder扩展点
<extension id="builder" name="WorkFlow Project Builder" point="org.eclipse.core.resources.builders"> <builder hasNature="true" isConfigurable="false"> <run class="com.workflow.builder.ProjectBuilder"> </run> </builder> </extension>3、nature的实现类
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.runtime.CoreException; import com.workflow.builder.ProjectBuilder; import com.workflow.tool.ProjectUtil; /** * 自定义的nature实现类 * @author lww * */ public class WorkflowProjectNature implements IProjectNature { private IProject project; public static final String ID = "MyDesigner.nature";//nature的ID为plugin的ID加上nature扩展的ID /** * builder安装 */ @Override public void configure() throws CoreException { IProjectDescription description = project.getDescription(); ProjectUtil.addBuilderToProject(description, new String[] { ProjectBuilder.ID }, null); project.setDescription(description, null); } /** * builder卸载 */ @Override public void deconfigure() throws CoreException { IProjectDescription description = project.getDescription(); ProjectUtil.removeBuilderFromProject(description, new String[] { ProjectBuilder.ID }, null); project.setDescription(description, null); } @Override public IProject getProject() { return project; } @Override public void setProject(IProject project) {//在project.setDescription()的时候调用,如果那个project的description安了这个nature this.project = project; } }4、builder的实现类
import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** *自定义 builder实现类 *org.eclipse.core.resources.builders用于提供一种操作, *这种操作可以在IResource改变的时候自动去build,如同改变java文件,会自动进行build, *显示错误一样,我们扩展这个builder,并且在自己的项目中使用。我们要做的就是实现build的过程, *至于时机由eclipse控制 * @author lww * */ public class ProjectBuilder extends IncrementalProjectBuilder { private IProject project; public static final String ID = "MyDesigner.builder";// Builder的ID为plugin的ID加上Builder扩展的ID. private static final String MARKER_TYPE = "MyDesigner.xmlProblem"; private SAXParserFactory parserFactory; /** * 根据不同的build类型,来实现不同的build策略 */ @Override protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException { switch (kind) { case FULL_BUILD: fullBuild(monitor); break; default: IResourceDelta delta = getDelta(project); if (delta == null) { fullBuild(monitor); } else { incrementalBuild(delta, monitor); } break; } return null; } /** * 点击project 菜单栏中clean Action的时候执行该方法 */ @Override protected void clean(IProgressMonitor monitor) throws CoreException { super.clean(monitor); /* * remove all build files */ IFolder outputFiles = project.getFolder("Processes"); outputFiles.refreshLocal(IResource.DEPTH_INFINITE, monitor); if (outputFiles.exists()) { outputFiles.delete(true, monitor); } } /** * 调用一些初始信息,或者初始变量 */ @Override protected void startupOnInitialize() { super.startupOnInitialize(); this.project = getProject(); } /** * 添加 标识,在Markers视图中显示该错误 * @param file * @param message * @param lineNumber * @param severity */ private void addMarker(final IFile file, String message, int lineNumber, int severity) { try { IMarker marker = file.createMarker(MARKER_TYPE); marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, severity); if (lineNumber == -1) { lineNumber = 1; } marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); } catch (CoreException e) { } } /** * 检查文件后缀为.xml * @param resource */ void checkXML(IResource resource) { if (resource instanceof IFile && resource.getName().endsWith(".xml")) { IFile file = (IFile) resource; deleteMarkers(file); XMLErrorHandler reporter = new XMLErrorHandler(file); try { getParser().parse(file.getContents(), reporter); } catch (Exception e1) { } } } /** * 删除Markers * @param file */ private void deleteMarkers(IFile file) { try { file.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO); } catch (CoreException ce) { } } private SAXParser getParser() throws ParserConfigurationException, SAXException { if (parserFactory == null) { parserFactory = SAXParserFactory.newInstance(); } return parserFactory.newSAXParser(); } protected void fullBuild(final IProgressMonitor monitor) throws CoreException { try { getProject().accept(new WorkFlowResourceVisitor()); } catch (CoreException e) { } } protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { // the visitor does the work. delta.accept(new WorkFlowDeltaVisitor()); } class WorkFlowDeltaVisitor implements IResourceDeltaVisitor { @Override public boolean visit(IResourceDelta delta) throws CoreException { IResource resource = delta.getResource(); switch (delta.getKind()) { case IResourceDelta.ADDED: // handle added resource checkXML(resource); break; case IResourceDelta.REMOVED: // handle removed resource break; case IResourceDelta.CHANGED: // handle changed resource checkXML(resource); break; } // return true to continue visiting children. return true; } } class WorkFlowResourceVisitor implements IResourceVisitor { @Override public boolean visit(IResource resource) throws CoreException { checkXML(resource); return true; } } class XMLErrorHandler extends DefaultHandler { private IFile file; public XMLErrorHandler(IFile file) { this.file = file; } private void addMarker(SAXParseException e, int severity) { ProjectBuilder.this.addMarker(file, e.getMessage(), e.getLineNumber(), severity); } public void error(SAXParseException exception) throws SAXException { addMarker(exception, IMarker.SEVERITY_ERROR); } public void fatalError(SAXParseException exception) throws SAXException { addMarker(exception, IMarker.SEVERITY_ERROR); } public void warning(SAXParseException exception) throws SAXException { addMarker(exception, IMarker.SEVERITY_WARNING); } } }
5、操作类
import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; /** * project的操作类(添加nature、builder) * @author lww * */ public class ProjectUtil { /** * 添加Nature信息到Project中 * 添加Comment信息 */ public static void addNature2Project(IProjectDescription description, String[] natureIds) 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); description.setComment("It's a WorkFlow project"); } /** * 添加builder到project中 * @param description * @param builderIds * @param monitor * @throws CoreException */ 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); } /** * 移除builder从project中 * @param description * @param builderIds * @param monitor */ 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])); } }
org.eclipse.core.resources.builders用于提供一种操作,这种操作可以在IResource改变的时候自动去build,如同改变java文件,会自动进行build,显示错误一样,我们扩展这个builder,并且在自己的项目中使用。我们要做的就是实现build的过程,至于时机由eclipse控制
上面的例子就在修改文件时,验证XML文件内容格式是否存在问题,并显示在markers视图中显示,所以还要添加扩展点org.eclipse.core.resources.markers。
6、markers扩展点
<extension id="xmlProblem" name="com.workflow.xmlProblem" point="org.eclipse.core.resources.markers"> <persistent value="true"> </persistent> <super type="org.eclipse.core.resources.problemmarker"> </super> </extension>
7、创建工程
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);
创建的工程变为
.project文件中多了buildSpec和natures
当修改后缀名为.xml的文件后,保存,它就会去检查xml文件内容,若内容存在问题就在markers中显示错误信息
参考资料:http://liugang594.iteye.com/blog/261513
http://blog.csdn.net/soszou/article/details/8018032
org.eclipse.core.resources.natures org.eclipse.core.resources.builders扩展点介绍,古老的榕树,5-wow.com
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。