UI持久化机制

原创 2007年10月10日 15:08:00
Eclipse 中 IMemento 接口定义了对象持久化方式,通过 IMemento 接口的实现类,用户能把对象持久化到文件系统中, IMemento 接口定义如例程 24-7 所示。
例程 24-7 IMemento.java
package org.eclipse.ui;
 
public interface IMemento {
    public static final String TAG_ID = "IMemento.internal.id"; //$NON-NLS-1$
 
    public IMemento createChild(String type);
 
    public IMemento createChild(String type, String id);
 
    public IMemento getChild(String type);
 
    public IMemento[] getChildren(String type);
 
    public Float getFloat(String key);
 
    public String getID();
 
    public Integer getInteger(String key);
 
    public String getString(String key);
 
    public String getTextData();
 
    public void putFloat(String key, float value);
 
    public void putInteger(String key, int value);
 
    public void putMemento(IMemento memento);
 
    public void putString(String key, String value);
 
    public void putTextData(String data);
}
Eclipse 中 XMLMemento 实现了 IMemento 接口,通过 XMLMemento 对象, Eclipse 能把当前 UI 的状态持久化到文件系统中,其中 createChild 方法为创建下一级 IMemento 节点, getChild 方法返回下一级 IMemento 节点。
24.4.2 UI 持久化与恢复的实现
Eclipse UI 的设计目标之一,就是在多次会话之间保持用户体验的连贯性。当一次会话结束时,工作台会保存当前的配置和工作台窗口的内容;用户开始新的一次会话时,工作台将这些状态恢复到上一次会话结束之前的样子。
Eclipse UI 持久化的过程比较复杂,因 UI 要持久化的内容比较多,包括编辑器、视图、视角、 page 和 window 的状态,但持久化的方式一样,持久化的步骤如下:
( 1 )创建 XMLMemento 对象,并保存,实现类为 Workbench ,如下代码片段所示。
                   XMLMemento memento = XMLMemento
                                     .createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH);
                   IStatus status = saveState(memento);o);
( 2 )得到所有的工作台窗口( WorkbenchWindow ),保存所有窗口的状态,实现类为 Workbench ,如下代码片段所示。
                   IWorkbenchWindow[] windows = getWorkbenchWindows();
                   for (int nX = 0; nX < windows.length; nX++) {
                            WorkbenchWindow window = (WorkbenchWindow) windows[nX];
                            IMemento childMem = memento
                                               .createChild(IWorkbenchConstants.TAG_WINDOW);
                            result.merge(window.saveState(childMem));
                   }
( 3 )得到工作台窗口包括的 Page ( WorkbenchPage )页,并保存 Page 页的状态,实现类为 WorkbenchWindow ,如下代码片段所示。
        Iterator itr = pageList.iterator();
        while (itr.hasNext()) {
            WorkbenchPage page = (WorkbenchPage) itr.next();
 
            IMemento pageMem = memento
                    .createChild(IWorkbenchConstants.TAG_PAGE);
            pageMem.putString(IWorkbenchConstants.TAG_LABEL, page.getLabel());
            result.add(page.saveState(pageMem));
 
            if (page == getActiveWorkbenchPage()) {
                pageMem.putString(IWorkbenchConstants.TAG_FOCUS, "true"); //$NON-NLS-1$
            }
 
            IAdaptable input = page.getInput();
            if (input != null) {
                IPersistableElement persistable = (IPersistableElement) input
                        .getAdapter(IPersistableElement.class);
                if (persistable == null) {
                    WorkbenchPlugin
                            .log("Unable to save page input: " //$NON-NLS-1$
                                    + input
                                    + ", because it does not adapt to IPersistableElement");
                } else {
                    IMemento inputMem = pageMem
                            .createChild(IWorkbenchConstants.TAG_INPUT);
                    inputMem.putString(IWorkbenchConstants.TAG_FACTORY_ID,
                            persistable.getFactoryId());
                    persistable.saveState(inputMem);
                }
            }
        }
( 4 )保存 Page 页中所有的编辑器、视图、视角的状态,通过 EditorManager 、 ViewFactory 和 Perspective 保存编辑器、视图、视角的状态,实现类为 WorkbenchPage ,如下代码片段所示。
        IMemento childMem = memento
                .createChild(IWorkbenchConstants.TAG_EDITORS);
        result.merge(editorMgr.saveState(childMem));
 
        childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
        result.merge(getViewFactory().saveState(childMem));
        Iterator itr = perspList.iterator();
        while (itr.hasNext()) {
            Perspective persp = (Perspective) itr.next();
            IMemento gChildMem = childMem
                    .createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
            result.merge(persp.saveState(gChildMem));
        }
