Eclipse日志控件的设计和E4迁移

简要说明

一直想着弄清楚各种GUI上的日志打印的原理,比如,shell执行一个命令后打印在屏幕上的日志,Eclipse 或Idea IDE上日志控件的打印。

刚好在做Pi2(Pisces2-m-gui)的时,使用的是Eclipse RCP 2.0(E4),需要用到日志控件来显示文件传输的日志。于是,想着把E3(Eclipse 3.x)的日志插件直接拿来用,不巧的是,基于E3 API开发的Eclipse的原有的插件并没有做E4的兼容。

为了使用E3的日志控件,想了各种方法,最后实在没有更好的思路,就想着,基于E3的日志控件源码,将其改造适配到E4的API上来,这样就可以在E4上使用了。后来在使用opcoach开源的e4 preferences插件的时候,发现opcoach用的也是这个思路,看来都是被新平台不兼容旧组件给逼的。

日志控件的设计原理

既然通过改造E3 上原有的插件源码来适配E4的思路没问题,接下来就是要弄清楚日志控件的功能是怎么实现的了。下图是依据E3的 IOConsoleView相关源码整理出来的日志打印的流程或原理。

上面的图我们可以简单分成两个部分来看,

  • 左边的IOConsoleOutputStream类的写日志接口;
  • 虚线框的IOConsolePartitioner。

第一部分比较简单,IOConsoleOutputStream.write(xxx)方法,有7个重载的write方法,是提供给使用方往日志控件写日志的用的,对应源码如下图所示。

第二部分的IOConsolePartitioner类,是日志打印的核心,也相对复杂些。

这个IOConsolePartitioner像名字所示的一样,它的作用就是将日志内容分割成一段一段的,然后保存到深灰色区域的Document里。

图上就可以看出,主要包括四个部分:

  • 缓存队列,用于缓存写入的日志内容;
  • 队列处理的Job,用于消费缓存队列;
  • 存储日志的Document及其结构;
  • 另外一个Job,用于剪除超出Document存储最大长度的日志。

写日志使用的是异步方式写的,使用方调用write方法后,将日志内容扔pendingPartitions队列就返回了,然后由一个后台独立运行的叫queueJob的QueueProcessingJob(线程)来处理缓存队列中的日志内容,主要消费队列的日志,计算保存到Document的位置,并记录下位置信息,接着将日志内容追加到Document的指定位置上,最后Document会触发一个内容变动的事件,UI接收到后刷新显示的内容。至此,一条日志完成了。

需要注意的是,每往队列里写一行日志的时候,日志内容都要以 回车换行(”\r\n”)来结尾,否则显示在日志控件上的日志信息是不换行,日志内容连着显示。

触发Document内容变动事件定义在:org.eclipse.jface.text.AbstractDocument

日志控件迁移到E4

上一章节弄清楚了日志控件的核心功能和组件,那么,将其迁移到E4的目标就明确了。整个迁移过程可以分为三个部分:

  • Job的迁移和E3 静态Singleton调用方式改成E4的@Inject注入的方式来获取依赖的类,例如,UISynchronize。
  • UI模型结构的调整,主要去除E3的PageSite概念相关的类,直接使用核心功能组件来重组一个简化的适用于E4的UI模型。
  • 改造后日志控件的初始化和使用

·  

Job迁移和UI模型结构调整的相关文件列表:

改造后的日志控件在E4中的使用

待办

改造的调用还有更好的实现方式,后续会参考Cybersearch2开源的statusbar(http://cybersearch2.com.au/eclipse/statusbar.html)方式,修改成fragment的插件,更方便给其他插件使用。

后记

以上关于日志控件的插件 cn.bbstone.e4.ui.logview 在文章写成还未开源,后续对代码稍做整理后会尽快开源。

参考

Opcoach

https://www.opcoach.com/en/managing-preference-pages-with-eclipse-4/

https://github.com/opcoach/e4Preferences

Statusbar 

http://cybersearch2.com.au/eclipse/statusbar.html

https://github.com/andrew-bowley/statusbar

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注