`

使用代码生成插件工程,脱离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;
	}
}
分享到:
评论

相关推荐

    Eclipse代码生成器插件开发

    在本节中,我们探讨了Eclipse代码生成器插件开发的相关知识点,包括插件开发基本概念、Wizard向导制作、plugin.xml文件、Wizard类、新建项目向导和自定义Wizard页面等。这些知识点对于开发Eclipse插件非常重要,了解...

    java工程脱离eclipse运行

    Java工程脱离Eclipse运行是指将Java工程从Eclipse中独立出来,生成一个可以独立运行的JAR包。下面是实现这一过程的详细步骤: 1. 选择要导出的项目,右键点击选择“导出” 2. 在弹出的框中选中“jar 文件” 3. 选择...

    eclipse代码行数统计插件

    在Eclipse中,安装和使用代码行数统计插件非常简单。首先,用户需要打开"Windows"菜单,然后选择"Show View",接着在弹出的子菜单中找到"Other"选项。在"Other"对话框中,你可以搜索与代码统计相关的插件,比如"PMD...

    mybatis-generator eclipse自动生成代码插件离线安装包

    Eclipse是广受欢迎的Java集成开发环境,而`mybatis-generator eclipse自动生成代码插件离线安装包`则是为了让开发者在没有网络连接的情况下也能在Eclipse中安装并使用MBG。 安装MBG插件的过程分为以下几个步骤: 1...

    统计代码行数的Eclipse插件

    2. 配置插件:安装完成后,可能需要在Eclipse的首选项设置中配置插件,如选择统计范围(工程、工作区或特定文件)以及是否包含注释。 3. 运行统计:在选定的范围内右键点击,选择插件提供的菜单项,比如"统计代码...

    eclipse android 代码生成插件源码

    通过学习这个插件的源码,开发者不仅可以提高自己的编程效率,还能深入理解Android插件开发,包括Eclipse插件API的使用、XML解析、代码生成等技术。这对于提升个人技能和理解Android生态系统的底层机制有着积极的...

    mybatis自动生成代码 eclipse插件

    MyBatis Generator(MBG)是一款强大的Eclipse插件,专为简化数据库操作而设计,它能够自动根据数据库表结构生成Java实体类、Mapper接口及XML配置文件等,极大地提升了开发效率。在Java Web开发中,MyBatis ...

    eclipse插件生成ssh框架

    eclipse插件生成ssh框架和ssi框架

    eclipse的mybatis逆向工程生成插件

    标题中的"eclipse的mybatis逆向工程生成插件"指的是将Mybatis Generator集成到Eclipse中,以方便开发者快速生成基于数据库表结构的Java代码。逆向工程通常是指从现有数据库结构出发,自动生成与之对应的源代码,使得...

    Eclipse插件之UML反向类图生成工具

    2. 找到并选择适合的UML反向工程插件,如“GenMyModel”、“Eclipse UML2 Tools”等。 3. 按照提示进行安装,可能需要重启Eclipse以使插件生效。 4. 安装完成后,可以在Eclipse的“Package Explorer”或“Project ...

    eclipse插件mybatis逆向生成插件MyBatis Generator

    它极大地简化了基于MyBatis框架的数据访问层(DAO)代码编写工作,通过数据库表反向工程实现代码自动化生成。这款插件适用于集成到Eclipse或MyEclipse环境中,帮助开发者快速构建项目。 首先,让我们深入了解一下...

    myBatis代码生成eclipse插件

    单独jar包,myBatis代码生成eclipse插件,拷贝到eclipse的dropins文件夹

    Eclipse代码生成器

    基于Eclipse的RCP插件开发,集成MyBatis的插件代码生成功能,另外使用Freemarker来生成代码,插件绝对原创,目前市面上没有.本人还没公开发布.所以好不好使用了才知道,10分不高.后续会发布的github上.并提供源代码.谢谢...

    axis2 eclipse插件代码生成器(包含客户端,服务端)

    axis2 eclipse插件代码生成器(包含客户端,服务端)axis2-eclipse-codegen-plugin-1.6.2.zip axis2-eclipse-service-plugin-1.6.2.zip

    axis2支持webservice 自动生成代码客户端服务端代码插件

    标题提及的“axis2支持webservice 自动生成代码客户端服务端代码插件”,是指Apache Axis2为Eclipse IDE提供的一套工具,旨在简化Web服务的开发流程。这个插件允许开发者通过WSDL(Web Services Description ...

    基于Eclipse插件的简易代码生成工具 毕业设计 论文

    《基于Eclipse插件的简易代码生成工具》是一篇毕业设计论文,主要探讨了如何利用Eclipse平台开发一款能够自动生成代码的插件。在软件开发过程中,编码工作占据了大量时间,尤其对于重复性高的代码段,手动编写既耗时...

    eclipse axis2插件安装

    使用 Eclipse 创建一个新的 Java 工程,Axis2 插件可以帮助我们生成 .aar 文件。生成成功后,我们可以发布服务了。 四、根据 Java 代码生成 WSDL 文件 使用 Eclipse 的 Axis2 插件,我们可以根据 Java 代码生成 ...

    mybatis-eclipse插件及生成代码说明

    mybatis-eclipse插件及生成代码说明 包含mybatis-eclipse插件、插件的安装说明以及通过一个简单的实例描述如何在eclipse中使用mybatis-eclipse插件自动生成Mybatis相关的model、dao、Mapping等文件。 详见:...

Global site tag (gtag.js) - Google Analytics