使用代码生成插件工程,脱离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;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值