標籤:建立工程 resources.builder resources.markers resources.natures
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安裝 */@Overridepublic void configure() throws CoreException {IProjectDescription description = project.getDescription(); ProjectUtil.addBuilderToProject(description, new String[] { ProjectBuilder.ID }, null); project.setDescription(description, null); }/** * builder卸載 */@Overridepublic void deconfigure() throws CoreException {IProjectDescription description = project.getDescription(); ProjectUtil.removeBuilderFromProject(description, new String[] { ProjectBuilder.ID }, null); project.setDescription(description, null); }@Overridepublic IProject getProject() {return project;}@Overridepublic void setProject(IProject project) {//在project.setDescription()的時候調用,如果那個project的description安了這個naturethis.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策略 */@Overrideprotected 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的時候執行該方法 */@Overrideprotected 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);}}/** * 調用一些初始資訊,或者初始變數 */@Overrideprotected 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 {@Overridepublic boolean visit(IResourceDelta delta) throws CoreException {IResource resource = delta.getResource();switch (delta.getKind()) {case IResourceDelta.ADDED:// handle added resourcecheckXML(resource);break;case IResourceDelta.REMOVED:// handle removed resourcebreak;case IResourceDelta.CHANGED:// handle changed resourcecheckXML(resource);break;}// return true to continue visiting children.return true;}}class WorkFlowResourceVisitor implements IResourceVisitor {@Overridepublic 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