( 5 )把最底层的 XMLMemento 保存到文件,实现类为 Workbench ,如下代码片段所示。
         private boolean saveMementoToFile(XMLMemento memento) {
                   File stateFile = getWorkbenchStateFile();
                   if (stateFile == null)
                            return false;
                   try {
                            FileOutputStream stream = new FileOutputStream(stateFile);
                            OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8");
                            memento.save(writer);
                            writer.close();
                   } catch (IOException e) {
                            stateFile.delete();
                            MessageDialog.openError((Shell) null,
                                               WorkbenchMessages.SavingProblem,
                                              WorkbenchMessages.ProblemSavingState);
                            return false;
                   }
 
                   return true;
         }
如上的步骤只是列出了持久化的过程,并没有完全列出持久化的所有代码,读者可以通过实现类找到具体代码的实现。
当 Eclipse 重新启动时, Eclipse 将通过从文件中读取相应的 XMLMemento 信息 ,恢复上一次退出 Eclipse 时的状态,具体步骤如下:
( 1 )从文件中读取 XMLMemento 信息,实现类为 Workbench ,如下代码片段如示。
                   final File stateFile = getWorkbenchStateFile();
                   if (stateFile == null || !stateFile.exists()) {
                            String msg = WorkbenchMessages.Workbench_noStateToRestore;
                            return new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH,
                                               IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null);
                   }
                   FileInputStream input = new FileInputStream(stateFile);
                   BufferedReader reader = new BufferedReader(
                                                        new InputStreamReader(input, "utf-8"));
                   IMemento memento = XMLMemento.createReadRoot(reader);
         ….
        IStatus restoreResult = restoreState(memento);
( 2 )从 XMLMemento 读取所有窗口信息,并恢复窗口,实现类为 Workbench ,如下代码片段所示。
                   IMemento[] children = memento
                       .getChildren(IWorkbenchConstants.TAG_WINDOW);
                  
                   createdWindows = new WorkbenchWindow[children.length];
                  
                   for (int i = 0; i < children.length; i++) {
                            childMem = children[i];
                            WorkbenchWindow newWindow = newWorkbenchWindow();
                            createdWindows[i] = newWindow;
                            newWindow.create();
                           
                            windowManager.add(newWindow);
                           
                            boolean restored = false;
                            try {
                                     status.merge(newWindow.restoreState(childMem, null));
                                     try {
                                               newWindow.fireWindowRestored();
                                     } catch (WorkbenchException e) {
                                               status.add(e.getStatus());
                                     }
                                     restored = true;
                            } finally {
                                     if (!restored) {
                                               createdWindows[i] = null;
                                               newWindow.close();
                                     }
                            }
                   }
( 3 )恢复所有 Page 的状态,实现类为 WorkbenchWindow ,如下代码片段所示。
            WorkbenchPage newPage = null;
            try {
                newPage = new WorkbenchPage(this, input);
                result.add(newPage.restoreState(pageMem, activeDescriptor));
                pageList.add(newPage);
                firePageOpened(newPage);
            } catch (WorkbenchException e) {
                WorkbenchPlugin
                        .log("Unable to restore perspective - constructor failed.", e);
                result.add(e.getStatus());
                continue;
            }
( 4 )恢复所有编辑器、视图和视角的状态,通过 EditorManager 、 ViewFactory 和 Perspective 恢复编辑器、视图、视角的状态,实现类为 WorkbenchPage ,如下代码片段所示。
                IMemento childMem = memento
                        .getChild(IWorkbenchConstants.TAG_EDITORS);
                result.merge(getEditorManager().restoreState(childMem));
   
                childMem = memento.getChild(IWorkbenchConstants.TAG_VIEWS);
                if (childMem != null)
                    result.merge(getViewFactory().restoreState(childMem));
                IMemento perspMems[] = childMem
                        .getChildren(IWorkbenchConstants.TAG_PERSPECTIVE);
                Perspective activePerspective = null;
                for (int i = 0; i < perspMems.length; i++) {
                    try {
                        Perspective persp = new Perspective(null, this);
                        result.merge(persp.restoreState(perspMems[i]));
                        IPerspectiveDescriptor desc = persp.getDesc();
                        if (desc.equals(activeDescriptor))
                            activePerspective = persp;
                        else if ((activePerspective == null)
                                && desc.getId().equals(activePerspectiveID))
                            activePerspective = persp;
                        perspList.add(persp);
                        window.firePerspectiveOpened(this, desc);
                    } catch (WorkbenchException e) {
                    }
                }
