`

使用代码生成插件工程,脱离eclipse本身的新建工程向导(2)

 
阅读更多
    在第一步完成后,我从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;
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics