本文记录通过Debug dbeaver 项目学习到的RCP相关零散知识点。
dbeaver 项目部署到eclipse 和 idea,并进行debug调试,查看PDF文档
1.项目启动
eclipse rcp应用,使用了osgi框架:equinox,那么应用启动入口点是 org.eclipse.equinox.app.IApplication 接口类。在 dbeaver 中,额外定义了一个接口类 org.jkiss.dbeaver.model.app.DBPApplication ,该接口作用是意图通过调用接口中的方法来重新定义 dbeaver的行为或者设置。dbeaver 定义了一个抽象类 org.jkiss.dbeaver.registry.BaseApplicationImpl 实现了上述两个接口,最终提供了一个类 org.jkiss.dbeaver.ui.app.standalone.DBeaverApplication继承了BaseApplicationImpl 抽象类。即dbeaver项目启动会从DBeaverApplication 进行入口。项目入口定义在/org.jkiss.dbeaver.ui.app.standalone/plugin.xml 文件中:
以下是DBeaverApplication 类图:
2. /org.jkiss.dbeaver.ui.app.standalone/plugin.xml
该xml文件定义了程序入口程序,下面看下程序打开主界面菜单控件的定义。
菜单定义在 <extension point="org.eclipse.ui.menus"> 节点中。看下一个编辑控件菜单定义:
以上菜单定义控件commandId 是以 org.eclipse.ui 开头,表示这是eclipse内置的控件,该控件在应用启动时会自动注册commandId对应的事件行为。而我们自定义的commandId 比如 org.jkiss.dbeaver.core.new.connection,
该commandId定义方式如下:
a. 定义commandId,并定义触发该commandId的事件处理类
b. 定义commandId的名称,描述文字,以及类别
c. 定义commandId的显示图片
定义好后,就可以使用commandId对应的控件,如:
3. 点击控件弹出对话框及界面显示处理
以 org.jkiss.dbeaver.core.new.connection 新建连接为例
从上述分析中,可以找到该控件的点击处理事件,org.jkiss.dbeaver.ui.actions.datasource.DataSourceCreateHandler ,可以找到这个代码:
是打开一个对话框,对话框具体处理方法在 NewConnectionDialog.openNewConnectionDialog(window) 中,该方法中会调用NewConnectionDialog 的 open方法打开即将要打开的新建连接向导页面。
通过debug,发现最终会调用 org.eclipse.jface.wizard.WizardDialog#createContents 方法 ,先去addPages(),然后再createContents
NewConnectionWizard 类图
进入到NewConnectionWizard 类中将会执行org.jkiss.dbeaver.ui.dialogs.connection.NewConnectionWizard#addPages 方法,向向导页面中添加页面,该方法是在 org.eclipse.jface.wizard.Wizard 抽象类中进行定义,可以查看相关类注释
4. 查询管理器
查询刷新按钮事件: org.jkiss.dbeaver.ui.controls.querylog.QueryLogCommandHandler 最终在方法 org.jkiss.dbeaver.ui.controls.querylog.QueryLogViewer.EventHistoryReadService.evaluate(DBRProgressMonitor) 中进行历史数据过滤。执行SQL历史记录是暂存在 org.jkiss.dbeaver.runtime.qm.QMMCollectorImpl.eventPool 这个List 数组中,因此程序重启,原先历史记录就会消失。操作SQL触发添加历史记录方法事件: org.jkiss.dbeaver.runtime.qm.QMMCollectorImpl.fireMetaEvent(QMMObject, Action)。
日志查询器鼠标右击菜单在 org.jkiss.dbeaver.ui.controls.querylog.QueryLogViewer.createFiltersMenu(IMenuManager) 该方法进行初始化