Eclipse 中, EditorManager ViewFactory 负责编辑器和视图的持久化和恢复,另外还处理编辑器和视图的相关操作,读者可以跟踪 EditorManager ViewFactory 中的方法,了解跟编辑器和视图持久化的实现。  

RabbitMQ持久化机制

之前其实已经写过一篇关于RabbitMQ持久化的 文章 ,但那篇文章侧重代码层面的写入流程,对于持久化操作何时发生以及什么时候会刷新到磁盘等问题其实都没有搞清楚,这篇文章着重于关注这些问题。 消...
  • yongche_shi
  • yongche_shi
  • 2016年05月25日 18:21
  • 2824

【Redis缓存机制】9.快照持久化和AOF持久化

持久化功能 redis为了内部数据的安全考虑,会把本身的数据以文件形式保存到硬盘中一份,在服务器 重启之后会把硬盘中的数据恢复到内存(redis)的里边。 数据保存到硬盘的过程就称为“持久化”效果。...
  • u013517797
  • u013517797
  • 2016年12月01日 15:37
  • 2243

Kafka学习(三):Kafka的内部机制深入(持久化,分布式,通讯协议)

一.Kafka的持久化 1.数据持久化:      发现线性的访问磁盘(即:按顺序的访问磁盘),很多时候比随机的内存访问快得多,而且有利于持久化;     传统的使用内存做为磁盘的缓存     K...
  • ZuoAnYinXiang
  • ZuoAnYinXiang
  • 2016年03月16日 15:58
  • 5159

“戏”说Spark-Spark核心-RDD 持久化机制详解

RDD有一个叫持久化的机制,就是在不同操作间,持久化(或缓存)一个数据集在内存中。当你持久化一个RDD,每一个结点都将把它的计算分块结果保存在内存中,并在对此数据集(或者衍生出的数据集)进行的其它动作...
  • weixin_35602748
  • weixin_35602748
  • 2017年11月29日 17:06
  • 46

Redis持久化机制和虚拟内存的使用

Redis数据都在内存中,经常要把内存的数据同步到硬盘中来保证持久化 持久化的方式: RDB:1.Snapshotting AOF:2.Append-only file http://www.redi...
  • dingsai88
  • dingsai88
  • 2015年02月23日 02:45
  • 1096

Redis源码剖析和注释(十七)--- RDB持久化机制

Redis RDB持久化机制1. RDB的介绍因为Redis是内存数据库,因此将数据存储在内存中,如果一旦服务器进程退出,服务器中的数据库状态就会消失不见,为了解决这个问题,Redis提供了两种持久化...
  • men_wen
  • men_wen
  • 2017年05月06日 07:28
  • 1305

NoSQL之Redis高级命令详解--持久化机制

Redis的持久化机制 Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中得数据同步到硬盘来保证持久化。 Redis目前支持两种持久化方式: 1.snapshotting(快照...
  • liutingxu1
  • liutingxu1
  • 2013年12月05日 11:54
  • 868

Redis数据持久化机制AOF原理分析二

本文所引用的源码全部来自Redis2.8.2版本。 Redis AOF数据持久化机制的实现相关代码是redis.c, redis.h, aof.c, bio.c, rio.c, config.c ...
  • Acceptedxukai
  • Acceptedxukai
  • 2014年01月12日 15:36
  • 6544

深入剖析Redis RDB持久化机制

http://blog.nosqlfan.com/html/4039.html
  • DBAdream
  • DBAdream
  • 2014年05月13日 18:12
  • 545

redis持久化机制

redis持久化机制redis 是一个支持持久化的内存数据库,也就是说 redis 需要经常将内存中的数据同步到磁盘 来保证持久化。redis 支持两种持久化方式,一种是 Snapshotting(快...
  • zhengyong15984285623
  • zhengyong15984285623
  • 2016年04月17日 12:20
  • 711
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UI持久化机制
举报原因:
原因补充:

(最多只允许输入30个字)