您好,登錄后才能下訂單哦!
這篇文章給大家介紹Eclipse插件開發中的Java項目模型是怎樣的,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
Java項目模型
Eclipse的項目有很多種,包括Java項目、C++項目、C#項目等,每種項目都有自己的特點。我們最常接觸到的項目就是Java項目,因此我們重點來講解一下Java項目模型。
Java模型是用來對與創建、編輯和構建Java程序相關聯的對象進行建模的一些類。Java模型類是在org.eclipse.jdt.core中定義的。這些類實現資源的特定于Java的行為,并進一步將Java資源分解成模型元素。
Java模型的繼承結構圖如圖3.13所示。
圖3.13 Java模型的繼承結構圖
IJavaElement的子類接口還有IMethod、IType等,在這里沒有全部列出。Java模型中的類結構比較簡單,級次也非常少。
下面介紹一下各個接口的主要方法。
(1) IJavaElement
exists:判斷元素是否存在。處理Java元素與處理資源對象相似。當使用Java元素時,實際上是在使用某些底層的模型對象的句柄。必須使用exists()來確定元素是否真正存在于工作空間中。
getElementName:返回元素的名稱。
getJavaModel:返回其對應的JavaModel,返回值類型是IJavaModel。
getJavaProject:返回元素對應的Java工程,返回值類型是IJavaProject。
getParent:返回父元素,返回值類型是IJavaElement。
getResource:返回元素對應的資源,返回值類型是IResource。
(2) IClassFile
此接口代表編譯后的class二進制文件。
isClass:判斷是否是Java類。
isInterface:判斷是否是接口。
(3) ICompilationUnit
此接口代表Java源文件。
getAllTypes:返回此文件中定義的所有類型,返回值類型是IType[]。一個Java文件中可以定義多個類型。
getPrimary:返回主類型,返回值類型是ICompilationUnit。
(4) IJavaModel
此接口表示根 Java 元素,對應于工作空間。是所有具有 Java 性質的項目的父類。它對于Java項目的作用和IWorkspaceRoot對于IProject的作用相似。
contains:判斷是否存在指定的資源。
getJavaProject:返回指定名字的Java項目,返回值類型是IJavaProject。
getJavaProjects:返回所有的Java項目,返回值類型是IJavaProject[]。
getWorkspace:返回所在的工作空間。
(5) IJavaProject
此接口表示Java項目。
IJavaElement findElement(IPath path):返回項目的path路徑下的Java元素。
IPackageFragment findPackageFragment(IPath path):返回項目的path路徑下的IPackageFragment。
IPackageFragmentRoot findPackageFragmentRoot(IPath path):返回項目的path路徑下的IPackageFragmentRoot。
findType:根據一個全名取得此元素的類型,此類有數個重載方法,返回值類型為IType。
getAllPackageFragmentRoots:返回所有的IPackageFragmentRoot,返回值類型是IPackageFragmentRoot[]。
getOutputLocation:返回輸出路徑,返回值類型是IPath。
getRequiredProjectNames:返回依賴項目,返回值類型是字符串數組。
setOutputLocation:設定輸出路徑。
(6) IPackageFragment
此接口表示整個包或者包的一部分。
createCompilationUnit:創建一個ICompilationUnit,返回值類型是ICompilationUnit。
getClassFile:返回指定名稱對應的IClassFile,返回值類型是IClassFile。
getClassFiles:返回所有的IClassFile,返回值類型是IClassFile[]。
getCompilationUnit:返回指定名稱對應的ICompilationUnit,返回值類型是ICompilationUnit。
getCompilationUnits:返回所有ICompilationUnit,返回值類型是ICompilationUnit[]。
getKind:判斷此包是源碼包還是普通包,返回值是int型,如等于IPackage- FragmentRoot.K_SOURCE則是源文件包,如等于IPackageFragmentRoot.K_BINARY則為普通包。
hasSubpackages:是否有子包。
(7) IPackageFragmentRoot
此接口表示一組包段,并將各段映射至底層資源,它可以是文件夾、JAR或ZIP文件。
createPackageFragment:創建一個IPackageFragment,返回值類型是IPackage- Fragment。
getKind:此包段是源碼包段還是二進制包段,返回值類型是int,如果等于IPackageFragmentRoot.K_SOURCE則是源文件包段,如果等于IPackageFragment- Root.K_BINARY則為二進制包段。
getPackageFragment:根據包名返回對應的IPackageFragment。
常用工具類
(1) JavaCore(定義在org.eclipse.jdt.core包下)
JavaCore從Plugin繼承,它是JDT插件的生命周期管理器。不過對于第三方插件開發人員來說,它的重要性更多地體現在它提供的一些工具類方法中。
IJavaElement create(IFile file):從文件創建對應的Java元素。
IJavaElement create(IFolder folder):從文件夾創建對應的Java元素。
IJavaProject create(IProject project):得到IProject對應的IJavaProject。
IJavaElement create(IResource resource):從資源創建對應的Java元素。
IJavaModel create(IWorkspaceRoot root):從工作空間根目錄得到對應的IJavaModel。
IClassFile createClassFileFrom(IFile file):從文件創建對應的IClassFile。
ICompilationUnit createCompilationUnitFrom(IFile file):從文件創建對應的ICompilationUnit。
(2) JavaUI(定義在org.eclipse.jdt.ui包下)
JavaUI中定義了常用的Java插件界面相關的方法。
createPackageDialog:創建一個包選擇對話框,返回值是SelectionDialog。
createTypeDialog:創建一個類型選擇對話框,返回值是SelectionDialog。
IEditorPart openInEditor(IJavaElement element):用編輯器打開指定的Java元素并返回編輯器實例。
revealInEditor(IEditorPart part, IJavaElement element):在編輯器中定位元素element。
插件開發中經常會碰到一些常用的技巧,掌握這些技巧可以極大地提高插件的開發效率,并且可以減小插件的體積。下面列出一些常見的技巧。
(1) 由一個普通項目得到Java項目
Java項目是一種特殊的項目,需要注意的是IJavaProject并不是從IProject繼承的。不能將一個IProject對象強制轉換成一個IJavaProject對象,也不能把一個IJavaProject實例賦值給IProject變量。
由IProject項目得到Java項目的方式:
IJavaProject javaPoject = JavaCore.create(IProject);
由IJavaProject得到IProject的方式:
調用IJavaProject的IProject getProject();
(2)得到工作空間中的所有Java項目
我們可以首先得到工作空間中的所有項目,然后逐個進行轉換。不過這不免麻煩了一些,下面介紹更好的方式。IJavaModel是所有Java項目的根,通過它就可以得到所有的Java項目:
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) 在工程下創建一個com.cownew包,并創建一個Hello.java文件
(5) 打開【打開類型】對話框
以下代碼段使用 JavaUI 類來打開【打開類型】對話框:
new ProgressMonitorDialog(parent), SearchEngine.createWorkspaceScope(),
用類似方法還可以創建【打開包】和【打開主要類型】對話框。
(6) 打包指定的文件
我們寫一些工具的時候也許需要把文件打成jar包,然后進行發布到應用服務器等操作,調用JDT提供的類可簡化這個操作(用到的打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);
參數mainType表示Jar包的main類,filestoExport為要打包的文件。
(7) 自動設置Java項目的構建路徑
有一些插件會將需要的jar包自動設置到構建路徑上,比如使用WTP的新建向導新建web項目的時候就會把web開發需要的jar包自動放入項目的構建路徑,使用PDE的“將項目轉換為插件項目”功能后項目的構建路徑中就增加了插件依賴項的庫。那么它們是怎么實現的呢?
Java項目的構建路徑有如下幾種:源文件夾、二進制庫、依賴項目、類路徑變量和類路徑容器。
圖3.14 源文件夾
圖3.15 構建依賴項目
圖3.16 Jar和類文件夾依賴
每種不同的構建路徑都有不同的作用:源文件夾是把源碼進行構建的途徑,二進制庫是導入少量jar包的方式,依賴項目是供多項目分模塊開發使用的,使用類路徑變量可以避免二進制包的路徑依賴,而類路徑容器則為大量二進制庫的引入提供了方便。
JDT為這些不同的構建路徑提供了一個統一的接口:IClassPathEntry,只要調用IJavaProject的setRawClasspath方法就可以為項目設定構建路徑。
可以看到setRawClasspath方法需要一個IClasspathEntry數組,數組中的元素就是要設置的每一個構建路徑。前面提到的JavaCore類提供了一系列的靜態方法來幫助我們生成不同的IClasspathEntry,而無須關注生成的細節。下面來看不同構建路徑的添加方式。
① 源文件夾。使用JavaCore.newSourceEntry方法。下面的代碼的作用是構造項目MyProject的源文件夾src的類路徑條目:
JavaCore.newSourceEntry(new Path("/MyProject/src"));
② 二進制庫IClasspathEntry。使用JavaCore.newLibraryEntry 方法。下面的代碼就是構造MyProject的類文件lib的類路徑條目:
Path("/MyProject/lib"),null, null,false);
以下類路徑條目具有源代碼連接:
設定關聯源代碼包有利于代碼的跟蹤調試。
③ 依賴項目。使用JavaCore.newProjectEntry方法。下面的代碼就是構造依賴項目MyFramework:
IClassPathEntry prjEntry = JavaCore.newProjectEntry(new
Path("/MyFramework"), true);
④ 類路徑變量。使用JavaCore.newVariableEntry方法。類路徑變量對于整個工作空間來說是全局的,并且可以通過 JavaCore 方法 getClasspathVariable 和 setClasspathVariable 來處理。
可能會注冊自動的類路徑變量初始化方法,當啟動工作空間時,通過擴展點 org.eclipse. jdt.core.classpathVariableInitializer來調用該類路徑變量初始化方法。
以下類路徑條目指示一個庫,該庫的位置存放在變量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兩個方法來處理類路徑容器。
可能會注冊一個自動的類路徑容器初始化方法,當需要綁定容器時,通過擴展點 org.eclipse.jdt.core.classpathContainerInitializer來被動地調用類路徑容器初始化方法。
以下類路徑條目指示系統類庫容器:
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);
我們只要調用相應的方法創建我們的類路徑條目就可以了,然后把這些條目組成的數組通過setRawClasspath方法設定到項目中。需要注意的是如果我們只把要添加的類路徑條目傳入 setRawClasspath方法的話,就會替換原有的項目構建路徑,這常常是我們不希望的。可以調用IJavaProject的 readRawClasspath方法讀取項目已有的設置,把我們要設置的構建路徑添加到它的后面,然后再調用setRawClasspath方法設定新的項目構建路徑。
在這個例子中,將要實現一個“為項目添加 lucene支持”的功能,用戶在項目上右擊,選擇菜單中的【為項目添加lucene支持】命令以后,插件就會把lucene的jar包和源碼包復制到項目的lib目錄下,并且將jar包加入構建路徑。如圖3.17所示為增加lucene支持前的項目結構。
圖3.17 增加lucene支持之前的項目結構
用戶在項目上右擊,在彈出的快捷菜單中選擇【為項目添加lucene支持】命令后的項目結構如圖3.18所示。
圖3.18 增加lucene支持之后的項目結構
圖3.19是項目的構建路徑。
圖3.19 增加的lucene包
首先新建一個插件工程,并將JDT相關的依賴項加入。然后添加一個org.eclipse.ui.popupMenus的擴展點,如果不熟悉怎么添加,可以使用插件向導中的“彈出菜單”向導。
需要注意contribution的配置,如圖3.20所示。
圖3.20 contribution的配置
此插件只針對Java項目起作用,因此 objectClass中填入org.eclipse.jdt.core.IJavaProject;adaptable選擇true;如果是用向導生成的那么請記住清空nameFilter。下面是核心類ActionAddLucene的實現代碼:
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));
下面解釋一下代碼中的重點部分。
IClasspathEntry[] oldPaths = javaProject.readRawClasspath();
讀取項目原有的構建路徑條目。
IClasspathEntry luceneLibEntry = JavaCore.newLibraryEntry( project.getFile(LIB + FILESEPARATOR + LUCENEJAR).getFullPath(), project.getFile(LIB + FILESEPARATOR + LUCENESRCJAR).getFullPath(), null, false);
這一句構建lucene的jar包。
第1個參數是二進制jar包的位置,我們的二進制jar包的位置為項目路徑下的lib/lucene-1.4.3-src.jar。
第2個參數是jar包對應的源碼包的位置。
第3個參數為源碼包的根路徑,因為有的源碼jar包的源碼根路徑不是jar包的根路徑,比如simplejta的源碼jar包的格式如圖3.21所示。
圖3.21 Jar包的結構
對于這種情況就要指定第2個參數為“src”,lucene的源碼包的源碼根路徑就是jar包的根路徑,因此我們設置此參數為null。
第4個參數表示是否導出,我們設置為false。
(3) URL luceneLib = Activator.getDefault().getBundle().getEntry(RESOUCELIB + FILE- SEPARATOR + LUCENEJAR);
我們把“lucene-1.4.3.jar”、 “lucene-1.4.3-src.jar”放到我們插件的“resoucelib”目錄下,當用戶單擊【為項目添加lucene支持】的時候要把這兩個文件復制到項目的lib目錄下,因此需要首先讀取插件路徑“resoucelib”目錄下的這兩個jar包。
讀取插件路徑下的文件時我們使用插件Activator類提供的方法即可,比如如下調用:
就可以讀取到插件根目錄下的文件“config/my.xml”,返回類型是java.net.URL。
(4) copyURLToFile(luceneLib, project, LIB + FILESEPARATOR + LUCENEJAR);
Activator.getDefault().getBundle().getEntry讀取到的文件位置是URL類型的,我們需要把這個URL對應的文件復制到項目的lib下。下面看一下copyURLToFile的主干代碼:
URL類有一個openStream可以打開文件的輸入流,IFile也有一個接受輸入流的create方法用來創建文件,因此我們只需要把url的輸入流輸出給IFile的create方法即可。
這里我們也可以由url得到其對應的磁盤上的路徑,也可以得到IFile對應的磁盤上的路徑,然后使用Java IO來進行文件復制操作。但是這樣做不僅代碼數量變多了,而且由于使用的不是Eclipse的資源管理API,會帶來無法自動刷新等問題,因此建議盡量使用Eclipse提供的API來完成此功能。
學習Eclipse插件開發的最好的方式就是研讀 Eclipse的源碼,而對插件開發者最有參考價值的就是JDT(Java Development Tools)的代碼,相信把所有的包研讀一遍以后就會成為插件開發的高手了。下面是各個主要包的內容,讀者可以根據需要有選擇地進行研讀。
關于Eclipse插件開發中的Java項目模型是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。