eclipse插件开发--打开编辑器(上)

 

【打开editor的接口讨论】
        先来看一下workbench吧,workbench从静态划分应该大致如下:
       
             从结构图我们大致就可以猜测出来,workbench page作为一个IWorkbenchPart(无论是eidtor part还是view part)的容器,肯定会接受workbench page的管理。看了一下,IWorkbenchPage接口定义中确实提供给了如下打开编辑器的操作:

             【IWokbenchPage提供的接口】

1  public   interface  IWorkbenchPage  extends  IPartService, ISelectionService,ICompatibleWorkbenchPage {
2      
3        public  IEditorPart openEdito(IEditorInput input, String editorId) throws  PartInitException;
4       
5        public  IEditorPart openEdito(IEditorInput input, String editorId,  boolean  activate)  throws  PartInitException;
6     
7        public  IEditorPart openEditor( final  IEditorInput input,  final  String editorId,  final   boolean  activate,  final   int  matchFlags) throws  PartInitException;
8  }

          
             那到这边,可能很多人已经知道了怎么调用这些接口了:
          PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(...)
           (说明:PlatformUI可以看作是整个eclipse ui框架的门面类,当然最核心的作用就是让用户获取到workbench。Eclipse中存在的其他一些门面类如:ResourcesPlugin、Platform、JavaCore、JavaUI等)

             我们再仔细看一下IWorkbenchPage对应的实现类(org.eclipse.ui.internal.WorkbenchPage)中的以上接口的实现代码,真正在管理Editor的是一个叫做EditorManager的东东(同理,view part对应的管理器角色类是叫做ViewFactory的东东)。这里的EditorManager和View Factory是workbench实现中非常精华的部分,看一下里面的实现就会很大程度上理解workbench所谓懒加载、懒初始化是如何实现的了,如何实现part 复用的...等等。 
            
           上图就用来说明workbench是如何来管理各种part的,其中descriptor角色的核心作用是延迟加载扩展(延迟加载用户通过editors或者views提供的扩展),reference角色的核心作用是用来延迟初时化具体的part(例如避免过早的创建对应的control等等)。再说下去有点偏离主题了,这部分,以后有时间再写
            
           【IDE工具类提供的接口】
             上面IWorkbenchPage提供接口都需要用户准备两样东西:一是创建IEditorInput实例,二是指定editor id。有些用户可能不想干这两件事情,所以在工具类org.eclipse.ui.ide.IDE中提供了其他的接口:

1  public   static  IEditorPart openEditor(IWorkbenchPage page, IFile input)  throws  PartInitException { }

3  public   static  IEditorPart openEditor(IWorkbenchPage page, IFile input,  boolean  activate)  throws  PartInitException {   }

5  public   static  IEditorPart openEditor(IWorkbenchPage page, IFile input,  boolean  activate,  boolean  determineContentType) { }

7  public   static  IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId)  throws  PartInitException {   }

9  public   static  IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId,  boolean  activate)  throws  PartInitException {   }
10 
11

            上面5个接口操作中, 对于上面的三个操作,Eclipse会自动为你准备IEditorInput实例,并动态绑定合适的编辑器类型。对于下面的两个操作,Eclipse会为你自动准备IEditorInput实例,但是需要用户自己指定editor id。
            
            接下来我们看两个问题,一是如何创建IEditorInput实例的;而是如何动态计算对应的editor id的。
           
           【有关FileEditorInput】
           在IDE工具类中提供的5个接受IFile对象的openEditor接口中,在对应的实现中都是默认构造了一个FileEditorInput(org.eclipse.ui.part.FileEditorInput)实例,这个实例也是org.eclipse.ui.IFileEditorInput接口的默认实现类(注意:Eclipse中很多地方都使用这种Interface/Default Impl的方式,Interface会暴露,Default Impl则根据情况选择是否暴露,一般是如果Interface希望用户来扩展继承,则会暴露对应的Default Impl,如果Interface不希望用户来扩展继承,例如IResource系列接口,则一般会将Default Impl丢如对应的internal包中)。
             我们看一下org.eclipse.ui.part.FileEditorInput中是如何实现IEditorInput.exists()接口的:

