溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

發(fā)布時(shí)間:2021-11-20 17:00:59 來源:億速云 閱讀:128 作者:柒染 欄目:編程語言

這篇文章給大家介紹Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

Java項(xiàng)目模型

Eclipse的項(xiàng)目有很多種,包括Java項(xiàng)目、C++項(xiàng)目、C#項(xiàng)目等,每種項(xiàng)目都有自己的特點(diǎn)。我們最常接觸到的項(xiàng)目就是Java項(xiàng)目,因此我們重點(diǎn)來講解一下Java項(xiàng)目模型。

Java模型是用來對(duì)與創(chuàng)建、編輯和構(gòu)建Java程序相關(guān)聯(lián)的對(duì)象進(jìn)行建模的一些類。Java模型類是在org.eclipse.jdt.core中定義的。這些類實(shí)現(xiàn)資源的特定于Java的行為,并進(jìn)一步將Java資源分解成模型元素。

Java模型的繼承結(jié)構(gòu)圖如圖3.13所示。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.13  Java模型的繼承結(jié)構(gòu)圖

IJavaElement的子類接口還有IMethod、IType等,在這里沒有全部列出。Java模型中的類結(jié)構(gòu)比較簡(jiǎn)單,級(jí)次也非常少。

下面介紹一下各個(gè)接口的主要方法。

(1)   IJavaElement

exists:判斷元素是否存在。處理Java元素與處理資源對(duì)象相似。當(dāng)使用Java元素時(shí),實(shí)際上是在使用某些底層的模型對(duì)象的句柄。必須使用exists()來確定元素是否真正存在于工作空間中。

getElementName:返回元素的名稱。

getJavaModel:返回其對(duì)應(yīng)的JavaModel,返回值類型是IJavaModel。

getJavaProject:返回元素對(duì)應(yīng)的Java工程,返回值類型是IJavaProject。

getParent:返回父元素,返回值類型是IJavaElement。

getResource:返回元素對(duì)應(yīng)的資源,返回值類型是IResource。

(2)   IClassFile

此接口代表編譯后的class二進(jìn)制文件。

isClass:判斷是否是Java類。

isInterface:判斷是否是接口。

(3)   ICompilationUnit

此接口代表Java源文件。

getAllTypes:返回此文件中定義的所有類型,返回值類型是IType[]。一個(gè)Java文件中可以定義多個(gè)類型。

getPrimary:返回主類型,返回值類型是ICompilationUnit。

(4)   IJavaModel

此接口表示根 Java 元素,對(duì)應(yīng)于工作空間。是所有具有 Java 性質(zhì)的項(xiàng)目的父類。它對(duì)于Java項(xiàng)目的作用和IWorkspaceRoot對(duì)于IProject的作用相似。

contains:判斷是否存在指定的資源。

getJavaProject:返回指定名字的Java項(xiàng)目,返回值類型是IJavaProject。

getJavaProjects:返回所有的Java項(xiàng)目,返回值類型是IJavaProject[]。

getWorkspace:返回所在的工作空間。

(5)   IJavaProject

此接口表示Java項(xiàng)目。

IJavaElement findElement(IPath path):返回項(xiàng)目的path路徑下的Java元素。

IPackageFragment findPackageFragment(IPath path):返回項(xiàng)目的path路徑下的IPackageFragment。

IPackageFragmentRoot findPackageFragmentRoot(IPath path):返回項(xiàng)目的path路徑下的IPackageFragmentRoot。

findType:根據(jù)一個(gè)全名取得此元素的類型,此類有數(shù)個(gè)重載方法,返回值類型為IType。

getAllPackageFragmentRoots:返回所有的IPackageFragmentRoot,返回值類型是IPackageFragmentRoot[]。

getOutputLocation:返回輸出路徑,返回值類型是IPath。

getRequiredProjectNames:返回依賴項(xiàng)目,返回值類型是字符串?dāng)?shù)組。

setOutputLocation:設(shè)定輸出路徑。

(6)   IPackageFragment

此接口表示整個(gè)包或者包的一部分。

createCompilationUnit:創(chuàng)建一個(gè)ICompilationUnit,返回值類型是ICompilationUnit。

getClassFile:返回指定名稱對(duì)應(yīng)的IClassFile,返回值類型是IClassFile。

getClassFiles:返回所有的IClassFile,返回值類型是IClassFile[]。

getCompilationUnit:返回指定名稱對(duì)應(yīng)的ICompilationUnit,返回值類型是ICompilationUnit。

