在第一步完成后,我从pde的向导代码入手看eclipse生成代码的机制,发现经过一些小改造,其实完全可以脱离向导的实现,因为在向导中,eclipse保存一些信息作为创建插件工程的必须项。
有兴趣的话可以看看eclipse的最终实现类:NewProjectCreationOperation,最终调用这类的execute(IProgressMonitor monitor)方法。
经过改造后的类如下:
import java.util.ArrayList;import java.util.Set;import java.util.TreeSet;import org.eclipse.core.resources.ICommand;import org.eclipse.core.resources.IFile;import org.eclipse.core.resources.IFolder;import org.eclipse.core.resources.IProject;import org.eclipse.core.resources.IProjectDescription;import org.eclipse.core.resources.IResource;import org.eclipse.core.resources.IWorkspace;import org.eclipse.core.resources.IWorkspaceRoot;import org.eclipse.core.resources.ResourcesPlugin;import org.eclipse.core.runtime.CoreException;import org.eclipse.core.runtime.IPath;import org.eclipse.core.runtime.NullProgressMonitor;import org.eclipse.core.runtime.Path;import org.eclipse.core.runtime.SubProgressMonitor;import org.eclipse.jdt.core.IClasspathEntry;import org.eclipse.jdt.core.IJavaElement;import org.eclipse.jdt.core.IJavaProject;import org.eclipse.jdt.core.IPackageFragment;import org.eclipse.jdt.core.IPackageFragmentRoot;import org.eclipse.jdt.core.JavaCore;import org.eclipse.jdt.core.JavaModelException;import org.eclipse.pde.core.build.IBuildEntry;import org.eclipse.pde.core.build.IBuildModelFactory;import org.eclipse.pde.core.plugin.IPlugin;import org.eclipse.pde.core.plugin.IPluginBase;import org.eclipse.pde.core.plugin.IPluginImport;import org.eclipse.pde.core.plugin.IPluginLibrary;import org.eclipse.pde.core.plugin.IPluginReference;import org.eclipse.pde.internal.core.ClasspathComputer;import org.eclipse.pde.internal.core.TargetPlatformHelper;import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;import org.eclipse.pde.internal.core.bundle.BundlePluginBase;import org.eclipse.pde.internal.core.bundle.WorkspaceBundlePluginModel;import org.eclipse.pde.internal.core.ibundle.IBundle;import org.eclipse.pde.internal.core.ibundle.IBundlePluginBase;import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;import org.eclipse.pde.internal.core.natures.PDE;import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase;import org.eclipse.pde.internal.core.project.PDEProject;import org.eclipse.pde.internal.core.util.CoreUtility;import org.osgi.framework.Constants;/** * 创建插件工程 * * @author aquarion * @version 1.0 * */@SuppressWarnings("restriction")public class CreatePluginProject { private static WorkspacePluginModelBase fModel; private static PluginClassCodeGenerator fGenerator; public static void createPluginProject(String projectName) { // 获取工作区 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); // 创建新项目 IProject project = root.getProject(projectName); // 设置工程的位置 // IPath path = new Path(""); // 为项目指定存放路径,默认放在当前工作区 IWorkspace workspace = root.getWorkspace(); final IProjectDescription description = workspace .newProjectDescription(project.getName()); description.setLocation(null); // 设置工程标记,即为java工程 String[] newJavaNature = new String[1]; newJavaNature[0] = JavaCore.NATURE_ID; // 这个标记证明本工程是Java工程 description.setNatureIds(newJavaNature); // 在文件系统中生成工程 try { NullProgressMonitor monitor = new NullProgressMonitor(); project.create(description, monitor); project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor( monitor, 1000)); } catch (CoreException e) { e.printStackTrace(); } // 转化成java工程 IJavaProject javaProject = JavaCore.create(project); // 创建输出路径 IFolder binFolder = javaProject.getProject().getFolder("bin"); try { binFolder.create(true, true, null); javaProject.setOutputLocation(binFolder.getFullPath(), null); } catch (CoreException e) { e.printStackTrace(); } // 设置Java生成器 try { IProjectDescription description2 = javaProject.getProject() .getDescription(); ICommand command = description2.newCommand(); command.setBuilderName("org.eclipse.jdt.core.javabuilder"); description2.setBuildSpec(new ICommand[] { command }); description2 .setNatureIds(new String[] { "org.eclipse.jdt.core.javanature" }); javaProject.getProject().setDescription(description2, null); } catch (CoreException e) { e.printStackTrace(); } // 创建源代码文件夹 IFolder srcFolder = javaProject.getProject().getFolder("src"); try { srcFolder.create(true, true, null); } catch (CoreException e) { e.printStackTrace(); } // 验证并加入插件工程的Nature try { project = createProject(project); } catch (CoreException e1) { e1.printStackTrace(); } // 为一个java工程设置默认的class path try { if (project.hasNature(JavaCore.NATURE_ID)) { setClasspath(project); } } catch (JavaModelException e) { e.printStackTrace(); } catch (CoreException e) { e.printStackTrace(); } // 生成Activator类 try { generateTopLevelPluginClass(project, projectName + ".Activator", projectName); } catch (CoreException e) { e.printStackTrace(); } // 生成mf文件 try { createManifest(project, projectName); } catch (CoreException e) { e.printStackTrace(); } // 生成bulid.properties文件 try { createBuildPropertiesFile(project); } catch (CoreException e) { e.printStackTrace(); } // 调整mf文件 try { adjustManifests(project, fModel.getPluginBase()); } catch (CoreException e) { e.printStackTrace(); } // 最终保存到文件系统中 fModel.save(); } /** * 创建工程 * * @param project * @return * @throws CoreException */ private static IProject createProject(IProject project) throws CoreException { if (!project.exists()) { CoreUtility.createProject(project, null, null); project.open(null); } if (!project.hasNature(PDE.PLUGIN_NATURE)) { CoreUtility.addNatureToProject(project, PDE.PLUGIN_NATURE, null); } if (!project.hasNature(JavaCore.NATURE_ID)) { CoreUtility.addNatureToProject(project, JavaCore.NATURE_ID, null); } CoreUtility.addNatureToProject(project, "org.eclipse.pde.UpdateSiteNature", null); CoreUtility.addNatureToProject(project, "org.eclipse.pde.FeatureNature", null); CoreUtility.addNatureToProject(project, "org.eclipse.pde.api.tools.apiAnalysisNature", null); IFolder folder = project.getFolder("src"); if (!folder.exists()) { CoreUtility.createFolder(folder); } return project; } /** * 设置class path * * @param project * @throws JavaModelException * @throws CoreException */ private static void setClasspath(IProject project) throws JavaModelException, CoreException { IJavaProject javaProject = JavaCore.create(project); // Set output folder IPath path = project.getFullPath().append("bin"); javaProject.setOutputLocation(path, null); IClasspathEntry[] entries = getClassPathEntries(javaProject); javaProject.setRawClasspath(entries, null); } private static IClasspathEntry[] getClassPathEntries(IJavaProject project) { IClasspathEntry[] internalClassPathEntries = getInternalClassPathEntries(project); IClasspathEntry[] entries = new IClasspathEntry[internalClassPathEntries.length + 2]; System.arraycopy(internalClassPathEntries, 0, entries, 2, internalClassPathEntries.length); // Set EE of new project String executionEnvironment = "JavaSE-1.6"; ClasspathComputer.setComplianceOptions(project, executionEnvironment); entries[0] = ClasspathComputer.createJREEntry(executionEnvironment); entries[1] = ClasspathComputer.createContainerEntry(); return entries; } private static IClasspathEntry[] getInternalClassPathEntries( IJavaProject project) { IClasspathEntry[] entries = new IClasspathEntry[1]; IPath path = project.getProject().getFullPath().append("src"); entries[0] = JavaCore.newSourceEntry(path); return entries; } /** * 生成Activator类 * * @param project * @param className * @param id * @throws CoreException */ private static void generateTopLevelPluginClass(IProject project, String className, String id) throws CoreException { fGenerator = new PluginClassCodeGenerator(project, className, id); fGenerator.generate(); } /** * 生成MF文件 * * @param project * @param name * @throws CoreException */ private static void createManifest(IProject project, String name) throws CoreException { IFile pluginXml = PDEProject.getPluginXml(project); IFile manifest = PDEProject.getManifest(project); fModel = new WorkspaceBundlePluginModel(manifest, pluginXml); IPluginBase pluginBase = fModel.getPluginBase(); String targetVersion = "3.7"; pluginBase.setSchemaVersion(TargetPlatformHelper .getSchemaVersionForTargetVersion(targetVersion)); pluginBase.setId(name); pluginBase.setVersion("1.0.0.qualifier"); String temp = getName(name); pluginBase.setName(temp); pluginBase.setProviderName(""); if (fModel instanceof IBundlePluginModelBase) { IBundlePluginModelBase bmodel = ((IBundlePluginModelBase) fModel); ((IBundlePluginBase) bmodel.getPluginBase()) .setTargetVersion(targetVersion); bmodel.getBundleModel().getBundle() .setHeader(Constants.BUNDLE_MANIFESTVERSION, "2"); //$NON-NLS-1$ } ((IPlugin) pluginBase).setClassName(name.toLowerCase() + ".Activator"); IPluginReference[] dependencies = getDependencies(); for (int i = 0; i < dependencies.length; i++) { IPluginReference ref = dependencies[i]; IPluginImport iimport = fModel.getPluginFactory().createImport(); iimport.setId(ref.getId()); iimport.setVersion(ref.getVersion()); iimport.setMatch(ref.getMatch()); pluginBase.add(iimport); } // add Bundle Specific fields if applicable if (pluginBase instanceof BundlePluginBase) { IBundle bundle = ((BundlePluginBase) pluginBase).getBundle(); // Set required EE String exeEnvironment = "JavaSE-1.6"; if (exeEnvironment != null) { bundle.setHeader(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT, exeEnvironment); } // ----------------------- bundle.setHeader(Constants.BUNDLE_ACTIVATIONPOLICY, Constants.ACTIVATION_LAZY); // ------------------------ } } @SuppressWarnings({ "rawtypes", "unchecked" }) private static IPluginReference[] getDependencies() { ArrayList result = new ArrayList(); if (fGenerator != null) { IPluginReference[] refs = fGenerator.getDependencies(); for (int i = 0; i < refs.length; i++) { result.add(refs[i]); } } return (IPluginReference[]) result.toArray(new IPluginReference[result .size()]); } /** * 生成Build.properties文件 * * @param project * @throws CoreException */ private static void createBuildPropertiesFile(IProject project) throws CoreException { IFile file = PDEProject.getBuildProperties(project); if (!file.exists()) { WorkspaceBuildModel model = new WorkspaceBuildModel(file); IBuildModelFactory factory = model.getFactory(); // BIN.INCLUDES IBuildEntry binEntry = factory .createEntry(IBuildEntry.BIN_INCLUDES); fillBinIncludes(project, binEntry); createSourceOutputBuildEntries(model, factory); model.getBuild().add(binEntry); model.save(); } } private static void fillBinIncludes(IProject project, IBuildEntry binEntry) throws CoreException { binEntry.addToken("META-INF/"); //$NON-NLS-1$ String libraryName = null; binEntry.addToken(libraryName == null ? "." : libraryName); //$NON-NLS-1$ } private static void createSourceOutputBuildEntries( WorkspaceBuildModel model, IBuildModelFactory factory) throws CoreException { String srcFolder = "src"; String libraryName = null; if (libraryName == null) libraryName = "."; //$NON-NLS-1$ // SOURCE.<LIBRARY_NAME> IBuildEntry entry = factory.createEntry(IBuildEntry.JAR_PREFIX + libraryName); if (srcFolder.length() > 0) entry.addToken(new Path(srcFolder).addTrailingSeparator() .toString()); else entry.addToken("."); //$NON-NLS-1$ model.getBuild().add(entry); // OUTPUT.<LIBRARY_NAME> entry = factory.createEntry(IBuildEntry.OUTPUT_PREFIX + libraryName); String outputFolder = "bin"; if (outputFolder.length() > 0) entry.addToken(new Path(outputFolder).addTrailingSeparator() .toString()); else entry.addToken("."); //$NON-NLS-1$ model.getBuild().add(entry); } /** * 调整MF文件 * * @param project * @param bundle * @throws CoreException */ @SuppressWarnings({ "rawtypes", "unchecked" }) private static void adjustManifests(IProject project, IPluginBase bundle) throws CoreException { // if libraries are exported, compute export package (173393) IPluginLibrary[] libs = fModel.getPluginBase().getLibraries(); Set packages = new TreeSet(); for (int i = 0; i < libs.length; i++) { String[] filters = libs[i].getContentFilters(); // if a library is fully exported, then export all source packages // (since we don't know which source folders go with which library) if (filters.length == 1 && filters[0].equals("**")) { //$NON-NLS-1$ addAllSourcePackages(project, packages); break; } for (int j = 0; j < filters.length; j++) { if (filters[j].endsWith(".*")) //$NON-NLS-1$ packages.add(filters[j].substring(0, filters[j].length() - 2)); } } } @SuppressWarnings("rawtypes") private static void addAllSourcePackages(IProject project, Set list) { try { IJavaProject javaProject = JavaCore.create(project); IClasspathEntry[] classpath = javaProject.getRawClasspath(); for (int i = 0; i < classpath.length; i++) { IClasspathEntry entry = classpath[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { IPath path = entry.getPath().removeFirstSegments(1); if (path.segmentCount() > 0) { IPackageFragmentRoot root = javaProject .getPackageFragmentRoot(project.getFolder(path)); IJavaElement[] children = root.getChildren(); for (int j = 0; j < children.length; j++) { IPackageFragment frag = (IPackageFragment) children[j]; if (frag.getChildren().length > 0 || frag.getNonJavaResources().length > 0) list.add(children[j].getElementName()); } } } } } catch (JavaModelException e) { } } /** * 获取Bundle-Name * * @param projectName * @return */ private static String getName(String projectName) { String temp = new String(projectName); int index = temp.lastIndexOf("."); if (index != -1) { temp = temp.substring(index + 1); } String fristChar = temp.substring(0, 1).toUpperCase(); temp = temp.substring(1); temp = fristChar + temp; return temp; }}