1  public   class  FileEditorInput  implements  IFileEditorInput,IPathEditorInput,IPersistableElement {
2       private  IFile file;

4       public   boolean  exists() {
5           return  file.exists();
6       }
7  }

          我们看到内部的实现是持有了IFile句柄,如果IFile代表的资源没有存在于工作区之内,那么就会返回false。(疑问:如果我们打开工作区外部的文件呢???显然,FileEditorInput并不合适,稍后看...)
        
         【动态计算editor id】
         下面,我们再来看一下IDE类是如何计算所谓的默认eidtor id的。追踪实现,我们看到了IDE.getDefaultEditor

1  public   static  IEditorDescriptor getDefaultEditor(IFile file,  boolean  determineContentType) {
2           //  Try file specific editor.
3           IEditorRegistry editorReg  =  PlatformUI.getWorkbench()
4                   .getEditorRegistry();
5           try  {
6               String editorID  =  file.getPersistentProperty(EDITOR_KEY);
7               if  (editorID  !=   null ) {
8                   IEditorDescriptor desc  =  editorReg.findEditor(editorID);
9                   if  (desc  !=   null ) {
10                       return  desc;
11                   }
12               }
13           }  catch  (CoreException e) {
14               //  do nothing
15           }
16          
17           IContentType contentType  =   null ;
18           if  (determineContentType) {
19               contentType  =  getContentType(file);
20           }    
21           //  Try lookup with filename
22           return  editorReg.getDefaultEditor(file.getName(), contentType);
23       }

             上面的代码大致赶了如下两件事情:
            1、如果对应的资源设定了一个特定的持久化属性EDITOR_KEY,则会使用EDITOR_KEY属性值所代表的编辑器(说明:有关Eclipse资源的属性支持,请参阅其他文档)。那如果一个资源不在工作区之内,又如何设定EDITOR_KEY属性呢??? (~_~确实没法设定)
           2、查找对应的content type,用户通过org.eclipse.core.runtime.contentTypes扩展点来注册自定义的内容类型,在内容类型中会指定对应的文件扩展名和默认编码,例如JDT中注册了如下内容类型(摘自org.eclipse.jdt.core/plugin.xml):

<!--  ===================================================================================  -->
<!--  Extension: Java Content Types                                                        -->
<!--  ===================================================================================  -->
< extension  point ="org.eclipse.core.runtime.contentTypes" >
     <!--  declares a content type for Java Properties files  -->
     < content-type  id ="javaProperties"  name ="%javaPropertiesName"  
         base-type ="org.eclipse.core.runtime.text"
         priority ="high"                 
         file-extensions ="properties"
         default-charset ="ISO-8859-1" />
     <!--  Associates .classpath to the XML content type  -->
     < file-association 
         content-type ="org.eclipse.core.runtime.xml"  
         file-names =".classpath" />   
     <!--  declares a content type for Java Source files  -->
     < content-type  id ="javaSource"  name ="%javaSourceName"  
         base-type ="org.eclipse.core.runtime.text"
         priority ="high"                 
         file-extensions ="java" />
     <!--  declares a content type for Java class files  -->
     < content-type  id ="javaClass"  name ="%javaClassName"  
         priority ="high"                 
         file-extensions ="class" >         
         < describer
             class ="org.eclipse.core.runtime.content.BinarySignatureDescriber" >
             < parameter  name ="signature"  value ="CA, FE, BA, BE" />
         </ describer >
     </ content-type >         
     <!--  declares a content type for JAR manifest files  -->
     < content-type  id ="JARManifest"  name ="%jarManifestName"  
         base-type ="org.eclipse.core.runtime.text"
         priority ="high"                 
         file-names ="MANIFEST.MF"
         default-charset ="UTF-8" />
</ extension >

             那如果我们在注册编辑器的时候和对应的content type绑定,这不就联系起来了吗~_~。那我们看一下java源码编辑器扩展描述(摘自org.eclipse.jdt.ui/plugin.xml):

< editor
             name ="%JavaEditor.label"
             default ="true"
             icon ="$nl$/icons/full/obj16/jcu_obj.gif"
             contributorClass ="org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditorActionContributor"
             class ="org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor"
             symbolicFontName ="org.eclipse.jdt.ui.editors.textfont"
             id ="org.eclipse.jdt.ui.CompilationUnitEditor" >
             < contentTypeBinding
                contentTypeId ="org.eclipse.jdt.core.javaSource"
             />  
       </ editor >

           我们看到上面的xml中有contentTypeBinding元素,里面指定了绑定java源码content type。

转自:http://hi.baidu.com/haozi2638/blog/item/7a1c5ab5f8fba3c636d3ca25.html

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值