关于Eclipse打包机制的学习与改造记录

插件开发原因:当维护较多工程时,打jar包的时候,单个工程export很不方便,如果对eclipse的export进行扩展和改造,将需要维护的工程放在同一个工程的sourceFolder下,然后对这个工程进行export操作,改造后的操作实现,将该工程下的所有sourceFolder分别打成对应于该sourceFolder的jar包,jar包的名字根据sourceFolder来确定,这样对于代码维护人员就非常方便,一次export之后,生成所有的需要维护的工程的相应的jar包。

简单用图像演示一下操作:

工程如下:

打包选择:

(用户选择)

Finish后生成jar包:

OK下面介绍下对于export的改造和学习:

首先找到eclipse本身export的代码,org.eclipse.jdt.internal.ui.jarpacakger.JarPackageWizard.java

执行的代码放在performFinish下:

 1 @Override
2 public boolean performFinish() {
3 fJarPackage.setElements(fJarPackageWizardPage.getSelectedElementsWithoutContainedChildren());
4
5 if (!executeExportOperation(fJarPackage.createJarExportRunnable(getShell())))
6 return false;
7
8 // Save the dialog settings
9 if (fHasNewDialogSettings) {
10 IDialogSettings workbenchSettings= JavaPlugin.getDefault().getDialogSettings();
11 IDialogSettings section= workbenchSettings.getSection(DIALOG_SETTINGS_KEY);
12 section= workbenchSettings.addNewSection(DIALOG_SETTINGS_KEY);
13 setDialogSettings(section);
14 }
15 IWizardPage[] pages= getPages();
16 for (int i= 0; i < getPageCount(); i++) {
17 IWizardPage page= pages[i];
18 if (page instanceof IJarPackageWizardPage)
19 ((IJarPackageWizardPage) page).finish();
20 }
21 return true;
22 }

首先来看

fJarPackage.setElements(fJarPackageWizardPage.getSelectedElementsWithoutContainedChildren());
用来指定打包的内容;
这一句中用到的fJarPackage这个变量,变量对应的对象为:JarPackageData.java
注释可以看到:Model for a JAR package which stores information used during JAR export and import.
并没有细看这个代码但浏览一下就会知道,这里保存了打包信息,比如boolean fExportClassFiles,boolean fExportOutPutFolders,boolean
fExportJavaFiles,这些就可以看出来是保存了是否打包class文件等这些信息;
然后看一下参数:
fJarPackageWizardPage.getSelectedElementsWithoutContainedChildren()
Object[] getSelectedElementsWithoutContainedChildren() {
Set<Object> closure= removeContainedChildren(fInputGroup.getWhiteCheckedTreeItems());
closure.addAll(getExportedNonContainers());
return closure.toArray();
}

想要实现所要的功能,首先要获取工程下的所有源代码目录(sourceFolder),两个方法实现:

public Set<Object> getTdsExportFolder(){
Set<Object> whiteCheckedTreeItems= fInputGroup.getWhiteCheckedTreeItems();
Set<Object> javaSourceFolder = getCorrespondingContainersTDSFolder(whiteCheckedTreeItems); // 获取源代码包路径
return javaSourceFolder;
}

然后:

     /**
* used to get the root folder of the project
* Create a list with the folders / projects that correspond
* to the Java elements (Java project, package, package root)
*/
private Set<Object> getCorrespondingContainersTDSFolder(Set<Object> elements) {
Set<Object> javaElementResources= new HashSet<Object>(elements.size());
Iterator<Object> iter= elements.iterator();
while (iter.hasNext()) {
Object element= iter.next();
if (element instanceof IJavaElement) {
IJavaElement je= (IJavaElement)element;
int type= je.getElementType();
if (type == IJavaElement.PACKAGE_FRAGMENT_ROOT) {
// exclude default package since it is covered by the root
if (!(type == IJavaElement.PACKAGE_FRAGMENT && ((IPackageFragment)element).isDefaultPackage())) {
Object resource;
try {
resource= je.getCorrespondingResource();
} catch (JavaModelException ex) {
resource= null;
}
if (resource != null)
javaElementResources.add(resource);
}
}
}
}
return javaElementResources;
}

这样可以获取该工程下用户选择的所有sourceFolder,然后在自己的ExportWizard循环执行打包操作,看一下打包操作:

想要打个打包,那么就要对

fJarPackage.setElements(fJarPackageWizardPage.getSelectedElementsWithoutContainedChildren());这句进行修改,源代码里是对工程下的所有选择项进行打包,我们要对单个的
sourceFolder目录进行打包,那么这里就要指定不同的Elements也就是打包项;也就是要得到不同sourceFolder下的所有要打包的文件;
    /**
*
*
@param Folder
*
@return get the export elements to jar package...
* 根据sourceFolder目录参数获得该目录下所有要打包的elements
*/
public Object[] getSelectedElementsWithoutContainedChildren(Folder current) {
Set<Object> closure= removeContainedChildren(fInputGroup.getWhiteCheckedTreeItems());
Iterator<Object> iter= closure.iterator();
System.out.println(closure.size());
LinkedList<Object> list = new LinkedList<Object>();
while(iter.hasNext()) {
try{
Object obj = iter.next();
if(obj instanceof PackageFragmentRoot){
if(!((PackageFragmentRoot)obj).getResource().getName().equals(current.getName())){
list.add(obj);
}
}
System.out.println(obj);
}catch(Exception ex){
System.out.println("next...");
ex.printStackTrace();
}
}

for(int i=0; i<list.size(); i++){
if(closure.contains(list.get(i))){
closure.remove(list.get(i));
}
}
return closure.toArray();
}
这样就可以进行打包操作,将exportWizard里的performFinish操作进行改造:

 public boolean performFinish() {
Set<Object> sets = fJarPackageWizardPage.getTdsExportFolder();
Iterator<Object> iter = sets.iterator();
while(iter.hasNext()){
Folder current = (Folder)iter.next();
if (!current.getName().equals("test") && !current.getName().equals("xtend-gen")) {
fJarPackage
.setElements(fJarPackageWizardPage
.getSelectedElementsWithoutContainedChildrenTDS((Folder) current));

if (fJarPackage.getJarLocation() != null) {
System.out.println(fJarPackage.getJarLocation());
}

IPath oldPath = fJarPackage.getJarLocation();

// 如果第一次那么保存下来 , 如果不是第一次那么将内容与新内容进行对比,不同则保存
          // 这段代码用来记录打包时用户填写的路径,不同的工程保存自己相应的打包录路径,下一次打包时,路径里显示的就是该工程上一次的打包目录
try {
if(currentPro.getResource().getPersistentProperty(PROJECT_PERSISTENCE) == null){
currentPro.getResource().setPersistentProperty(PROJECT_PERSISTENCE, oldPath.toString());
} else {
String path = currentPro.getResource().getPersistentProperty(PROJECT_PERSISTENCE);
// 如果用户修改路径那么更新打包路径
if(!path.equals(fJarPackage.getJarLocation().toOSString())){
currentPro.getResource().setPersistentProperty(PROJECT_PERSISTENCE, fJarPackage.getJarLocation().toOSString());
}
}
} catch (CoreException e) {
e.printStackTrace();
}


fJarPackage.setJarLocation(new Path(fJarPackage
.getJarLocation() + "/" + current.getName() + ".jar"));
if (!executeExportOperation(fJarPackage
.createJarExportRunnable(getShell())))
return false;

fJarPackage.setJarLocation(oldPath);
}
}

// if (!executeExportOperation(fJarPackage
// .createJarExportRunnable(getShell())))
// return false;

// Save the dialog settings
if (fHasNewDialogSettings) {
IDialogSettings workbenchSettings = JavaPlugin.getDefault()
.getDialogSettings();
IDialogSettings section = workbenchSettings
.getSection(DIALOG_SETTINGS_KEY);
section = workbenchSettings
.addNewSection(DIALOG_SETTINGS_KEY);
setDialogSettings(section);
}
IWizardPage[] pages = getPages();
for (int i = 0; i < getPageCount(); i++) {
IWizardPage page = pages[i];
if (page instanceof IJarPackageWizardPage)
((IJarPackageWizardPage) page).finish();
}
return true;
}

OK,这样就实现了我们需求的功能。




posted on 2011-12-10 18:46  aquariusm  阅读(427)  评论(0)    收藏  举报

导航