<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    XMLMemento對象的相關分析

    Posted on 2007-04-26 18:00 nemo 閱讀(2150) 評論(1)  編輯  收藏 所屬分類: EclipseRCP/SWT/JFACE

       今天發現了Eclispe的XMLMemento的一個Bug??磥聿皇亲约簩懙某绦虻拇_應該謹慎使用,即使是Eclipse的官方包也要小心。發現這個bug花了我3個小時,最后只得自己重寫一個XMLMemento.
       當我們往XMLMemento對象中寫入數據并保存后,XMLMemento會識別XML文件每行的終止位置,并在保存的時候會自動調用println()方法。而println()方法是與平臺無關的,我們可以隨便使用。
       但是,假如我們重新從保存的文件中抽取XMLMemento對象,就會發現,這個XMLMemento對象同我們原來的XMLMemento對象相比,增加了文本(Text)節點,而這個文本節點中僅包含一個字符'\n',這在Unix系統下是一個換行符,因而XMLMemento類對其做了相應的轉換:

        private static final class DOMWriter extends PrintWriter {

            
    private static String getReplacement(char c) {
                
    // Encode special XML characters into the equivalent character references.
                
    // The first five are defined by default for all XML documents.
                
    // The next three (#xD, #xA, #x9) are encoded to avoid them
                
    // being converted to spaces on deserialization
                
    // (fixes bug 93720)
                switch (c) {
                         ......

                    case '\r':
                        
    return "#x0D"//$NON-NLS-1$
                    case '\n':
                        
    return "#x0A"//$NON-NLS-1$
                         ......

                }

                
    return null;
            }

    }

    但是這種轉換相對于Windows平臺來說卻相當糟糕。因為windows平臺下的換行符是"\r\n",而不是"\n",因而如果再次保存該XMLMemento對象就會出現亂碼,這會在每個/>結束時出現 字符串。
    XMLMemento對象是為了保存當前會話的快照,以便使用戶能夠在兩次使用應用程序過程中得到一致性的操作體驗。這對于一般的程序來說,因為從來不使用XMLMement對象中的textData,而且在最后保存的過程中會重新創建一個XMLMemento對象來保存當前的狀態,這個XMLMemento對象同上一次的XMLMemento對象沒有關系。但是對于想要在整個應用程序期間使用同一個XMLMemento的需求來說,可能是一個很壞的消息。因為兩次保存的結果會不一致,最終原來使用的代碼將無法解析模型。

    XMLMemento還有對中國人來說一個更討厭的地方,這就是它只支持UTF-8格式,在它的內部創建了一個DOMWriter私有類,將首行代碼寫死在了程序里:


        private static final class DOMWriter extends PrintWriter {

            
    /* constants */
            
    private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"//$NON-NLS-1$

    }

    真讓人不爽。因為雖然XMLMemento有其被建議使用的范圍:

    org.eclipse.ui.IMemento
    Interface to a memento used 
    for saving the important state of an object in a form that can be persisted in the file system. 

    Mementos were designed with the following requirements in mind: 

    Certain objects need to be saved and restored across platform sessions. 
    When an object is restored, an appropriate 
    class for an object might not be available. It must be possible to skip an object in this case
    When an object is restored, the appropriate 
    class for the object may be different from the one when the object was originally saved. If so, the new class should still be able to read the old form of the data. 

    Mementos meet these requirements by providing support 
    for storing a mapping of arbitrary string keys to primitive values, and by allowing mementos to have other mementos as children (arranged into a tree). A robust external storage format based on XML is used. 

    The key 
    for an attribute may be any alpha numeric value. However, the value of TAG_ID is reserved for internal use. 

    This 
    interface is not intended to be implemented or extended by clients. 



    但是XMLMemento可以支持的功能實際上非常強大,可以作為現成的簡單XML文件解析器。使用其創建XML,以及從XML文件中提取模型很方便。
    所以,如果想要使用XMLMemento做這方面的事情的話,只能改Eclipse的代碼了……幸好XMLMemento只是實現了一個IMemento接口,是頂層類。因而我們可以簡單的將其復制出來。
    然后改動以下地方:

    1.改變出錯信息的提示(默認寫入系統.log文件,取消該依賴關系,改為在終端輸出或刪掉都可);
    2.改變DOMWriter中的XML_VERSION值,改為你需要的字符集(也可以將這個字段提取出來,根據需要動態的改變)。
    3.改變getReplaceMent()方法,改變例示如下:

            private static String getReplacement(char c) {
                
    // Encode special XML characters into the equivalent character references.
                
    // The first five are defined by default for all XML documents.
                
    // The next three (#xD, #xA, #x9) are encoded to avoid them
                
    // being converted to spaces on deserialization
                
    // (fixes bug 93720)
                switch (c) {
                    
    case '<' :
                        
    return "lt"//$NON-NLS-1$
                    case '>' :
                        
    return "gt"//$NON-NLS-1$
                    case '"' :
                        
    return "quot"//$NON-NLS-1$
                    case '\'' :
                        return "apos"//$NON-NLS-1$
                    case '&' :
                        
    return "amp"//$NON-NLS-1$
                    case '\r':
                        
    return "#x0D"//$NON-NLS-1$
                    case '\n':
                        
    return System.getProperty("line.separator"); //$NON-NLS-1$
                    case '\u0009':
                        
    return "#x09"//$NON-NLS-1$
                }

                
    return null;
    }

    4.改變appendEscapedChar方法,改變例示如下:

            private static void appendEscapedChar(StringBuffer buffer, char c) {
                String replacement 
    = getReplacement(c);
                
    if (replacement != null{
                    
    if(replacement.equals(System.getProperty("line.separator")))
                        buffer.append(replacement);
                    
    else{
                    buffer.append(
    '&');
                    buffer.append(replacement);
                    buffer.append(
    ';');
                    }

                }
     else {
                    buffer.append(c);
                }

            }

    }



     附:提交的Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=184175

    Build ID: M20060921-0945
    Steps To Reproduce:
    1.create an XMLMemento instance
    2.create elements
    3.save the instance into .xml file
    Note: i haven't put textData into the memento, but when i save contents of the
    memento into the file, the system will put '\n' into the file.
    4.close the file
    5.create a new XMLMemento instance from the .xml file
    6.save the new XMLMemento instance.
    7.then strange characters appears in the .xml file:

    More information:
    platform independence:
    automatically put '\n' into the .xml file is nice, but the line separator is
    0x0D0A in Windows, and it is 0x0D in Unix, so the fix should be platform
    independence.
    we can get this property from System.getProperty("line.separator");

    Feedback

    # re: XMLMemento對象的相關分析  回復  更多評論   

    2007-04-26 20:28 by BeanSoft
    開源系統需謹慎..的確如此, 還好你們很了解 Eclipse 的代碼...

    posts - 21, comments - 74, trackbacks - 0, articles - 3

    Copyright © nemo

    主站蜘蛛池模板: 羞羞漫画在线成人漫画阅读免费| 亚洲制服丝袜第一页| 福利片免费一区二区三区| 永久黄网站色视频免费观看| 亚洲视频一区二区三区四区| 91精品免费久久久久久久久| 亚洲精品亚洲人成在线麻豆| 久久九九兔免费精品6| 亚洲国产精品成人久久久| 野花高清在线观看免费3中文| 最新国产成人亚洲精品影院| 24小时日本在线www免费的| 亚洲AV无码一区二区三区牲色| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 一区二区三区免费视频网站 | 久久亚洲国产欧洲精品一| 国产黄在线播放免费观看| 亚洲自偷自偷图片| 日本免费人成网ww555在线| 91精品国产亚洲爽啪在线影院| 一本岛高清v不卡免费一三区| 日韩亚洲国产综合高清| 国产男女猛烈无遮挡免费视频网站 | 亚洲成AV人片在线观看| 亚洲免费在线观看视频| 亚洲精品无码你懂的| 亚洲婷婷国产精品电影人久久| 99在线视频免费观看| 亚洲制服丝袜在线播放| 国产猛烈高潮尖叫视频免费| 特级做A爰片毛片免费看无码 | 亚洲高清中文字幕免费| 亚洲国产精品尤物YW在线观看| a级毛片免费全部播放| 亚洲AV日韩综合一区尤物| 亚洲毛片网址在线观看中文字幕| 毛片在线播放免费观看| 亚洲色欲色欲www在线播放 | 亚洲最大视频网站| 啊灬啊灬别停啊灬用力啊免费看| 免费国产午夜高清在线视频|