getCompilationUnits:返回所有ICompilationUnit,返回值類型是ICompilationUnit[]。

getKind:判斷此包是源碼包還是普通包,返回值是int型,如等于IPackage- FragmentRoot.K_SOURCE則是源文件包,如等于IPackageFragmentRoot.K_BINARY則為普通包。

hasSubpackages:是否有子包。

(7)   IPackageFragmentRoot

此接口表示一組包段,并將各段映射至底層資源,它可以是文件夾、JAR或ZIP文件。

createPackageFragment:創(chuàng)建一個(gè)IPackageFragment,返回值類型是IPackage- Fragment。

getKind:此包段是源碼包段還是二進(jìn)制包段,返回值類型是int,如果等于IPackageFragmentRoot.K_SOURCE則是源文件包段,如果等于IPackageFragment- Root.K_BINARY則為二進(jìn)制包段。

getPackageFragment:根據(jù)包名返回對(duì)應(yīng)的IPackageFragment。

常用工具類

(1)   JavaCore(定義在org.eclipse.jdt.core包下)

JavaCore從Plugin繼承,它是JDT插件的生命周期管理器。不過對(duì)于第三方插件開發(fā)人員來說,它的重要性更多地體現(xiàn)在它提供的一些工具類方法中。

IJavaElement create(IFile file):從文件創(chuàng)建對(duì)應(yīng)的Java元素。

IJavaElement create(IFolder folder):從文件夾創(chuàng)建對(duì)應(yīng)的Java元素。

IJavaProject create(IProject project):得到IProject對(duì)應(yīng)的IJavaProject。

IJavaElement create(IResource resource):從資源創(chuàng)建對(duì)應(yīng)的Java元素。

IJavaModel create(IWorkspaceRoot root):從工作空間根目錄得到對(duì)應(yīng)的IJavaModel。

IClassFile createClassFileFrom(IFile file):從文件創(chuàng)建對(duì)應(yīng)的IClassFile。

ICompilationUnit createCompilationUnitFrom(IFile file):從文件創(chuàng)建對(duì)應(yīng)的ICompilationUnit。

(2)   JavaUI(定義在org.eclipse.jdt.ui包下)

JavaUI中定義了常用的Java插件界面相關(guān)的方法。

createPackageDialog:創(chuàng)建一個(gè)包選擇對(duì)話框,返回值是SelectionDialog。

createTypeDialog:創(chuàng)建一個(gè)類型選擇對(duì)話框,返回值是SelectionDialog。

IEditorPart openInEditor(IJavaElement element):用編輯器打開指定的Java元素并返回編輯器實(shí)例。

revealInEditor(IEditorPart part, IJavaElement element):在編輯器中定位元素element。

插件開發(fā)中經(jīng)常會(huì)碰到一些常用的技巧,掌握這些技巧可以極大地提高插件的開發(fā)效率,并且可以減小插件的體積。下面列出一些常見的技巧。

(1)   由一個(gè)普通項(xiàng)目得到Java項(xiàng)目

Java項(xiàng)目是一種特殊的項(xiàng)目,需要注意的是IJavaProject并不是從IProject繼承的。不能將一個(gè)IProject對(duì)象強(qiáng)制轉(zhuǎn)換成一個(gè)IJavaProject對(duì)象,也不能把一個(gè)IJavaProject實(shí)例賦值給IProject變量。

由IProject項(xiàng)目得到Java項(xiàng)目的方式:

IJavaProject javaPoject = JavaCore.create(IProject);

由IJavaProject得到IProject的方式:

調(diào)用IJavaProject的IProject getProject();

(2)得到工作空間中的所有Java項(xiàng)目

我們可以首先得到工作空間中的所有項(xiàng)目,然后逐個(gè)進(jìn)行轉(zhuǎn)換。不過這不免麻煩了一些,下面介紹更好的方式。IJavaModel是所有Java項(xiàng)目的根,通過它就可以得到所有的Java項(xiàng)目:

IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();  IJavaModel jModel = JavaCore.create(root);  IJavaProject jProject[] = jModel.getJavaProjects();

(3)   打開Java編輯器并顯示Java編譯單元的特定成員

代碼如下:

void showMethod(IMember member) {      ICompilationUnit cu = member.getCompilationUnit();      IEditorPart javaEditor = JavaUI.openInEditor(cu);      JavaUI.revealInEditor(javaEditor, member);  }

(4)   在工程下創(chuàng)建一個(gè)com.cownew包,并創(chuàng)建一個(gè)Hello.java文件

(5)   打開【打開類型】對(duì)話框

以下代碼段使用 JavaUI 類來打開【打開類型】對(duì)話框:

new ProgressMonitorDialog(parent),   SearchEngine.createWorkspaceScope(),

用類似方法還可以創(chuàng)建【打開包】和【打開主要類型】對(duì)話框。

(6)   打包指定的文件

我們寫一些工具的時(shí)候也許需要把文件打成jar包,然后進(jìn)行發(fā)布到應(yīng)用服務(wù)器等操作,調(diào)用JDT提供的類可簡(jiǎn)化這個(gè)操作(用到的打Jar包的類都在org.eclipse.ui.jarpackager下):

JarPackageData description= new JarPackageData();  IPath location= new Path("C:/cownew.jar");  description.setJarLocation(location);  description.setSaveManifest(true);  description.setManifestMainClass(mainType);  description.setElements(filestoExport);  IJarExportRunnable runnable=   description.createJarExportRunnable(parentShell);  new ProgressMonitorDialog(parentShell).run(true,true, runnable);

參數(shù)mainType表示Jar包的main類,filestoExport為要打包的文件。

(7)   自動(dòng)設(shè)置Java項(xiàng)目的構(gòu)建路徑

有一些插件會(huì)將需要的jar包自動(dòng)設(shè)置到構(gòu)建路徑上,比如使用WTP的新建向?qū)陆╳eb項(xiàng)目的時(shí)候就會(huì)把web開發(fā)需要的jar包自動(dòng)放入項(xiàng)目的構(gòu)建路徑,使用PDE的“將項(xiàng)目轉(zhuǎn)換為插件項(xiàng)目”功能后項(xiàng)目的構(gòu)建路徑中就增加了插件依賴項(xiàng)的庫。那么它們是怎么實(shí)現(xiàn)的呢?

Java項(xiàng)目的構(gòu)建路徑有如下幾種:源文件夾、二進(jìn)制庫、依賴項(xiàng)目、類路徑變量和類路徑容器。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.14  源文件夾

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.15  構(gòu)建依賴項(xiàng)目

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.16  Jar和類文件夾依賴

每種不同的構(gòu)建路徑都有不同的作用:源文件夾是把源碼進(jìn)行構(gòu)建的途徑,二進(jìn)制庫是導(dǎo)入少量jar包的方式,依賴項(xiàng)目是供多項(xiàng)目分模塊開發(fā)使用的,使用類路徑變量可以避免二進(jìn)制包的路徑依賴,而類路徑容器則為大量二進(jìn)制庫的引入提供了方便。

JDT為這些不同的構(gòu)建路徑提供了一個(gè)統(tǒng)一的接口:IClassPathEntry,只要調(diào)用IJavaProject的setRawClasspath方法就可以為項(xiàng)目設(shè)定構(gòu)建路徑。

可以看到setRawClasspath方法需要一個(gè)IClasspathEntry數(shù)組,數(shù)組中的元素就是要設(shè)置的每一個(gè)構(gòu)建路徑。前面提到的JavaCore類提供了一系列的靜態(tài)方法來幫助我們生成不同的IClasspathEntry,而無須關(guān)注生成的細(xì)節(jié)。下面來看不同構(gòu)建路徑的添加方式。

①  源文件夾。使用JavaCore.newSourceEntry方法。下面的代碼的作用是構(gòu)造項(xiàng)目MyProject的源文件夾src的類路徑條目:

JavaCore.newSourceEntry(new Path("/MyProject/src"));

②  二進(jìn)制庫IClasspathEntry。使用JavaCore.newLibraryEntry 方法。下面的代碼就是構(gòu)造MyProject的類文件lib的類路徑條目:

Path("/MyProject/lib"),null, null,false);  

以下類路徑條目具有源代碼連接:

設(shè)定關(guān)聯(lián)源代碼包有利于代碼的跟蹤調(diào)試。

③    依賴項(xiàng)目。使用JavaCore.newProjectEntry方法。下面的代碼就是構(gòu)造依賴項(xiàng)目MyFramework:

IClassPathEntry prjEntry = JavaCore.newProjectEntry(new

Path("/MyFramework"), true);

④  類路徑變量。使用JavaCore.newVariableEntry方法。類路徑變量對(duì)于整個(gè)工作空間來說是全局的,并且可以通過 JavaCore 方法 getClasspathVariable 和 setClasspathVariable 來處理。

可能會(huì)注冊(cè)自動(dòng)的類路徑變量初始化方法,當(dāng)啟動(dòng)工作空間時(shí),通過擴(kuò)展點(diǎn) org.eclipse. jdt.core.classpathVariableInitializer來調(diào)用該類路徑變量初始化方法。

以下類路徑條目指示一個(gè)庫,該庫的位置存放在變量HOME中。使用變量SRC_HOME和SRC_ROOT來定義源代碼連接:

IClassPathEntry varEntry = JavaCore.newVariableEntry(

    new Path("HOME/foo.jar"), //庫路徑

    new Path("SRC_HOME/foo_src.zip"), //源碼歸檔路徑

    new Path("SRC_ROOT"), //源碼歸檔根路徑

    true);

JavaCore.setClasspathVariable("HOME", new Path("d:/myInstall"), null);

⑤    類路徑容器。通過 JavaCore的getClasspathContainer和setClasspathContainer兩個(gè)方法來處理類路徑容器。

可能會(huì)注冊(cè)一個(gè)自動(dòng)的類路徑容器初始化方法,當(dāng)需要綁定容器時(shí),通過擴(kuò)展點(diǎn) org.eclipse.jdt.core.classpathContainerInitializer來被動(dòng)地調(diào)用類路徑容器初始化方法。

以下類路徑條目指示系統(tǒng)類庫容器:

IClassPathEntry varEntry = JavaCore.newContainerEntry(                            new Path("JDKLIB/default"),false);  JavaCore.setClasspathContainer(  new Path("JDKLIB/default"),  new IJavaProject[]{ myProject },           new IClasspathContainer[] {               new IClasspathContainer() {                   public IClasspathEntry[] getClasspathEntries() {                       return new IClasspathEntry[]{                           JavaCore.newLibraryEntry(  new Path("d:/rt.jar"), null, null, false);                       };                    }                   public String getDescription() {   return "Basic JDK library container"; }                   public int getKind() { return IClasspathContainer.K_SYSTEM; }                   public IPath getPath() { return new Path("JDKLIB/basic"); }               }                     },   null);

我們只要調(diào)用相應(yīng)的方法創(chuàng)建我們的類路徑條目就可以了,然后把這些條目組成的數(shù)組通過setRawClasspath方法設(shè)定到項(xiàng)目中。需要注意的是如果我們只把要添加的類路徑條目傳入 setRawClasspath方法的話,就會(huì)替換原有的項(xiàng)目構(gòu)建路徑,這常常是我們不希望的??梢哉{(diào)用IJavaProject的 readRawClasspath方法讀取項(xiàng)目已有的設(shè)置,把我們要設(shè)置的構(gòu)建路徑添加到它的后面,然后再調(diào)用setRawClasspath方法設(shè)定新的項(xiàng)目構(gòu)建路徑。

在這個(gè)例子中,將要實(shí)現(xiàn)一個(gè)“為項(xiàng)目添加 lucene支持”的功能,用戶在項(xiàng)目上右擊,選擇菜單中的【為項(xiàng)目添加lucene支持】命令以后,插件就會(huì)把lucene的jar包和源碼包復(fù)制到項(xiàng)目的lib目錄下,并且將jar包加入構(gòu)建路徑。如圖3.17所示為增加lucene支持前的項(xiàng)目結(jié)構(gòu)。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.17  增加lucene支持之前的項(xiàng)目結(jié)構(gòu)

用戶在項(xiàng)目上右擊,在彈出的快捷菜單中選擇【為項(xiàng)目添加lucene支持】命令后的項(xiàng)目結(jié)構(gòu)如圖3.18所示。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.18  增加lucene支持之后的項(xiàng)目結(jié)構(gòu)

圖3.19是項(xiàng)目的構(gòu)建路徑。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.19  增加的lucene包

首先新建一個(gè)插件工程,并將JDT相關(guān)的依賴項(xiàng)加入。然后添加一個(gè)org.eclipse.ui.popupMenus的擴(kuò)展點(diǎn),如果不熟悉怎么添加,可以使用插件向?qū)е械摹皬棾霾藛巍毕驅(qū)А?/p>

需要注意contribution的配置,如圖3.20所示。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.20  contribution的配置

此插件只針對(duì)Java項(xiàng)目起作用,因此 objectClass中填入org.eclipse.jdt.core.IJavaProject;adaptable選擇true;如果是用向?qū)傻哪敲凑?qǐng)記住清空nameFilter。下面是核心類ActionAddLucene的實(shí)現(xiàn)代碼:

System.getProperty("file.separator","/");  JavaCore.newLibraryEntry(project  .getFullPath(), project  LUCENESRCJAR).getFullPath(), null,   new IClasspathEntry[oldPaths.length + 1];  LIB + FILESEPARATOR + LUCENEJAR);  LIB + FILESEPARATOR + LUCENESRCJAR);  IClasspathEntry entry)  e.getMessage(), e));

下面解釋一下代碼中的重點(diǎn)部分。

IClasspathEntry[] oldPaths = javaProject.readRawClasspath();

讀取項(xiàng)目原有的構(gòu)建路徑條目。

IClasspathEntry luceneLibEntry = JavaCore.newLibraryEntry(  project.getFile(LIB + FILESEPARATOR + LUCENEJAR).getFullPath(),   project.getFile(LIB + FILESEPARATOR + LUCENESRCJAR).getFullPath(),  null, false);

這一句構(gòu)建lucene的jar包。

第1個(gè)參數(shù)是二進(jìn)制jar包的位置,我們的二進(jìn)制jar包的位置為項(xiàng)目路徑下的lib/lucene-1.4.3-src.jar。

第2個(gè)參數(shù)是jar包對(duì)應(yīng)的源碼包的位置。

第3個(gè)參數(shù)為源碼包的根路徑,因?yàn)橛械脑创ajar包的源碼根路徑不是jar包的根路徑,比如simplejta的源碼jar包的格式如圖3.21所示。

Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的

圖3.21  Jar包的結(jié)構(gòu)

對(duì)于這種情況就要指定第2個(gè)參數(shù)為“src”,lucene的源碼包的源碼根路徑就是jar包的根路徑,因此我們?cè)O(shè)置此參數(shù)為null。

第4個(gè)參數(shù)表示是否導(dǎo)出,我們?cè)O(shè)置為false。

(3)   URL luceneLib = Activator.getDefault().getBundle().getEntry(RESOUCELIB + FILE- SEPARATOR + LUCENEJAR);

我們把“l(fā)ucene-1.4.3.jar”、 “l(fā)ucene-1.4.3-src.jar”放到我們插件的“resoucelib”目錄下,當(dāng)用戶單擊【為項(xiàng)目添加lucene支持】的時(shí)候要把這兩個(gè)文件復(fù)制到項(xiàng)目的lib目錄下,因此需要首先讀取插件路徑“resoucelib”目錄下的這兩個(gè)jar包。

讀取插件路徑下的文件時(shí)我們使用插件Activator類提供的方法即可,比如如下調(diào)用:

就可以讀取到插件根目錄下的文件“config/my.xml”,返回類型是java.net.URL。

(4)   copyURLToFile(luceneLib, project, LIB + FILESEPARATOR + LUCENEJAR);

Activator.getDefault().getBundle().getEntry讀取到的文件位置是URL類型的,我們需要把這個(gè)URL對(duì)應(yīng)的文件復(fù)制到項(xiàng)目的lib下。下面看一下copyURLToFile的主干代碼:

URL類有一個(gè)openStream可以打開文件的輸入流,IFile也有一個(gè)接受輸入流的create方法用來創(chuàng)建文件,因此我們只需要把url的輸入流輸出給IFile的create方法即可。

這里我們也可以由url得到其對(duì)應(yīng)的磁盤上的路徑,也可以得到IFile對(duì)應(yīng)的磁盤上的路徑,然后使用Java IO來進(jìn)行文件復(fù)制操作。但是這樣做不僅代碼數(shù)量變多了,而且由于使用的不是Eclipse的資源管理API,會(huì)帶來無法自動(dòng)刷新等問題,因此建議盡量使用Eclipse提供的API來完成此功能。

學(xué)習(xí)Eclipse插件開發(fā)的最好的方式就是研讀 Eclipse的源碼,而對(duì)插件開發(fā)者最有參考價(jià)值的就是JDT(Java Development Tools)的代碼,相信把所有的包研讀一遍以后就會(huì)成為插件開發(fā)的高手了。下面是各個(gè)主要包的內(nèi)容,讀者可以根據(jù)需要有選擇地進(jìn)行研讀。

關(guān)于Eclipse插件開發(fā)中的Java項(xiàng)目模型是怎樣的就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI