1*86250549SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*86250549SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*86250549SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*86250549SAndrew Rist  * distributed with this work for additional information
6*86250549SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*86250549SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*86250549SAndrew Rist  * "License"); you may not use this file except in compliance
9*86250549SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*86250549SAndrew Rist  *
11*86250549SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*86250549SAndrew Rist  *
13*86250549SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*86250549SAndrew Rist  * software distributed under the License is distributed on an
15*86250549SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*86250549SAndrew Rist  * KIND, either express or implied.  See the License for the
17*86250549SAndrew Rist  * specific language governing permissions and limitations
18*86250549SAndrew Rist  * under the License.
19*86250549SAndrew Rist  *
20*86250549SAndrew Rist  *************************************************************/
21*86250549SAndrew Rist 
22*86250549SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir package complex.writer;
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
27cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
28cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
29cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory;
30cdf0e10cSrcweir import com.sun.star.lang.XComponent;
31cdf0e10cSrcweir import com.sun.star.lang.XServiceInfo;
32cdf0e10cSrcweir import com.sun.star.lang.NoSupportException;
33cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
34cdf0e10cSrcweir import com.sun.star.beans.XPropertySetInfo;
35cdf0e10cSrcweir import com.sun.star.beans.PropertyValue;
36cdf0e10cSrcweir import com.sun.star.beans.Pair;
37cdf0e10cSrcweir import com.sun.star.beans.StringPair;
38cdf0e10cSrcweir import com.sun.star.container.XNamed;
39cdf0e10cSrcweir import com.sun.star.container.XChild;
40cdf0e10cSrcweir import com.sun.star.container.XIndexAccess;
41cdf0e10cSrcweir import com.sun.star.container.XNameAccess;
42cdf0e10cSrcweir import com.sun.star.container.XContentEnumerationAccess;
43cdf0e10cSrcweir import com.sun.star.container.XEnumerationAccess;
44cdf0e10cSrcweir import com.sun.star.container.XEnumeration;
45cdf0e10cSrcweir import com.sun.star.container.NoSuchElementException;
46cdf0e10cSrcweir import com.sun.star.frame.XStorable;
47cdf0e10cSrcweir import com.sun.star.util.XCloseable;
48cdf0e10cSrcweir import com.sun.star.text.XText;
49cdf0e10cSrcweir import com.sun.star.text.XTextContent;
50cdf0e10cSrcweir import com.sun.star.text.XTextDocument;
51cdf0e10cSrcweir import com.sun.star.text.XTextRange;
52cdf0e10cSrcweir import com.sun.star.text.XTextCursor;
53cdf0e10cSrcweir import com.sun.star.text.XWordCursor;
54cdf0e10cSrcweir import com.sun.star.text.XSentenceCursor;
55cdf0e10cSrcweir import com.sun.star.text.XParagraphCursor;
56cdf0e10cSrcweir import com.sun.star.text.XFootnote;
57cdf0e10cSrcweir import com.sun.star.text.XTextField;
58cdf0e10cSrcweir import com.sun.star.text.XBookmarksSupplier;
59cdf0e10cSrcweir import com.sun.star.text.XTextSectionsSupplier;
60cdf0e10cSrcweir import com.sun.star.text.XDocumentIndexesSupplier;
61cdf0e10cSrcweir import com.sun.star.text.TextContentAnchorType;
62cdf0e10cSrcweir import static com.sun.star.text.TextContentAnchorType.*;
63cdf0e10cSrcweir import static com.sun.star.text.ControlCharacter.*;
64cdf0e10cSrcweir import com.sun.star.rdf.XMetadatable;
65cdf0e10cSrcweir import com.sun.star.rdf.Statement;
66cdf0e10cSrcweir import com.sun.star.rdf.XDocumentRepository;
67cdf0e10cSrcweir import com.sun.star.rdf.XRepositorySupplier;
68cdf0e10cSrcweir import org.junit.After;
69cdf0e10cSrcweir import org.junit.AfterClass;
70cdf0e10cSrcweir import org.junit.Before;
71cdf0e10cSrcweir import org.junit.BeforeClass;
72cdf0e10cSrcweir import org.junit.Test;
73cdf0e10cSrcweir import org.openoffice.test.OfficeConnection;
74cdf0e10cSrcweir import static org.junit.Assert.*;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir import java.util.Map;
77cdf0e10cSrcweir import java.util.HashMap;
78cdf0e10cSrcweir import java.util.List;
79cdf0e10cSrcweir import java.util.ArrayList;
80cdf0e10cSrcweir import java.util.Stack;
81cdf0e10cSrcweir 
82cdf0e10cSrcweir 
83cdf0e10cSrcweir class TreeNodeEnum
84cdf0e10cSrcweir {
85cdf0e10cSrcweir     private Object[] m_Elements;
86cdf0e10cSrcweir     private int m_Pos;
TreeNodeEnum(Object[] Elements)87cdf0e10cSrcweir     TreeNodeEnum(Object[] Elements) { m_Elements = Elements; m_Pos = 0; }
hasNext()88cdf0e10cSrcweir     boolean hasNext() { return m_Pos < m_Elements.length; }
next()89cdf0e10cSrcweir     TreeNode next() { return (TreeNode) m_Elements[m_Pos++]; }
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir /** base class for tree nodes. only instance: root of tree. */
93cdf0e10cSrcweir class TreeNode
94cdf0e10cSrcweir {
95cdf0e10cSrcweir     private List<TreeNode> m_Children;
getType()96cdf0e10cSrcweir     String getType() { return "__ROOT__"; }
hasContent()97cdf0e10cSrcweir     boolean hasContent() { return false; }
isNesting()98cdf0e10cSrcweir     boolean isNesting() { return false; }
dup()99cdf0e10cSrcweir     TreeNode dup() { throw new RuntimeException("TreeNode.dup"); }
createEnumeration()100cdf0e10cSrcweir     TreeNodeEnum createEnumeration() {
101cdf0e10cSrcweir         return new TreeNodeEnum(m_Children.toArray());
102cdf0e10cSrcweir     }
TreeNode()103cdf0e10cSrcweir     TreeNode() { m_Children = new ArrayList<TreeNode>(); }
appendChild(TreeNode child)104cdf0e10cSrcweir     TreeNode appendChild(TreeNode child)
105cdf0e10cSrcweir     { m_Children.add(child); return this; }
toString()106cdf0e10cSrcweir     public String toString() {
107cdf0e10cSrcweir         return "<" + getType() + ">";
108cdf0e10cSrcweir     }
109cdf0e10cSrcweir }
110cdf0e10cSrcweir 
111cdf0e10cSrcweir abstract class MarkNode extends TreeNode
112cdf0e10cSrcweir {
113cdf0e10cSrcweir     boolean m_isPoint;
114cdf0e10cSrcweir     boolean m_isStart = false;
115cdf0e10cSrcweir     String m_Name;
isPoint()116cdf0e10cSrcweir     boolean isPoint() { return m_isPoint; }
isStart()117cdf0e10cSrcweir     boolean isStart() { return m_isStart; }
getName()118cdf0e10cSrcweir     String getName() { return m_Name; }
MarkNode(String name)119cdf0e10cSrcweir     MarkNode(String name) { m_Name = name; m_isPoint = true; }
equals(MarkNode other)120cdf0e10cSrcweir     boolean equals(MarkNode other) {
121cdf0e10cSrcweir         return (other.m_Name.equals(m_Name)) && (other.m_isPoint == m_isPoint)
122cdf0e10cSrcweir             && (other.m_isStart == m_isStart);
123cdf0e10cSrcweir     }
toString()124cdf0e10cSrcweir     public String toString() {
125cdf0e10cSrcweir         return super.toString() + "\tname: " + m_Name +
126cdf0e10cSrcweir             "\tisPoint: " + m_isPoint + "\tisStart: " + m_isStart;
127cdf0e10cSrcweir     }
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir class BookmarkNode extends MarkNode
131cdf0e10cSrcweir {
132cdf0e10cSrcweir     private StringPair m_XmlId;
getXmlId()133cdf0e10cSrcweir     StringPair getXmlId() { return m_XmlId; }
dup()134cdf0e10cSrcweir     BookmarkNode dup() { return new BookmarkNode(getName(), getXmlId()); }
BookmarkNode(String name)135cdf0e10cSrcweir     BookmarkNode(String name) { this(name, new StringPair());  }
BookmarkNode(String name, StringPair xmlid)136cdf0e10cSrcweir     BookmarkNode(String name, StringPair xmlid) {
137cdf0e10cSrcweir         super(name); m_XmlId = xmlid;
138cdf0e10cSrcweir     }
getType()139cdf0e10cSrcweir     String getType() { return "Bookmark"; }
equals(Object other)140cdf0e10cSrcweir     public boolean equals(Object other) {
141cdf0e10cSrcweir         return (other instanceof BookmarkNode)
142cdf0e10cSrcweir             && super.equals((MarkNode) other)
143cdf0e10cSrcweir             && MetaNode.eq(((BookmarkNode) other).m_XmlId, m_XmlId);
144cdf0e10cSrcweir     }
toString()145cdf0e10cSrcweir     public String toString() {
146cdf0e10cSrcweir         return super.toString()
147cdf0e10cSrcweir             + "\txmlid: " + m_XmlId.First + "#" + m_XmlId.Second;
148cdf0e10cSrcweir     }
149cdf0e10cSrcweir }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir class BookmarkStartNode extends BookmarkNode
152cdf0e10cSrcweir {
dup()153cdf0e10cSrcweir     BookmarkStartNode dup() { return new BookmarkStartNode(getName()); }
BookmarkStartNode(String name)154cdf0e10cSrcweir     BookmarkStartNode(String name) { this(name, new StringPair()); }
BookmarkStartNode(String name, StringPair xmlid)155cdf0e10cSrcweir     BookmarkStartNode(String name, StringPair xmlid) {
156cdf0e10cSrcweir         super(name, xmlid); m_isPoint = false; m_isStart = true;
157cdf0e10cSrcweir     }
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir class BookmarkEndNode extends BookmarkNode
161cdf0e10cSrcweir {
dup()162cdf0e10cSrcweir     BookmarkEndNode dup() { return new BookmarkEndNode(getName()); }
BookmarkEndNode(String name)163cdf0e10cSrcweir     BookmarkEndNode(String name) { this(name, new StringPair()); }
BookmarkEndNode(String name, StringPair xmlid)164cdf0e10cSrcweir     BookmarkEndNode(String name, StringPair xmlid) {
165cdf0e10cSrcweir         super(name, xmlid); m_isPoint = false; m_isStart = false;
166cdf0e10cSrcweir     }
167cdf0e10cSrcweir }
168cdf0e10cSrcweir 
169cdf0e10cSrcweir class ReferenceMarkNode extends MarkNode
170cdf0e10cSrcweir {
dup()171cdf0e10cSrcweir     ReferenceMarkNode dup() { return new ReferenceMarkNode(getName()); }
ReferenceMarkNode(String name)172cdf0e10cSrcweir     ReferenceMarkNode(String name) { super(name); }
getType()173cdf0e10cSrcweir     String getType() { return "ReferenceMark"; }
equals(Object other)174cdf0e10cSrcweir     public boolean equals(Object other) {
175cdf0e10cSrcweir         return (other instanceof ReferenceMarkNode)
176cdf0e10cSrcweir             && super.equals((MarkNode) other);
177cdf0e10cSrcweir     }
178cdf0e10cSrcweir }
179cdf0e10cSrcweir 
180cdf0e10cSrcweir class ReferenceMarkStartNode extends ReferenceMarkNode
181cdf0e10cSrcweir {
dup()182cdf0e10cSrcweir     ReferenceMarkStartNode dup()
183cdf0e10cSrcweir     { return new ReferenceMarkStartNode(getName()); }
ReferenceMarkStartNode(String name)184cdf0e10cSrcweir     ReferenceMarkStartNode(String name) {
185cdf0e10cSrcweir         super(name); m_isPoint = false; m_isStart = true;
186cdf0e10cSrcweir     }
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir class ReferenceMarkEndNode extends ReferenceMarkNode
190cdf0e10cSrcweir {
dup()191cdf0e10cSrcweir     ReferenceMarkEndNode dup()
192cdf0e10cSrcweir     { return new ReferenceMarkEndNode(getName()); }
ReferenceMarkEndNode(String name)193cdf0e10cSrcweir     ReferenceMarkEndNode(String name) {
194cdf0e10cSrcweir         super(name); m_isPoint = false; m_isStart = false;
195cdf0e10cSrcweir     }
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir class DocumentIndexMarkNode extends MarkNode
199cdf0e10cSrcweir {
dup()200cdf0e10cSrcweir     DocumentIndexMarkNode dup()
201cdf0e10cSrcweir     { return new DocumentIndexMarkNode(getName()); }
DocumentIndexMarkNode(String name)202cdf0e10cSrcweir     DocumentIndexMarkNode(String name) { super(name); }
getType()203cdf0e10cSrcweir     String getType() { return "DocumentIndexMark"; }
equals(Object other)204cdf0e10cSrcweir     public boolean equals(Object other) {
205cdf0e10cSrcweir         return (other instanceof DocumentIndexMarkNode)
206cdf0e10cSrcweir             && super.equals((MarkNode) other);
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir class DocumentIndexMarkStartNode extends DocumentIndexMarkNode
211cdf0e10cSrcweir {
dup()212cdf0e10cSrcweir     DocumentIndexMarkStartNode dup()
213cdf0e10cSrcweir     { return new DocumentIndexMarkStartNode(getName()); }
DocumentIndexMarkStartNode(String name)214cdf0e10cSrcweir     DocumentIndexMarkStartNode(String name) {
215cdf0e10cSrcweir         super(name); m_isPoint = false; m_isStart = true;
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir class DocumentIndexMarkEndNode extends DocumentIndexMarkNode
220cdf0e10cSrcweir {
dup()221cdf0e10cSrcweir     DocumentIndexMarkEndNode dup()
222cdf0e10cSrcweir     { return new DocumentIndexMarkEndNode(getName()); }
DocumentIndexMarkEndNode(String name)223cdf0e10cSrcweir     DocumentIndexMarkEndNode(String name) {
224cdf0e10cSrcweir         super(name); m_isPoint = false; m_isStart = false;
225cdf0e10cSrcweir     }
226cdf0e10cSrcweir }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir abstract class ContentNode extends TreeNode
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     private String m_Content;
getContent()231cdf0e10cSrcweir     String getContent() { return m_Content; }
hasContent()232cdf0e10cSrcweir     boolean hasContent() { return true; }
ContentNode(String content)233cdf0e10cSrcweir     ContentNode(String content) {
234cdf0e10cSrcweir         m_Content = content;
235cdf0e10cSrcweir     }
appendChild(TreeNode t)236cdf0e10cSrcweir     TreeNode appendChild(TreeNode t) {
237cdf0e10cSrcweir         throw new RuntimeException("ContentNode.appendChild");
238cdf0e10cSrcweir     }
toString()239cdf0e10cSrcweir     public String toString() {
240cdf0e10cSrcweir         return super.toString() + "\tcontent: " + m_Content;
241cdf0e10cSrcweir     }
equals(ContentNode other)242cdf0e10cSrcweir     boolean equals(ContentNode other) {
243cdf0e10cSrcweir         return (other.m_Content.equals(m_Content));
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir class TextNode extends ContentNode
248cdf0e10cSrcweir {
dup()249cdf0e10cSrcweir     TextNode dup() { return new TextNode(getContent()); }
TextNode(String content)250cdf0e10cSrcweir     TextNode(String content) { super(content); }
getType()251cdf0e10cSrcweir     String getType() { return "Text"; }
equals(Object other)252cdf0e10cSrcweir     public boolean equals(Object other) {
253cdf0e10cSrcweir         return (other instanceof TextNode) && super.equals((ContentNode) other);
254cdf0e10cSrcweir     }
255cdf0e10cSrcweir }
256cdf0e10cSrcweir 
257cdf0e10cSrcweir class TextFieldNode extends ContentNode
258cdf0e10cSrcweir {
dup()259cdf0e10cSrcweir     TextFieldNode dup() { return new TextFieldNode(getContent()); }
TextFieldNode(String content)260cdf0e10cSrcweir     TextFieldNode(String content) { super(content); }
getType()261cdf0e10cSrcweir     String getType() { return "TextField"; }
equals(Object other)262cdf0e10cSrcweir     public boolean equals(Object other) {
263cdf0e10cSrcweir         return (other instanceof TextFieldNode)
264cdf0e10cSrcweir             && super.equals((ContentNode) other);
265cdf0e10cSrcweir     }
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir class FrameNode extends TreeNode
269cdf0e10cSrcweir {
270cdf0e10cSrcweir     private String m_Name;
271cdf0e10cSrcweir     private TextContentAnchorType m_Anchor;
getName()272cdf0e10cSrcweir     String getName() { return m_Name; }
getAnchor()273cdf0e10cSrcweir     TextContentAnchorType getAnchor() { return m_Anchor; }
dup()274cdf0e10cSrcweir     FrameNode dup() { return new FrameNode(getName(), getAnchor()); }
FrameNode(String name, TextContentAnchorType anchor)275cdf0e10cSrcweir     FrameNode(String name, TextContentAnchorType anchor) {
276cdf0e10cSrcweir         m_Name = name; m_Anchor = anchor;
277cdf0e10cSrcweir     }
getType()278cdf0e10cSrcweir     String getType() { return "Frame"; }
equals(Object other)279cdf0e10cSrcweir     public boolean equals(Object other) {
280cdf0e10cSrcweir         return (other instanceof FrameNode)
281cdf0e10cSrcweir             && (((FrameNode) other).m_Name.equals(m_Name))
282cdf0e10cSrcweir             && (((FrameNode) other).m_Anchor == m_Anchor);
283cdf0e10cSrcweir     }
toString()284cdf0e10cSrcweir     public String toString() {
285cdf0e10cSrcweir         return super.toString()
286cdf0e10cSrcweir             + "\tname: " + m_Name + "\tanchor: " + toString(m_Anchor);
287cdf0e10cSrcweir     }
toString(TextContentAnchorType anchor)288cdf0e10cSrcweir     static String toString(TextContentAnchorType anchor) {
289cdf0e10cSrcweir         switch (anchor.getValue()) {
290cdf0e10cSrcweir             case AS_CHARACTER_value: return "AS_CHARACTER";
291cdf0e10cSrcweir             case AT_CHARACTER_value: return "AT_CHARACTER";
292cdf0e10cSrcweir             case AT_PARAGRAPH_value: return "AT_PARAGRAPH";
293cdf0e10cSrcweir             case AT_PAGE_value:      return "AT_PAGE";
294cdf0e10cSrcweir             case AT_FRAME_value:     return "AT_FRAME";
295cdf0e10cSrcweir             default: throw new RuntimeException("unknown anchor");
296cdf0e10cSrcweir         }
297cdf0e10cSrcweir     }
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir class FootnoteNode extends TreeNode
301cdf0e10cSrcweir {
302cdf0e10cSrcweir     private String m_Label;
getLabel()303cdf0e10cSrcweir     String getLabel() { return m_Label; }
dup()304cdf0e10cSrcweir     FootnoteNode dup() { return new FootnoteNode(getLabel()); }
FootnoteNode(String label)305cdf0e10cSrcweir     FootnoteNode(String label) { m_Label = label; }
getType()306cdf0e10cSrcweir     String getType() { return "Footnote"; }
equals(Object other)307cdf0e10cSrcweir     public boolean equals(Object other) {
308cdf0e10cSrcweir         return (other instanceof FootnoteNode)
309cdf0e10cSrcweir             && (((FootnoteNode) other).m_Label.equals(m_Label));
310cdf0e10cSrcweir     }
toString()311cdf0e10cSrcweir     public String toString() {
312cdf0e10cSrcweir         return super.toString() + "\tlabel: " + m_Label;
313cdf0e10cSrcweir     }
314cdf0e10cSrcweir }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir class ControlCharacterNode extends TreeNode
317cdf0e10cSrcweir {
318cdf0e10cSrcweir     private short m_Char;
getChar()319cdf0e10cSrcweir     short getChar() { return m_Char; }
dup()320cdf0e10cSrcweir     ControlCharacterNode dup() { return new ControlCharacterNode(getChar()); }
ControlCharacterNode(short c)321cdf0e10cSrcweir     ControlCharacterNode(short c) { m_Char = c; }
getType()322cdf0e10cSrcweir     String getType() { return "ControlCharacter"; }
equals(Object other)323cdf0e10cSrcweir     public boolean equals(Object other) {
324cdf0e10cSrcweir         return (other instanceof ControlCharacterNode)
325cdf0e10cSrcweir             && (((ControlCharacterNode) other).m_Char == m_Char);
326cdf0e10cSrcweir     }
toString()327cdf0e10cSrcweir     public String toString() {
328cdf0e10cSrcweir         return super.toString() + "\tchar: " + m_Char;
329cdf0e10cSrcweir     }
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir class SoftPageBreakNode extends TreeNode
333cdf0e10cSrcweir {
getType()334cdf0e10cSrcweir     String getType() { return "SoftPageBreak"; }
equals(Object other)335cdf0e10cSrcweir     public boolean equals(Object other) {
336cdf0e10cSrcweir         return (other instanceof SoftPageBreakNode);
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir class HyperlinkNode extends TreeNode
341cdf0e10cSrcweir {
342cdf0e10cSrcweir     private String m_URL;
getURL()343cdf0e10cSrcweir     String getURL() { return m_URL; }
dup()344cdf0e10cSrcweir     HyperlinkNode dup() { return new HyperlinkNode(getURL()); }
HyperlinkNode(String url)345cdf0e10cSrcweir     HyperlinkNode(String url) {
346cdf0e10cSrcweir         if (url.length() == 0) throw new RuntimeException("HyperlinkNode");
347cdf0e10cSrcweir         m_URL = url;
348cdf0e10cSrcweir     }
getType()349cdf0e10cSrcweir     String getType() { return "Hyperlink"; }
isNesting()350cdf0e10cSrcweir     boolean isNesting() { return true; }
equals(Object other)351cdf0e10cSrcweir     public boolean equals(Object other) {
352cdf0e10cSrcweir         return (other instanceof HyperlinkNode)
353cdf0e10cSrcweir             && (((HyperlinkNode) other).m_URL.equals(m_URL));
354cdf0e10cSrcweir     }
toString()355cdf0e10cSrcweir     public String toString() {
356cdf0e10cSrcweir         return super.toString() + "\turl: " + m_URL;
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir class RubyNode extends TreeNode
361cdf0e10cSrcweir {
362cdf0e10cSrcweir     private String m_Ruby;
getRubyText()363cdf0e10cSrcweir     String getRubyText() { return m_Ruby; }
dup()364cdf0e10cSrcweir     RubyNode dup() { return new RubyNode(getRubyText()); }
RubyNode(String ruby)365cdf0e10cSrcweir     RubyNode(String ruby) {
366cdf0e10cSrcweir         if (ruby.length() == 0) throw new RuntimeException("RubyNode");
367cdf0e10cSrcweir         m_Ruby = ruby;
368cdf0e10cSrcweir     }
getType()369cdf0e10cSrcweir     String getType() { return "Ruby"; }
isNesting()370cdf0e10cSrcweir     boolean isNesting() { return true; }
equals(Object other)371cdf0e10cSrcweir     public boolean equals(Object other) {
372cdf0e10cSrcweir         return (other instanceof RubyNode)
373cdf0e10cSrcweir             && (((RubyNode) other).m_Ruby.equals(m_Ruby));
374cdf0e10cSrcweir     }
toString()375cdf0e10cSrcweir     public String toString() {
376cdf0e10cSrcweir         return super.toString() + "\trubytext: " + m_Ruby;
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir class MetaNode extends TreeNode
381cdf0e10cSrcweir {
382cdf0e10cSrcweir     private StringPair m_XmlId;
getXmlId()383cdf0e10cSrcweir     StringPair getXmlId() { return m_XmlId; }
dup()384cdf0e10cSrcweir     MetaNode dup() { return new MetaNode(getXmlId()); }
MetaNode(StringPair xmlid)385cdf0e10cSrcweir     MetaNode (StringPair xmlid) { m_XmlId = xmlid; }
getType()386cdf0e10cSrcweir     String getType() { return "InContentMetadata"; }
isNesting()387cdf0e10cSrcweir     boolean isNesting() { return true; }
equals(Object other)388cdf0e10cSrcweir     public boolean equals(Object other) {
389cdf0e10cSrcweir         return (other instanceof MetaNode)
390cdf0e10cSrcweir             && eq(((MetaNode) other).m_XmlId, m_XmlId);
391cdf0e10cSrcweir     }
eq(StringPair left, StringPair right)392cdf0e10cSrcweir     static boolean eq(StringPair left, StringPair right)
393cdf0e10cSrcweir     {
394cdf0e10cSrcweir         return left.First.equals(right.First)
395cdf0e10cSrcweir             && left.Second.equals(right.Second);
396cdf0e10cSrcweir     }
toString()397cdf0e10cSrcweir     public String toString() {
398cdf0e10cSrcweir         return super.toString()
399cdf0e10cSrcweir             + "\txmlid: " + m_XmlId.First + "#" + m_XmlId.Second;
400cdf0e10cSrcweir     }
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir class MetaFieldNode extends MetaNode
404cdf0e10cSrcweir {
dup()405cdf0e10cSrcweir     MetaFieldNode dup() { return new MetaFieldNode(getXmlId()); }
MetaFieldNode(StringPair xmlid)406cdf0e10cSrcweir     MetaFieldNode (StringPair xmlid) { super(xmlid); }
getType()407cdf0e10cSrcweir     String getType() { return "MetadataField"; }
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir class Range
411cdf0e10cSrcweir {
412cdf0e10cSrcweir     private short m_Start;
413cdf0e10cSrcweir     private short m_End;
414cdf0e10cSrcweir     private TreeNode m_Node;
getStart()415cdf0e10cSrcweir     short getStart()    { return m_Start; }
getEnd()416cdf0e10cSrcweir     short getEnd()      { return m_End  ; }
getExtent()417cdf0e10cSrcweir     short getExtent()   { return (short) (m_End - m_Start); }
getNode()418cdf0e10cSrcweir     TreeNode getNode()  { return m_Node; }
Range(int start, int end, TreeNode node)419cdf0e10cSrcweir     Range(int start, int end, TreeNode node)
420cdf0e10cSrcweir     { m_Start = (short) start; m_End = (short) end; m_Node = node; }
421cdf0e10cSrcweir }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir //----------------------------------------------------------------------
424cdf0e10cSrcweir 
425cdf0e10cSrcweir /* this is where we nail the pudding to the wall */
426cdf0e10cSrcweir class FuzzyTester
427cdf0e10cSrcweir {
428cdf0e10cSrcweir     private long m_DiffContent = 0;
429cdf0e10cSrcweir     private long m_DiffMissing = 0;
430cdf0e10cSrcweir     private long m_DiffNesting = 0;
431cdf0e10cSrcweir     private long m_DiffSpuriousEmptyText = 0;
432cdf0e10cSrcweir     private long m_DiffSequence = 0; // ignored?
433cdf0e10cSrcweir     private Stack<Pair<TreeNode, TreeNodeEnum>> m_StackExpected;
434cdf0e10cSrcweir     private Stack<Pair<TreeNode, TreeNodeEnum>> m_StackActual;
435cdf0e10cSrcweir     private List<TreeNode> m_BufferExpected;
436cdf0e10cSrcweir     private List<TreeNode> m_BufferActual;
437cdf0e10cSrcweir 
FuzzyTester()438cdf0e10cSrcweir     FuzzyTester() {
439cdf0e10cSrcweir         m_BufferExpected = new ArrayList<TreeNode>();
440cdf0e10cSrcweir         m_BufferActual = new ArrayList<TreeNode>();
441cdf0e10cSrcweir         m_StackExpected = new Stack<Pair<TreeNode, TreeNodeEnum>>();
442cdf0e10cSrcweir         m_StackActual = new Stack<Pair<TreeNode, TreeNodeEnum>>();
443cdf0e10cSrcweir     }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     /** idea: traverse both trees, enumerate nodes, stopping at content nodes.
446cdf0e10cSrcweir         then compare buffers. */
doTest(TreeNode expected, TreeNode actual)447cdf0e10cSrcweir     void doTest(TreeNode expected, TreeNode actual)
448cdf0e10cSrcweir     {
449cdf0e10cSrcweir         assertEquals("__ROOT__", expected.getType());
450cdf0e10cSrcweir         assertEquals("__ROOT__", actual.getType());
451cdf0e10cSrcweir         m_StackExpected.push(new Pair(expected, expected.createEnumeration()));
452cdf0e10cSrcweir         m_StackActual.push(new Pair(actual, actual.createEnumeration()));
453cdf0e10cSrcweir         do {
454cdf0e10cSrcweir             traverse(m_StackExpected, m_BufferExpected);
455cdf0e10cSrcweir             traverse(m_StackActual, m_BufferActual);
456cdf0e10cSrcweir         //??? root?
457cdf0e10cSrcweir             testBuffer();
458cdf0e10cSrcweir         } while (!m_StackExpected.empty() || !m_StackActual.empty());
459cdf0e10cSrcweir         if (m_DiffSequence != 0) {
460cdf0e10cSrcweir             System.out.println("warning: " +  m_DiffSequence
461cdf0e10cSrcweir                     + " differences in sequence");
462cdf0e10cSrcweir         }
463cdf0e10cSrcweir         if (m_DiffSpuriousEmptyText != 0) {
464cdf0e10cSrcweir             System.out.println("warning: " +  m_DiffSpuriousEmptyText
465cdf0e10cSrcweir                     + " spurious empty text nodes");
466cdf0e10cSrcweir         }
467cdf0e10cSrcweir         if (m_DiffNesting != 0) {
468cdf0e10cSrcweir             System.out.println("WARNING: " +  m_DiffNesting
469cdf0e10cSrcweir                     + " differences in nesting");
470cdf0e10cSrcweir         }
471cdf0e10cSrcweir         assertEquals(0, m_DiffContent);
472cdf0e10cSrcweir         assertEquals(0, m_DiffMissing);
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir 
traverse(Stack<Pair<TreeNode, TreeNodeEnum>> stack, List<TreeNode> buffer)475cdf0e10cSrcweir     private void traverse(Stack<Pair<TreeNode, TreeNodeEnum>> stack,
476cdf0e10cSrcweir                   List<TreeNode> buffer)
477cdf0e10cSrcweir     {
478cdf0e10cSrcweir         while (!stack.empty()) {
479cdf0e10cSrcweir             TreeNodeEnum topEnum = stack.peek().Second;
480cdf0e10cSrcweir             if (topEnum.hasNext()) {
481cdf0e10cSrcweir                 TreeNode node = topEnum.next();
482cdf0e10cSrcweir                 buffer.add(node);
483cdf0e10cSrcweir                 TreeNodeEnum nodeEnum = node.createEnumeration();
484cdf0e10cSrcweir                 if (nodeEnum.hasNext()) {
485cdf0e10cSrcweir                     stack.push(new Pair(node, nodeEnum));
486cdf0e10cSrcweir                 }
487cdf0e10cSrcweir                 if (node.hasContent()) {
488cdf0e10cSrcweir                     if (!((node instanceof TextNode) // spurious empty text?
489cdf0e10cSrcweir                         && ((TextNode) node).getContent().length() == 0)) {
490cdf0e10cSrcweir                             return; // break here
491cdf0e10cSrcweir                     }
492cdf0e10cSrcweir                 }
493cdf0e10cSrcweir             } else {
494cdf0e10cSrcweir                 buffer.add(stack.peek().First);
495cdf0e10cSrcweir                 stack.pop();
496cdf0e10cSrcweir             }
497cdf0e10cSrcweir         }
498cdf0e10cSrcweir     }
499cdf0e10cSrcweir 
testTerminatingNode()500cdf0e10cSrcweir     private void testTerminatingNode()
501cdf0e10cSrcweir     {
502cdf0e10cSrcweir         int lenExpected = m_BufferExpected.size();
503cdf0e10cSrcweir         int lenActual   = m_BufferActual.size();
504cdf0e10cSrcweir         if (lenExpected == 0 || lenActual == 0)
505cdf0e10cSrcweir             return;
506cdf0e10cSrcweir         TreeNode expected = m_BufferExpected.get(lenExpected - 1);
507cdf0e10cSrcweir         TreeNode actual = m_BufferActual.get(lenActual - 1);
508cdf0e10cSrcweir 
509cdf0e10cSrcweir         boolean eRoot = expected.getType().equals("__ROOT__");
510cdf0e10cSrcweir         boolean aRoot = actual.getType().equals("__ROOT__");
511cdf0e10cSrcweir         if (eRoot || aRoot) {
512cdf0e10cSrcweir             if (!(eRoot && aRoot)) {
513cdf0e10cSrcweir                 if (aRoot) printMissing(expected);
514cdf0e10cSrcweir                 else       printUnexpected(actual);
515cdf0e10cSrcweir                 m_DiffMissing++;
516cdf0e10cSrcweir             }
517cdf0e10cSrcweir             return;
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir 
520cdf0e10cSrcweir         testContentNode((ContentNode) expected, (ContentNode) actual);
521cdf0e10cSrcweir 
522cdf0e10cSrcweir         m_BufferExpected.set(lenExpected - 1, null);
523cdf0e10cSrcweir         m_BufferActual.set(lenActual - 1, null);
524cdf0e10cSrcweir     }
525cdf0e10cSrcweir 
testContentNode(ContentNode expected, ContentNode actual)526cdf0e10cSrcweir     private void testContentNode(ContentNode expected, ContentNode actual)
527cdf0e10cSrcweir     {
528cdf0e10cSrcweir         String contentExpected = expected.getContent();
529cdf0e10cSrcweir         String contentActual = actual.getContent();
530cdf0e10cSrcweir         if (!expected.equals(actual)) {
531cdf0e10cSrcweir             printDiff("text content differs", contentExpected, contentActual);
532cdf0e10cSrcweir             m_DiffContent++;
533cdf0e10cSrcweir         }
534cdf0e10cSrcweir     }
535cdf0e10cSrcweir 
testBuffer()536cdf0e10cSrcweir     private void testBuffer()
537cdf0e10cSrcweir     {
538cdf0e10cSrcweir         int lenExpected = m_BufferExpected.size();
539cdf0e10cSrcweir         int lenActual   = m_BufferActual.size();
540cdf0e10cSrcweir         for (int i = 0; i < lenExpected - 1; i++ )
541cdf0e10cSrcweir         {
542cdf0e10cSrcweir             TreeNode node = m_BufferExpected.get(i);
543cdf0e10cSrcweir             int j = m_BufferActual.indexOf(node);
544cdf0e10cSrcweir             if (j >= 0) {
545cdf0e10cSrcweir                 TreeNode other = m_BufferActual.get(j);
546cdf0e10cSrcweir                 if (j != i)
547cdf0e10cSrcweir                 {
548cdf0e10cSrcweir                     //FIXME how bad is this?
549cdf0e10cSrcweir                     printDiff("position differs",
550cdf0e10cSrcweir                             String.valueOf(i), String.valueOf(j));
551cdf0e10cSrcweir                     // a hacky hack
552cdf0e10cSrcweir                     int min = Math.min(i,j);
553cdf0e10cSrcweir                     int max = Math.max(Math.min(lenActual - 1, i),j);
554cdf0e10cSrcweir                     for (int k = min; k != max; k ++) {
555cdf0e10cSrcweir                         TreeNode tmp = m_BufferActual.get(k);
556cdf0e10cSrcweir                         if (tmp != null && tmp.isNesting()) {
557cdf0e10cSrcweir                             printNesting(node, tmp);
558cdf0e10cSrcweir                             m_DiffNesting++;
559cdf0e10cSrcweir                         }
560cdf0e10cSrcweir                     }
561cdf0e10cSrcweir                     m_DiffSequence++;
562cdf0e10cSrcweir                 }
563cdf0e10cSrcweir                 m_BufferActual.set(j, null);
564cdf0e10cSrcweir             } else {
565cdf0e10cSrcweir //System.out.println("testBuffer:");
566cdf0e10cSrcweir                 printMissing(node);
567cdf0e10cSrcweir                 m_DiffMissing++;
568cdf0e10cSrcweir             }
569cdf0e10cSrcweir         }
570cdf0e10cSrcweir         for (int j = 0; j < lenActual - 1; j++)
571cdf0e10cSrcweir         {
572cdf0e10cSrcweir             TreeNode node = m_BufferActual.get(j);
573cdf0e10cSrcweir             if (node != null)
574cdf0e10cSrcweir             {
575cdf0e10cSrcweir //System.out.println("testBuffer:");
576cdf0e10cSrcweir                 printUnexpected(node);
577cdf0e10cSrcweir                 if ((node instanceof TextNode) &&
578cdf0e10cSrcweir                         ((TextNode) node).getContent().length() == 0) {
579cdf0e10cSrcweir                     m_DiffSpuriousEmptyText++;
580cdf0e10cSrcweir                 } else {
581cdf0e10cSrcweir                     m_DiffMissing++;
582cdf0e10cSrcweir                 }
583cdf0e10cSrcweir             }
584cdf0e10cSrcweir         }
585cdf0e10cSrcweir         testTerminatingNode();
586cdf0e10cSrcweir         m_BufferExpected.clear();
587cdf0e10cSrcweir         m_BufferActual.clear();
588cdf0e10cSrcweir     }
589cdf0e10cSrcweir 
printDiff(String prefix, String expected, String actual)590cdf0e10cSrcweir     void printDiff(String prefix, String expected, String actual)
591cdf0e10cSrcweir     {
592cdf0e10cSrcweir         System.out.println(prefix +
593cdf0e10cSrcweir                 ":\texpected: " + expected + "\tactual: " + actual);
594cdf0e10cSrcweir     }
595cdf0e10cSrcweir 
printNesting(TreeNode node, TreeNode nesting)596cdf0e10cSrcweir     void printNesting(TreeNode node, TreeNode nesting)
597cdf0e10cSrcweir     {
598cdf0e10cSrcweir         System.out.println("node: " + node.toString()
599cdf0e10cSrcweir                 + " possibly moved across nesting " + nesting.toString());
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir 
printMissing(TreeNode node)602cdf0e10cSrcweir     void printMissing(TreeNode node)
603cdf0e10cSrcweir     {
604cdf0e10cSrcweir         System.out.println("   missing node: " + node.toString());
605cdf0e10cSrcweir 
606cdf0e10cSrcweir     }
607cdf0e10cSrcweir 
printUnexpected(TreeNode node)608cdf0e10cSrcweir     void printUnexpected(TreeNode node)
609cdf0e10cSrcweir     {
610cdf0e10cSrcweir         System.out.println("unexpected node: " + node.toString());
611cdf0e10cSrcweir 
612cdf0e10cSrcweir     }
613cdf0e10cSrcweir }
614cdf0e10cSrcweir 
615cdf0e10cSrcweir 
616cdf0e10cSrcweir //----------------------------------------------------------------------
617cdf0e10cSrcweir 
618cdf0e10cSrcweir class EnumConverter
619cdf0e10cSrcweir {
620cdf0e10cSrcweir     private Stack<TreeNode> m_Stack;
621cdf0e10cSrcweir 
EnumConverter()622cdf0e10cSrcweir     EnumConverter() {
623cdf0e10cSrcweir         m_Stack = new Stack<TreeNode>();
624cdf0e10cSrcweir     }
625cdf0e10cSrcweir 
convert(XEnumeration xEnum)626cdf0e10cSrcweir     TreeNode convert(XEnumeration xEnum) throws Exception
627cdf0e10cSrcweir     {
628cdf0e10cSrcweir         TreeNode root = new TreeNode();
629cdf0e10cSrcweir         m_Stack.push(root);
630cdf0e10cSrcweir         TreeNode ret = convertChildren(xEnum);
631cdf0e10cSrcweir         assertTrue("EnumConverter.convert: stack", m_Stack.empty());
632cdf0e10cSrcweir         return ret;
633cdf0e10cSrcweir     }
634cdf0e10cSrcweir 
convertChildren(XEnumeration xEnum)635cdf0e10cSrcweir     TreeNode convertChildren(XEnumeration xEnum) throws Exception
636cdf0e10cSrcweir     {
637cdf0e10cSrcweir         while (xEnum.hasMoreElements()) {
638cdf0e10cSrcweir             TreeNode node;
639cdf0e10cSrcweir             Object xElement = xEnum.nextElement();
640cdf0e10cSrcweir             XTextRange xPortion = (XTextRange)
641cdf0e10cSrcweir                 UnoRuntime.queryInterface(XTextRange.class, xElement);
642cdf0e10cSrcweir             XPropertySet xPropSet = (XPropertySet)
643cdf0e10cSrcweir                 UnoRuntime.queryInterface(XPropertySet.class, xPortion);
644cdf0e10cSrcweir             String type = (String) xPropSet.getPropertyValue("TextPortionType");
645cdf0e10cSrcweir             if (type.equals("Text")) {
646cdf0e10cSrcweir                 String text = xPortion.getString();
647cdf0e10cSrcweir                 node = new TextNode(text);
648cdf0e10cSrcweir                 String url = (String) xPropSet.getPropertyValue("HyperLinkURL");
649cdf0e10cSrcweir                 if (url.length() > 0) {
650cdf0e10cSrcweir                     TreeNode temp = node;
651cdf0e10cSrcweir                     node = new HyperlinkNode(url);
652cdf0e10cSrcweir                     node.appendChild(temp);
653cdf0e10cSrcweir                 }
654cdf0e10cSrcweir             } else if (type.equals("TextField")) {
655cdf0e10cSrcweir                 Object xField = xPropSet.getPropertyValue("TextField");
656cdf0e10cSrcweir                 XServiceInfo xService = (XServiceInfo)
657cdf0e10cSrcweir                     UnoRuntime.queryInterface(XServiceInfo.class, xField);
658cdf0e10cSrcweir                 if (xService.supportsService(
659cdf0e10cSrcweir                         "com.sun.star.text.textfield.MetadataField"))
660cdf0e10cSrcweir                 {
661cdf0e10cSrcweir                     XMetadatable xMeta = (XMetadatable)
662cdf0e10cSrcweir                         UnoRuntime.queryInterface(XMetadatable.class, xField);
663cdf0e10cSrcweir                     StringPair xmlid = xMeta.getMetadataReference();
664cdf0e10cSrcweir                     node = new MetaFieldNode(xmlid);
665cdf0e10cSrcweir                     m_Stack.push(node);
666cdf0e10cSrcweir                     XEnumerationAccess xEA = (XEnumerationAccess)
667cdf0e10cSrcweir                         UnoRuntime.queryInterface(XEnumerationAccess.class,
668cdf0e10cSrcweir                         xMeta);
669cdf0e10cSrcweir                     XEnumeration xEnumChildren = xEA.createEnumeration();
670cdf0e10cSrcweir                     TreeNode node2 = convertChildren(xEnumChildren);
671cdf0e10cSrcweir                     assertSame("stack error: meta-field", node2, node);
672cdf0e10cSrcweir                 } else {
673cdf0e10cSrcweir                     XPropertySet xFieldPropSet = (XPropertySet)
674cdf0e10cSrcweir                         UnoRuntime.queryInterface(XPropertySet.class, xField);
675cdf0e10cSrcweir                     String content = (String)
676cdf0e10cSrcweir                         xFieldPropSet.getPropertyValue("Content");
677cdf0e10cSrcweir                     boolean isFixed = (Boolean)
678cdf0e10cSrcweir                         xFieldPropSet.getPropertyValue("IsFixed");
679cdf0e10cSrcweir                     assertTrue("field not fixed?", isFixed);
680cdf0e10cSrcweir                     node = new TextFieldNode(content);
681cdf0e10cSrcweir                 }
682cdf0e10cSrcweir             } else if (type.equals("Footnote")) {
683cdf0e10cSrcweir                 Object xNote = xPropSet.getPropertyValue("Footnote");
684cdf0e10cSrcweir                 XFootnote xFootnote = (XFootnote)
685cdf0e10cSrcweir                     UnoRuntime.queryInterface(XFootnote.class, xNote);
686cdf0e10cSrcweir                 String label = xFootnote.getLabel();
687cdf0e10cSrcweir                 node = new FootnoteNode(label);
688cdf0e10cSrcweir             } else if (type.equals("Frame")) {
689cdf0e10cSrcweir                 XContentEnumerationAccess xCEA = (XContentEnumerationAccess)
690cdf0e10cSrcweir                     UnoRuntime.queryInterface(XContentEnumerationAccess.class,
691cdf0e10cSrcweir                         xPortion);
692cdf0e10cSrcweir                 XEnumeration xContentEnum = xCEA.createContentEnumeration("");
693cdf0e10cSrcweir                 while (xContentEnum.hasMoreElements()) {
694cdf0e10cSrcweir                     Object xFrame = xContentEnum.nextElement();
695cdf0e10cSrcweir                     XPropertySet xFramePropSet = (XPropertySet)
696cdf0e10cSrcweir                         UnoRuntime.queryInterface(XPropertySet.class, xFrame);
697cdf0e10cSrcweir                     TextContentAnchorType anchor = (TextContentAnchorType)
698cdf0e10cSrcweir                         xFramePropSet.getPropertyValue("AnchorType");
699cdf0e10cSrcweir                     XNamed xNamed = (XNamed)
700cdf0e10cSrcweir                         UnoRuntime.queryInterface(XNamed.class, xFrame);
701cdf0e10cSrcweir                     String name = xNamed.getName();
702cdf0e10cSrcweir                     node = new FrameNode(name, anchor);
703cdf0e10cSrcweir                     m_Stack.peek().appendChild(node);
704cdf0e10cSrcweir                 }
705cdf0e10cSrcweir                 continue;
706cdf0e10cSrcweir             } else if (type.equals("ControlCharacter")) {
707cdf0e10cSrcweir                 short c = (Short)
708cdf0e10cSrcweir                     xPropSet.getPropertyValue("ControlCharacter");
709cdf0e10cSrcweir                 node = new ControlCharacterNode(c);
710cdf0e10cSrcweir             } else if (type.equals("Bookmark")) {
711cdf0e10cSrcweir                 Object xMark = xPropSet.getPropertyValue("Bookmark");
712cdf0e10cSrcweir                 XNamed xNamed = (XNamed)
713cdf0e10cSrcweir                     UnoRuntime.queryInterface(XNamed.class, xMark);
714cdf0e10cSrcweir                 String name = xNamed.getName();
715cdf0e10cSrcweir                 XMetadatable xMetadatable = (XMetadatable)
716cdf0e10cSrcweir                     UnoRuntime.queryInterface(XMetadatable.class, xMark);
717cdf0e10cSrcweir                 StringPair xmlid = xMetadatable.getMetadataReference();
718cdf0e10cSrcweir                 boolean isCollapsed = (Boolean)
719cdf0e10cSrcweir                     xPropSet.getPropertyValue("IsCollapsed");
720cdf0e10cSrcweir                 if (isCollapsed) {
721cdf0e10cSrcweir                     node = new BookmarkNode(name, xmlid);
722cdf0e10cSrcweir                 } else {
723cdf0e10cSrcweir                     boolean isStart = (Boolean)
724cdf0e10cSrcweir                         xPropSet.getPropertyValue("IsStart");
725cdf0e10cSrcweir                     if (isStart) {
726cdf0e10cSrcweir                         node = new BookmarkStartNode(name, xmlid);
727cdf0e10cSrcweir                     } else {
728cdf0e10cSrcweir                         node = new BookmarkEndNode(name, xmlid);
729cdf0e10cSrcweir                     }
730cdf0e10cSrcweir                 }
731cdf0e10cSrcweir             } else if (type.equals("ReferenceMark")) {
732cdf0e10cSrcweir                 Object xMark = xPropSet.getPropertyValue("ReferenceMark");
733cdf0e10cSrcweir                 XNamed xNamed = (XNamed)
734cdf0e10cSrcweir                     UnoRuntime.queryInterface(XNamed.class, xMark);
735cdf0e10cSrcweir                 String name = xNamed.getName();
736cdf0e10cSrcweir                 boolean isCollapsed = (Boolean)
737cdf0e10cSrcweir                     xPropSet.getPropertyValue("IsCollapsed");
738cdf0e10cSrcweir                 if (isCollapsed) {
739cdf0e10cSrcweir                     node = new ReferenceMarkNode(name);
740cdf0e10cSrcweir                 } else {
741cdf0e10cSrcweir                     boolean isStart = (Boolean)
742cdf0e10cSrcweir                         xPropSet.getPropertyValue("IsStart");
743cdf0e10cSrcweir                     if (isStart) {
744cdf0e10cSrcweir                         node = new ReferenceMarkStartNode(name);
745cdf0e10cSrcweir                     } else {
746cdf0e10cSrcweir                         node = new ReferenceMarkEndNode(name);
747cdf0e10cSrcweir                     }
748cdf0e10cSrcweir                 }
749cdf0e10cSrcweir             } else if (type.equals("DocumentIndexMark")) {
750cdf0e10cSrcweir                 Object xMark = xPropSet.getPropertyValue("DocumentIndexMark");
751cdf0e10cSrcweir                 XPropertySet xMarkSet = (XPropertySet)
752cdf0e10cSrcweir                     UnoRuntime.queryInterface(XPropertySet.class, xMark);
753cdf0e10cSrcweir                 String name = (String) xMarkSet.getPropertyValue("PrimaryKey");
754cdf0e10cSrcweir                 boolean isCollapsed = (Boolean)
755cdf0e10cSrcweir                     xPropSet.getPropertyValue("IsCollapsed");
756cdf0e10cSrcweir                 if (isCollapsed) {
757cdf0e10cSrcweir                     node = new DocumentIndexMarkNode(name);
758cdf0e10cSrcweir                 } else {
759cdf0e10cSrcweir                     boolean isStart = (Boolean)
760cdf0e10cSrcweir                         xPropSet.getPropertyValue("IsStart");
761cdf0e10cSrcweir                     if (isStart) {
762cdf0e10cSrcweir                         node = new DocumentIndexMarkStartNode(name);
763cdf0e10cSrcweir                     } else {
764cdf0e10cSrcweir                         node = new DocumentIndexMarkEndNode(name);
765cdf0e10cSrcweir                     }
766cdf0e10cSrcweir                 }
767cdf0e10cSrcweir             } else if (type.equals("SoftPageBreak")) {
768cdf0e10cSrcweir                 node = new SoftPageBreakNode();
769cdf0e10cSrcweir             } else if (type.equals("Ruby")) {
770cdf0e10cSrcweir                 boolean isStart = (Boolean)
771cdf0e10cSrcweir                     xPropSet.getPropertyValue("IsStart");
772cdf0e10cSrcweir                 if (isStart) {
773cdf0e10cSrcweir                     // ARRGH!!! stupid api...
774cdf0e10cSrcweir                     // the text is ONLY at the start!
775cdf0e10cSrcweir                     String ruby = (String)
776cdf0e10cSrcweir                         xPropSet.getPropertyValue("RubyText");
777cdf0e10cSrcweir                     node = new RubyNode(ruby);
778cdf0e10cSrcweir                     m_Stack.push(node);
779cdf0e10cSrcweir                     continue;
780cdf0e10cSrcweir                 } else {
781cdf0e10cSrcweir                     node = m_Stack.pop();
782cdf0e10cSrcweir                     assertTrue("stack error: Ruby expected; is: " +
783cdf0e10cSrcweir                                node.toString(), node instanceof RubyNode);
784cdf0e10cSrcweir                 }
785cdf0e10cSrcweir             } else if (type.equals("InContentMetadata")) {
786cdf0e10cSrcweir                 Object xMeta = xPropSet.getPropertyValue("InContentMetadata");
787cdf0e10cSrcweir                 XMetadatable xMetadatable = (XMetadatable)
788cdf0e10cSrcweir                     UnoRuntime.queryInterface(XMetadatable.class, xMeta);
789cdf0e10cSrcweir                 StringPair xmlid = xMetadatable.getMetadataReference();
790cdf0e10cSrcweir                 node = new MetaNode(xmlid);
791cdf0e10cSrcweir                 m_Stack.push(node);
792cdf0e10cSrcweir                 XEnumerationAccess xEA = (XEnumerationAccess)
793cdf0e10cSrcweir                     UnoRuntime.queryInterface(XEnumerationAccess.class, xMeta);
794cdf0e10cSrcweir                 XEnumeration xEnumChildren = xEA.createEnumeration();
795cdf0e10cSrcweir                 TreeNode node2 = convertChildren(xEnumChildren);
796cdf0e10cSrcweir                 assertSame("stack error: meta", node2, node);
797cdf0e10cSrcweir             } else {
798cdf0e10cSrcweir                 throw new RuntimeException("unexpected type: " + type);
799cdf0e10cSrcweir             }
800cdf0e10cSrcweir             m_Stack.peek().appendChild(node);
801cdf0e10cSrcweir         }
802cdf0e10cSrcweir         TreeNode ret = m_Stack.pop();
803cdf0e10cSrcweir         return ret;
804cdf0e10cSrcweir     }
805cdf0e10cSrcweir }
806cdf0e10cSrcweir 
807cdf0e10cSrcweir 
808cdf0e10cSrcweir //----------------------------------------------------------------------
809cdf0e10cSrcweir 
810cdf0e10cSrcweir abstract class Inserter
811cdf0e10cSrcweir {
812cdf0e10cSrcweir     private XMultiServiceFactory m_xDocFactory;
813cdf0e10cSrcweir     XText m_xText;
814cdf0e10cSrcweir     XParagraphCursor m_xCursor;
815cdf0e10cSrcweir 
Inserter(XTextDocument xDoc)816cdf0e10cSrcweir     Inserter(XTextDocument xDoc)
817cdf0e10cSrcweir     {
818cdf0e10cSrcweir         m_xDocFactory = (XMultiServiceFactory)
819cdf0e10cSrcweir             UnoRuntime.queryInterface(XMultiServiceFactory.class, xDoc);
820cdf0e10cSrcweir         m_xText = xDoc.getText();
821cdf0e10cSrcweir         XTextCursor xCursor = m_xText.createTextCursor();
822cdf0e10cSrcweir         m_xCursor = (XParagraphCursor)
823cdf0e10cSrcweir             UnoRuntime.queryInterface(XParagraphCursor.class, xCursor);
824cdf0e10cSrcweir     }
825cdf0e10cSrcweir 
initParagraph()826cdf0e10cSrcweir     void initParagraph() throws Exception
827cdf0e10cSrcweir     {
828cdf0e10cSrcweir         m_xCursor.gotoStartOfParagraph(false);
829cdf0e10cSrcweir         m_xText.insertControlCharacter(m_xCursor, PARAGRAPH_BREAK, false);
830cdf0e10cSrcweir         // we split the first (empty) paragraph, and then insert into the
831cdf0e10cSrcweir         // second (empty) paragraph; this ensures first is always empty!
832cdf0e10cSrcweir     }
833cdf0e10cSrcweir 
insertControlCharacter(XTextCursor xCursor, short cchar)834cdf0e10cSrcweir     void insertControlCharacter(XTextCursor xCursor, short cchar)
835cdf0e10cSrcweir         throws Exception
836cdf0e10cSrcweir     {
837cdf0e10cSrcweir         m_xText.insertControlCharacter(xCursor, cchar, false);
838cdf0e10cSrcweir     }
839cdf0e10cSrcweir 
insertText(XTextCursor xCursor, String text)840cdf0e10cSrcweir     void insertText(XTextCursor xCursor, String text)
841cdf0e10cSrcweir     {
842cdf0e10cSrcweir         xCursor.setString(text);
843cdf0e10cSrcweir     }
844cdf0e10cSrcweir 
insertTextField(XTextCursor xCursor, String content)845cdf0e10cSrcweir     void insertTextField(XTextCursor xCursor, String content) throws Exception
846cdf0e10cSrcweir     {
847cdf0e10cSrcweir         XTextContent xContent = makeTextField(content);
848cdf0e10cSrcweir         xContent.attach(xCursor);
849cdf0e10cSrcweir     }
850cdf0e10cSrcweir 
makeTextField(String content)851cdf0e10cSrcweir     XTextContent makeTextField(String content)
852cdf0e10cSrcweir         throws Exception
853cdf0e10cSrcweir     {
854cdf0e10cSrcweir         Object xField =
855cdf0e10cSrcweir             m_xDocFactory.createInstance("com.sun.star.text.textfield.Author");
856cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
857cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xField);
858cdf0e10cSrcweir         XPropertySet xPropSet = (XPropertySet)
859cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xField);
860cdf0e10cSrcweir         xPropSet.setPropertyValue("IsFixed", true);
861cdf0e10cSrcweir         xPropSet.setPropertyValue("FullName", false);
862cdf0e10cSrcweir         xPropSet.setPropertyValue("Content", content);
863cdf0e10cSrcweir         return xContent;
864cdf0e10cSrcweir     }
865cdf0e10cSrcweir 
insertFrame(XTextRange xCursor, String name, TextContentAnchorType anchor)866cdf0e10cSrcweir     void insertFrame(XTextRange xCursor, String name,
867cdf0e10cSrcweir             TextContentAnchorType anchor) throws Exception
868cdf0e10cSrcweir     {
869cdf0e10cSrcweir         XTextContent xContent = makeFrame(name, anchor);
870cdf0e10cSrcweir         xContent.attach(xCursor);
871cdf0e10cSrcweir     }
872cdf0e10cSrcweir 
makeFrame(String name, TextContentAnchorType anchor)873cdf0e10cSrcweir     XTextContent makeFrame(String name, TextContentAnchorType anchor)
874cdf0e10cSrcweir         throws Exception
875cdf0e10cSrcweir     {
876cdf0e10cSrcweir         Object xFrame =
877cdf0e10cSrcweir             m_xDocFactory.createInstance("com.sun.star.text.TextFrame");
878cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
879cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xFrame);
880cdf0e10cSrcweir         XPropertySet xPropSet = (XPropertySet)
881cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xFrame);
882cdf0e10cSrcweir         xPropSet.setPropertyValue("AnchorType", anchor);
883cdf0e10cSrcweir         XNamed xNamed = (XNamed)
884cdf0e10cSrcweir             UnoRuntime.queryInterface(XNamed.class, xContent);
885cdf0e10cSrcweir         xNamed.setName(name);
886cdf0e10cSrcweir         return xContent;
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir 
insertFootnote(XTextCursor xCursor, String label)889cdf0e10cSrcweir     void insertFootnote(XTextCursor xCursor, String label) throws Exception
890cdf0e10cSrcweir     {
891cdf0e10cSrcweir         XTextContent xContent = makeFootnote(label);
892cdf0e10cSrcweir         xContent.attach(xCursor);
893cdf0e10cSrcweir     }
894cdf0e10cSrcweir 
makeFootnote(String label)895cdf0e10cSrcweir     XTextContent makeFootnote(String label) throws Exception
896cdf0e10cSrcweir     {
897cdf0e10cSrcweir         Object xNote =
898cdf0e10cSrcweir             m_xDocFactory.createInstance("com.sun.star.text.Footnote");
899cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
900cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xNote);
901cdf0e10cSrcweir         XFootnote xFootnote = (XFootnote)
902cdf0e10cSrcweir             UnoRuntime.queryInterface(XFootnote.class, xNote);
903cdf0e10cSrcweir         xFootnote.setLabel(label);
904cdf0e10cSrcweir         return xContent;
905cdf0e10cSrcweir     }
906cdf0e10cSrcweir 
insertBookmark(XTextCursor xCursor, String name, StringPair xmlid)907cdf0e10cSrcweir     void insertBookmark(XTextCursor xCursor, String name, StringPair xmlid)
908cdf0e10cSrcweir         throws Exception
909cdf0e10cSrcweir     {
910cdf0e10cSrcweir         XTextContent xContent = makeBookmark(name);
911cdf0e10cSrcweir         xContent.attach(xCursor);
912cdf0e10cSrcweir         if (!xmlid.First.equals(""))
913cdf0e10cSrcweir         {
914cdf0e10cSrcweir             XMetadatable xMetadatable = (XMetadatable)
915cdf0e10cSrcweir                 UnoRuntime.queryInterface(XMetadatable.class, xContent);
916cdf0e10cSrcweir             xMetadatable.setMetadataReference(xmlid);
917cdf0e10cSrcweir         }
918cdf0e10cSrcweir     }
919cdf0e10cSrcweir 
makeBookmark(String name)920cdf0e10cSrcweir     XTextContent makeBookmark(String name) throws Exception
921cdf0e10cSrcweir     {
922cdf0e10cSrcweir         Object xBookmark =
923cdf0e10cSrcweir             m_xDocFactory.createInstance("com.sun.star.text.Bookmark");
924cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
925cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xBookmark);
926cdf0e10cSrcweir         XNamed xNamed = (XNamed)
927cdf0e10cSrcweir             UnoRuntime.queryInterface(XNamed.class, xContent);
928cdf0e10cSrcweir         xNamed.setName(name);
929cdf0e10cSrcweir         return xContent;
930cdf0e10cSrcweir     }
931cdf0e10cSrcweir 
insertReferenceMark(XTextCursor xCursor, String name)932cdf0e10cSrcweir     void insertReferenceMark(XTextCursor xCursor, String name) throws Exception
933cdf0e10cSrcweir     {
934cdf0e10cSrcweir         XTextContent xContent = makeReferenceMark(name);
935cdf0e10cSrcweir         xContent.attach(xCursor);
936cdf0e10cSrcweir     }
937cdf0e10cSrcweir 
makeReferenceMark(String name)938cdf0e10cSrcweir     XTextContent makeReferenceMark(String name) throws Exception
939cdf0e10cSrcweir     {
940cdf0e10cSrcweir         Object xMark =
941cdf0e10cSrcweir             m_xDocFactory.createInstance("com.sun.star.text.ReferenceMark");
942cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
943cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xMark);
944cdf0e10cSrcweir         XNamed xNamed = (XNamed)
945cdf0e10cSrcweir             UnoRuntime.queryInterface(XNamed.class, xContent);
946cdf0e10cSrcweir         xNamed.setName(name);
947cdf0e10cSrcweir         return xContent;
948cdf0e10cSrcweir     }
949cdf0e10cSrcweir 
insertDocumentIndexMark(XTextCursor xCursor, String key)950cdf0e10cSrcweir     void insertDocumentIndexMark(XTextCursor xCursor, String key)
951cdf0e10cSrcweir         throws Exception
952cdf0e10cSrcweir     {
953cdf0e10cSrcweir         XTextContent xContent = makeDocumentIndexMark(key);
954cdf0e10cSrcweir         xContent.attach(xCursor);
955cdf0e10cSrcweir     }
956cdf0e10cSrcweir 
makeDocumentIndexMark(String key)957cdf0e10cSrcweir     XTextContent makeDocumentIndexMark(String key) throws Exception
958cdf0e10cSrcweir     {
959cdf0e10cSrcweir         Object xMark =
960cdf0e10cSrcweir             m_xDocFactory.createInstance("com.sun.star.text.DocumentIndexMark");
961cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
962cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xMark);
963cdf0e10cSrcweir         XPropertySet xPropSet = (XPropertySet)
964cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xMark);
965cdf0e10cSrcweir         xPropSet.setPropertyValue("PrimaryKey", key);
966cdf0e10cSrcweir         return xContent;
967cdf0e10cSrcweir     }
968cdf0e10cSrcweir 
insertHyperlink(XTextCursor xCursor, String url)969cdf0e10cSrcweir     void insertHyperlink(XTextCursor xCursor, String url) throws Exception
970cdf0e10cSrcweir     {
971cdf0e10cSrcweir         XPropertySet xPropSet = (XPropertySet)
972cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xCursor);
973cdf0e10cSrcweir         xPropSet.setPropertyValue("HyperLinkURL", url);
974cdf0e10cSrcweir     }
975cdf0e10cSrcweir 
insertRuby(XTextCursor xCursor, String rubytext)976cdf0e10cSrcweir     void insertRuby(XTextCursor xCursor, String rubytext) throws Exception
977cdf0e10cSrcweir     {
978cdf0e10cSrcweir         XPropertySet xPropSet = (XPropertySet)
979cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xCursor);
980cdf0e10cSrcweir         xPropSet.setPropertyValue("RubyText", rubytext);
981cdf0e10cSrcweir     }
982cdf0e10cSrcweir 
insertMeta(XTextCursor xCursor, StringPair xmlid)983cdf0e10cSrcweir     XTextContent insertMeta(XTextCursor xCursor, StringPair xmlid)
984cdf0e10cSrcweir         throws Exception
985cdf0e10cSrcweir     {
986cdf0e10cSrcweir         XTextContent xContent = makeMeta();
987cdf0e10cSrcweir         xContent.attach(xCursor);
988cdf0e10cSrcweir         XMetadatable xMetadatable = (XMetadatable)
989cdf0e10cSrcweir             UnoRuntime.queryInterface(XMetadatable.class, xContent);
990cdf0e10cSrcweir         xMetadatable.setMetadataReference(xmlid);
991cdf0e10cSrcweir         return xContent;
992cdf0e10cSrcweir     }
993cdf0e10cSrcweir 
makeMeta()994cdf0e10cSrcweir     XTextContent makeMeta() throws Exception
995cdf0e10cSrcweir     {
996cdf0e10cSrcweir         Object xMeta = m_xDocFactory.createInstance(
997cdf0e10cSrcweir                 "com.sun.star.text.InContentMetadata");
998cdf0e10cSrcweir         XTextContent xContent = (XTextContent)
999cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextContent.class, xMeta);
1000cdf0e10cSrcweir         return xContent;
1001cdf0e10cSrcweir     }
1002cdf0e10cSrcweir 
insertMetaField(XTextCursor xCursor, StringPair xmlid)1003cdf0e10cSrcweir     XTextField insertMetaField(XTextCursor xCursor, StringPair xmlid)
1004cdf0e10cSrcweir         throws Exception
1005cdf0e10cSrcweir     {
1006cdf0e10cSrcweir         XTextField xContent = makeMetaField();
1007cdf0e10cSrcweir         xContent.attach(xCursor);
1008cdf0e10cSrcweir         XMetadatable xMetadatable = (XMetadatable)
1009cdf0e10cSrcweir             UnoRuntime.queryInterface(XMetadatable.class, xContent);
1010cdf0e10cSrcweir         xMetadatable.setMetadataReference(xmlid);
1011cdf0e10cSrcweir         return xContent;
1012cdf0e10cSrcweir     }
1013cdf0e10cSrcweir 
makeMetaField()1014cdf0e10cSrcweir     XTextField makeMetaField() throws Exception
1015cdf0e10cSrcweir     {
1016cdf0e10cSrcweir         Object xMeta = m_xDocFactory.createInstance(
1017cdf0e10cSrcweir                 "com.sun.star.text.textfield.MetadataField");
1018cdf0e10cSrcweir         XTextField xContent = (XTextField)
1019cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextField.class, xMeta);
1020cdf0e10cSrcweir         return xContent;
1021cdf0e10cSrcweir     }
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir }
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir class TreeInserter extends Inserter
1026cdf0e10cSrcweir {
1027cdf0e10cSrcweir     private Map<String, XTextRange> m_BookmarkStarts;
1028cdf0e10cSrcweir     private Map<String, XTextRange> m_ReferenceMarkStarts;
1029cdf0e10cSrcweir     private Map<String, XTextRange> m_DocumentIndexMarkStarts;
1030cdf0e10cSrcweir     private List<Pair<XTextRange, FrameNode>> m_FrameHints;
1031cdf0e10cSrcweir 
TreeInserter(XTextDocument xDoc)1032cdf0e10cSrcweir     TreeInserter(XTextDocument xDoc)
1033cdf0e10cSrcweir     {
1034cdf0e10cSrcweir         super(xDoc);
1035cdf0e10cSrcweir         m_BookmarkStarts = new HashMap<String, XTextRange>();
1036cdf0e10cSrcweir         m_ReferenceMarkStarts = new HashMap<String, XTextRange>();
1037cdf0e10cSrcweir         m_DocumentIndexMarkStarts = new HashMap<String, XTextRange>();
1038cdf0e10cSrcweir         m_FrameHints = new ArrayList<Pair<XTextRange, FrameNode>>();
1039cdf0e10cSrcweir     }
1040cdf0e10cSrcweir 
insertTree(TreeNode tree)1041cdf0e10cSrcweir     void insertTree(TreeNode tree) throws Exception
1042cdf0e10cSrcweir     {
1043cdf0e10cSrcweir         if (!tree.getType().equals("__ROOT__"))
1044cdf0e10cSrcweir             throw new RuntimeException("insertTree: test error: no root");
1045cdf0e10cSrcweir         initParagraph();
1046cdf0e10cSrcweir         insertChildren(tree.createEnumeration());
1047cdf0e10cSrcweir         for (int i = 0; i < m_FrameHints.size(); ++i) {
1048cdf0e10cSrcweir             Pair<XTextRange, FrameNode> p = m_FrameHints.get(i);
1049cdf0e10cSrcweir             insertFrame(p.First, p.Second.getName(), p.Second.getAnchor());
1050cdf0e10cSrcweir         }
1051cdf0e10cSrcweir     }
1052cdf0e10cSrcweir 
insertChildren(TreeNodeEnum children)1053cdf0e10cSrcweir     void insertChildren(TreeNodeEnum children) throws Exception
1054cdf0e10cSrcweir     {
1055cdf0e10cSrcweir         while (children.hasNext()) {
1056cdf0e10cSrcweir             m_xCursor.gotoEndOfParagraph(false);
1057cdf0e10cSrcweir             TreeNode node = children.next();
1058cdf0e10cSrcweir             String type = node.getType();
1059cdf0e10cSrcweir             if (type.equals("Bookmark")) {
1060cdf0e10cSrcweir                 BookmarkNode bkmk = (BookmarkNode) node;
1061cdf0e10cSrcweir                 String name = bkmk.getName();
1062cdf0e10cSrcweir                 StringPair id = bkmk.getXmlId();
1063cdf0e10cSrcweir                 if (bkmk.isPoint()) {
1064cdf0e10cSrcweir                     insertBookmark(m_xCursor, name, id);
1065cdf0e10cSrcweir                 } else if (bkmk.isStart()) {
1066cdf0e10cSrcweir                     m_BookmarkStarts.put(name, m_xCursor.getStart());
1067cdf0e10cSrcweir                 } else {
1068cdf0e10cSrcweir                     XTextRange xRange = m_BookmarkStarts.get(name);
1069cdf0e10cSrcweir                     XParagraphCursor xCursor = mkCursor(xRange);
1070cdf0e10cSrcweir                     insertBookmark(xCursor, name, id);
1071cdf0e10cSrcweir                 }
1072cdf0e10cSrcweir             } else if (type.equals("ReferenceMark")) {
1073cdf0e10cSrcweir                 ReferenceMarkNode mark = (ReferenceMarkNode) node;
1074cdf0e10cSrcweir                 String name = mark.getName();
1075cdf0e10cSrcweir                 if (mark.isPoint()) {
1076cdf0e10cSrcweir                     insertReferenceMark(m_xCursor, name);
1077cdf0e10cSrcweir                 } else if (mark.isStart()) {
1078cdf0e10cSrcweir                     m_ReferenceMarkStarts.put(name, m_xCursor.getStart());
1079cdf0e10cSrcweir                 } else {
1080cdf0e10cSrcweir                     XTextRange xRange = m_ReferenceMarkStarts.get(name);
1081cdf0e10cSrcweir                     XParagraphCursor xCursor = mkCursor(xRange);
1082cdf0e10cSrcweir                     insertReferenceMark(xCursor, name);
1083cdf0e10cSrcweir                 }
1084cdf0e10cSrcweir             } else if (type.equals("DocumentIndexMark")) {
1085cdf0e10cSrcweir                 DocumentIndexMarkNode mark = (DocumentIndexMarkNode) node;
1086cdf0e10cSrcweir                 String name = mark.getName();
1087cdf0e10cSrcweir                 if (mark.isPoint()) {
1088cdf0e10cSrcweir                     insertDocumentIndexMark(m_xCursor, name);
1089cdf0e10cSrcweir                 } else if (mark.isStart()) {
1090cdf0e10cSrcweir                     m_DocumentIndexMarkStarts.put(name, m_xCursor.getStart());
1091cdf0e10cSrcweir                 } else {
1092cdf0e10cSrcweir                     XTextRange xRange = m_DocumentIndexMarkStarts.get(name);
1093cdf0e10cSrcweir                     XParagraphCursor xCursor = mkCursor(xRange);
1094cdf0e10cSrcweir                     insertDocumentIndexMark(xCursor, name);
1095cdf0e10cSrcweir                 }
1096cdf0e10cSrcweir             } else if (type.equals("Hyperlink")) {
1097cdf0e10cSrcweir                 HyperlinkNode href = (HyperlinkNode) node;
1098cdf0e10cSrcweir                 XTextRange xRange = m_xCursor.getStart();
1099cdf0e10cSrcweir                 insertChildren(href.createEnumeration());
1100cdf0e10cSrcweir                 XParagraphCursor xCursor = mkCursor(xRange);
1101cdf0e10cSrcweir                 insertHyperlink(xCursor, href.getURL());
1102cdf0e10cSrcweir             } else if (type.equals("Ruby")) {
1103cdf0e10cSrcweir                 RubyNode ruby = (RubyNode) node;
1104cdf0e10cSrcweir                 XTextRange xRange = m_xCursor.getStart();
1105cdf0e10cSrcweir                 insertChildren(ruby.createEnumeration());
1106cdf0e10cSrcweir                 XParagraphCursor xCursor = mkCursor(xRange);
1107cdf0e10cSrcweir                 insertRuby(xCursor, ruby.getRubyText());
1108cdf0e10cSrcweir             } else if (type.equals("InContentMetadata")) {
1109cdf0e10cSrcweir                 MetaNode meta = (MetaNode) node;
1110cdf0e10cSrcweir                 XTextRange xRange = m_xCursor.getStart();
1111cdf0e10cSrcweir                 insertChildren(meta.createEnumeration());
1112cdf0e10cSrcweir                 XParagraphCursor xCursor = mkCursor(xRange);
1113cdf0e10cSrcweir                 insertMeta(xCursor, meta.getXmlId());
1114cdf0e10cSrcweir             } else if (type.equals("MetadataField")) {
1115cdf0e10cSrcweir                 MetaFieldNode meta = (MetaFieldNode) node;
1116cdf0e10cSrcweir                 XTextRange xRange = m_xCursor.getStart();
1117cdf0e10cSrcweir                 insertChildren(meta.createEnumeration());
1118cdf0e10cSrcweir                 XParagraphCursor xCursor = mkCursor(xRange);
1119cdf0e10cSrcweir                 insertMetaField(xCursor, meta.getXmlId());
1120cdf0e10cSrcweir             } else if (type.equals("Text")) {
1121cdf0e10cSrcweir                 TextNode text = (TextNode) node;
1122cdf0e10cSrcweir                 insertText(m_xCursor, text.getContent());
1123cdf0e10cSrcweir             } else if (type.equals("TextField")) {
1124cdf0e10cSrcweir                 TextFieldNode field = (TextFieldNode) node;
1125cdf0e10cSrcweir                 insertTextField(m_xCursor, field.getContent());
1126cdf0e10cSrcweir             } else if (type.equals("Footnote")) {
1127cdf0e10cSrcweir                 FootnoteNode note = (FootnoteNode) node;
1128cdf0e10cSrcweir                 insertFootnote(m_xCursor, note.getLabel());
1129cdf0e10cSrcweir             } else if (type.equals("Frame")) {
1130cdf0e10cSrcweir                 FrameNode frame = (FrameNode) node;
1131cdf0e10cSrcweir                 if (frame.getAnchor() == AT_CHARACTER) {
1132cdf0e10cSrcweir                     m_FrameHints.add( new Pair(m_xCursor.getStart(), frame) );
1133cdf0e10cSrcweir                 } else {
1134cdf0e10cSrcweir                     insertFrame(m_xCursor, frame.getName(), frame.getAnchor());
1135cdf0e10cSrcweir                 }
1136cdf0e10cSrcweir             } else if (type.equals("ControlCharacter")) {
1137cdf0e10cSrcweir                 ControlCharacterNode cchar = (ControlCharacterNode) node;
1138cdf0e10cSrcweir                 insertControlCharacter(m_xCursor, cchar.getChar());
1139cdf0e10cSrcweir             } else if (type.equals("SoftPageBreak")) {
1140cdf0e10cSrcweir                 SoftPageBreakNode spbk = (SoftPageBreakNode) node;
1141cdf0e10cSrcweir                 throw new RuntimeException("sorry, cannot test SoftPageBreak");
1142cdf0e10cSrcweir             } else {
1143cdf0e10cSrcweir                 throw new RuntimeException("unexpected type: " + type);
1144cdf0e10cSrcweir             }
1145cdf0e10cSrcweir         }
1146cdf0e10cSrcweir     }
1147cdf0e10cSrcweir 
mkCursor(XTextRange xRange)1148cdf0e10cSrcweir     XParagraphCursor mkCursor(XTextRange xRange)
1149cdf0e10cSrcweir     {
1150cdf0e10cSrcweir         XTextCursor xCursor = m_xText.createTextCursorByRange(xRange);
1151cdf0e10cSrcweir         XParagraphCursor xParaCursor = (XParagraphCursor)
1152cdf0e10cSrcweir             UnoRuntime.queryInterface(XParagraphCursor.class, xCursor);
1153cdf0e10cSrcweir         xParaCursor.gotoEndOfParagraph(true);
1154cdf0e10cSrcweir         return xParaCursor;
1155cdf0e10cSrcweir     }
1156cdf0e10cSrcweir }
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir // FIXME: this does not account for inserted dummy characters!
1160cdf0e10cSrcweir class RangeInserter extends Inserter
1161cdf0e10cSrcweir {
RangeInserter(XTextDocument xDoc)1162cdf0e10cSrcweir     RangeInserter(XTextDocument xDoc) throws Exception
1163cdf0e10cSrcweir     { super(xDoc); initParagraph(); }
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir     /*
1166cdf0e10cSrcweir     void insertText(int pos, String text)
1167cdf0e10cSrcweir     {
1168cdf0e10cSrcweir         m_xCursor.gotoStartOfParagraph(false);
1169cdf0e10cSrcweir         m_xCursor.goRight((short) pos, false);
1170cdf0e10cSrcweir         insertText(m_xCursor, text);
1171cdf0e10cSrcweir     }
1172cdf0e10cSrcweir     */
1173cdf0e10cSrcweir 
insertRange(Range range)1174cdf0e10cSrcweir     XTextContent insertRange(Range range) throws Exception
1175cdf0e10cSrcweir     {
1176cdf0e10cSrcweir         m_xCursor.gotoStartOfParagraph(false);
1177cdf0e10cSrcweir         m_xCursor.goRight(range.getStart(), false);
1178cdf0e10cSrcweir         m_xCursor.goRight(range.getExtent(), true);
1179cdf0e10cSrcweir         return insertNode(m_xCursor, range.getNode());
1180cdf0e10cSrcweir     }
1181cdf0e10cSrcweir 
insertNode(XParagraphCursor xCursor, TreeNode node)1182cdf0e10cSrcweir     XTextContent insertNode(XParagraphCursor xCursor, TreeNode node)
1183cdf0e10cSrcweir         throws Exception
1184cdf0e10cSrcweir     {
1185cdf0e10cSrcweir         String type = node.getType();
1186cdf0e10cSrcweir         if (type.equals("Bookmark")) {
1187cdf0e10cSrcweir             BookmarkNode bkmk = (BookmarkNode) node;
1188cdf0e10cSrcweir             if (bkmk.isPoint()) throw new RuntimeException("range only");
1189cdf0e10cSrcweir             insertBookmark(xCursor, bkmk.getName(), bkmk.getXmlId());
1190cdf0e10cSrcweir         } else if (type.equals("ReferenceMark")) {
1191cdf0e10cSrcweir             ReferenceMarkNode mark = (ReferenceMarkNode) node;
1192cdf0e10cSrcweir             if (mark.isPoint()) throw new RuntimeException("range only");
1193cdf0e10cSrcweir             insertReferenceMark(xCursor, mark.getName());
1194cdf0e10cSrcweir         } else if (type.equals("DocumentIndexMark")) {
1195cdf0e10cSrcweir             DocumentIndexMarkNode mark = (DocumentIndexMarkNode) node;
1196cdf0e10cSrcweir             if (mark.isPoint()) throw new RuntimeException("range only");
1197cdf0e10cSrcweir             insertDocumentIndexMark(xCursor, mark.getName());
1198cdf0e10cSrcweir         } else if (type.equals("Hyperlink")) {
1199cdf0e10cSrcweir             HyperlinkNode href = (HyperlinkNode) node;
1200cdf0e10cSrcweir             insertHyperlink(xCursor, href.getURL());
1201cdf0e10cSrcweir         } else if (type.equals("Ruby")) {
1202cdf0e10cSrcweir             RubyNode ruby = (RubyNode) node;
1203cdf0e10cSrcweir             insertRuby(xCursor, ruby.getRubyText());
1204cdf0e10cSrcweir         } else if (type.equals("InContentMetadata")) {
1205cdf0e10cSrcweir             MetaNode meta = (MetaNode) node;
1206cdf0e10cSrcweir             return insertMeta(xCursor, meta.getXmlId());
1207cdf0e10cSrcweir         } else if (type.equals("MetadataField")) {
1208cdf0e10cSrcweir             MetaFieldNode meta = (MetaFieldNode) node;
1209cdf0e10cSrcweir             return insertMetaField(xCursor, meta.getXmlId());
1210cdf0e10cSrcweir         } else if (type.equals("Text")) {
1211cdf0e10cSrcweir             TextNode text = (TextNode) node;
1212cdf0e10cSrcweir             insertText(xCursor, text.getContent());
1213cdf0e10cSrcweir         } else if (type.equals("TextField")) {
1214cdf0e10cSrcweir             TextFieldNode field = (TextFieldNode) node;
1215cdf0e10cSrcweir             insertTextField(m_xCursor, field.getContent());
1216cdf0e10cSrcweir         } else if (type.equals("Footnote")) {
1217cdf0e10cSrcweir             FootnoteNode note = (FootnoteNode) node;
1218cdf0e10cSrcweir             insertFootnote(m_xCursor, note.getLabel());
1219cdf0e10cSrcweir         } else if (type.equals("Frame")) {
1220cdf0e10cSrcweir             FrameNode frame = (FrameNode) node;
1221cdf0e10cSrcweir             insertFrame(xCursor, frame.getName(), frame.getAnchor());
1222cdf0e10cSrcweir         } else if (type.equals("ControlCharacter")) {
1223cdf0e10cSrcweir             ControlCharacterNode cchar = (ControlCharacterNode) node;
1224cdf0e10cSrcweir             insertControlCharacter(m_xCursor, cchar.getChar());
1225cdf0e10cSrcweir         } else if (type.equals("SoftPageBreak")) {
1226cdf0e10cSrcweir             throw new RuntimeException("sorry, cannot test SoftPageBreak");
1227cdf0e10cSrcweir         } else {
1228cdf0e10cSrcweir             throw new RuntimeException("unexpected type: " + type);
1229cdf0e10cSrcweir         }
1230cdf0e10cSrcweir         return null;
1231cdf0e10cSrcweir     }
1232cdf0e10cSrcweir }
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir //----------------------------------------------------------------------
1236cdf0e10cSrcweir 
1237cdf0e10cSrcweir public class TextPortionEnumerationTest
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir     private XMultiServiceFactory m_xMSF = null;
1240cdf0e10cSrcweir     private XComponentContext m_xContext = null;
1241cdf0e10cSrcweir     private XTextDocument m_xDoc = null;
1242cdf0e10cSrcweir     private String m_TmpDir = null;
1243cdf0e10cSrcweir 
1244cdf0e10cSrcweir     private int m_Count = 1;
1245cdf0e10cSrcweir 
before()1246cdf0e10cSrcweir     @Before public void before() throws Exception
1247cdf0e10cSrcweir     {
1248cdf0e10cSrcweir         m_xMSF = UnoRuntime.queryInterface(
1249cdf0e10cSrcweir             XMultiServiceFactory.class,
1250cdf0e10cSrcweir             connection.getComponentContext().getServiceManager());
1251cdf0e10cSrcweir         XPropertySet xPropertySet = (XPropertySet)
1252cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, m_xMSF);
1253cdf0e10cSrcweir         Object defaultCtx = xPropertySet.getPropertyValue("DefaultContext");
1254cdf0e10cSrcweir         m_xContext = (XComponentContext)
1255cdf0e10cSrcweir             UnoRuntime.queryInterface(XComponentContext.class, defaultCtx);
1256cdf0e10cSrcweir         assertNotNull("could not get component context.", m_xContext);
1257cdf0e10cSrcweir         m_xDoc = util.WriterTools.createTextDoc(m_xMSF);
1258cdf0e10cSrcweir         m_TmpDir = util.utils.getOfficeTemp/*Dir*/(m_xMSF);
1259cdf0e10cSrcweir         System.out.println("tempdir: " + m_TmpDir);
1260cdf0e10cSrcweir     }
1261cdf0e10cSrcweir 
after()1262cdf0e10cSrcweir     @After public void after()
1263cdf0e10cSrcweir     {
1264cdf0e10cSrcweir         util.DesktopTools.closeDoc(m_xDoc);
1265cdf0e10cSrcweir     }
1266cdf0e10cSrcweir 
testText()1267cdf0e10cSrcweir     @Test public void testText() throws Exception
1268cdf0e10cSrcweir     {
1269cdf0e10cSrcweir         TreeNode root = new TreeNode();
1270cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1271cdf0e10cSrcweir         root.appendChild(text);
1272cdf0e10cSrcweir         doTest(root);
1273cdf0e10cSrcweir     }
1274cdf0e10cSrcweir 
testTextField()1275cdf0e10cSrcweir     @Test public void testTextField() throws Exception
1276cdf0e10cSrcweir     {
1277cdf0e10cSrcweir         String name = mkName("ruby");
1278cdf0e10cSrcweir         TreeNode root = new TreeNode();
1279cdf0e10cSrcweir         TreeNode txtf = new TextFieldNode("abc");
1280cdf0e10cSrcweir         root.appendChild(txtf);
1281cdf0e10cSrcweir         doTest(root);
1282cdf0e10cSrcweir     }
1283cdf0e10cSrcweir 
testControlChar()1284cdf0e10cSrcweir     /*@Test*/ public void testControlChar() throws Exception
1285cdf0e10cSrcweir     {
1286cdf0e10cSrcweir //FIXME this is converted to a text portion: ControlCharacter is obsolete
1287cdf0e10cSrcweir         TreeNode root = new TreeNode();
1288cdf0e10cSrcweir         TreeNode cchr = new ControlCharacterNode(HARD_HYPHEN);
1289cdf0e10cSrcweir         root.appendChild(cchr);
1290cdf0e10cSrcweir         doTest(root);
1291cdf0e10cSrcweir     }
1292cdf0e10cSrcweir 
testSoftPageBreak()1293cdf0e10cSrcweir     /*@Test*/ public void testSoftPageBreak() throws Exception
1294cdf0e10cSrcweir     {
1295cdf0e10cSrcweir //FIXME: insert a soft page break: not done
1296cdf0e10cSrcweir         TreeNode root = new TreeNode();
1297cdf0e10cSrcweir         TreeNode spbk = new SoftPageBreakNode();
1298cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1299cdf0e10cSrcweir         root.appendChild(spbk);
1300cdf0e10cSrcweir         root.appendChild(text);
1301cdf0e10cSrcweir         doTest(root);
1302cdf0e10cSrcweir     }
1303cdf0e10cSrcweir 
testFootnote()1304cdf0e10cSrcweir     @Test public void testFootnote() throws Exception
1305cdf0e10cSrcweir     {
1306cdf0e10cSrcweir         String name = mkName("ftn");
1307cdf0e10cSrcweir         TreeNode root = new TreeNode();
1308cdf0e10cSrcweir         TreeNode ftnd = new FootnoteNode(name);
1309cdf0e10cSrcweir         root.appendChild(ftnd);
1310cdf0e10cSrcweir         doTest(root);
1311cdf0e10cSrcweir     }
1312cdf0e10cSrcweir 
testFrameAs()1313cdf0e10cSrcweir     @Test public void testFrameAs() throws Exception
1314cdf0e10cSrcweir     {
1315cdf0e10cSrcweir         String name = mkName("frame");
1316cdf0e10cSrcweir         TreeNode root = new TreeNode();
1317cdf0e10cSrcweir         TreeNode fram = new FrameNode(name, AS_CHARACTER);
1318cdf0e10cSrcweir         root.appendChild(fram);
1319cdf0e10cSrcweir         doTest(root);
1320cdf0e10cSrcweir     }
1321cdf0e10cSrcweir 
testFrameAt()1322cdf0e10cSrcweir     @Test public void testFrameAt() throws Exception
1323cdf0e10cSrcweir     {
1324cdf0e10cSrcweir         String name = mkName("frame");
1325cdf0e10cSrcweir         TreeNode root = new TreeNode();
1326cdf0e10cSrcweir //        TreeNode text = new TextNode(""); // necessary?
1327cdf0e10cSrcweir         TreeNode fram = new FrameNode(name, AT_CHARACTER);
1328cdf0e10cSrcweir //        root.appendChild(text);
1329cdf0e10cSrcweir         root.appendChild(fram);
1330cdf0e10cSrcweir         doTest(root);
1331cdf0e10cSrcweir     }
1332cdf0e10cSrcweir 
testBookmarkPoint()1333cdf0e10cSrcweir     @Test public void testBookmarkPoint() throws Exception
1334cdf0e10cSrcweir     {
1335cdf0e10cSrcweir         String name = mkName("mark");
1336cdf0e10cSrcweir         TreeNode root = new TreeNode();
1337cdf0e10cSrcweir         TreeNode bkmk = new BookmarkNode(name);
1338cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1339cdf0e10cSrcweir         root.appendChild(bkmk);
1340cdf0e10cSrcweir         root.appendChild(text);
1341cdf0e10cSrcweir         doTest(root);
1342cdf0e10cSrcweir     }
1343cdf0e10cSrcweir 
testBookmark()1344cdf0e10cSrcweir     @Test public void testBookmark() throws Exception
1345cdf0e10cSrcweir     {
1346cdf0e10cSrcweir         String name = mkName("mark");
1347cdf0e10cSrcweir         TreeNode root = new TreeNode();
1348cdf0e10cSrcweir         TreeNode bkm1 = new BookmarkStartNode(name);
1349cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1350cdf0e10cSrcweir         TreeNode bkm2 = new BookmarkEndNode(name);
1351cdf0e10cSrcweir         root.appendChild(bkm1);
1352cdf0e10cSrcweir         root.appendChild(text);
1353cdf0e10cSrcweir         root.appendChild(bkm2);
1354cdf0e10cSrcweir         doTest(root);
1355cdf0e10cSrcweir     }
1356cdf0e10cSrcweir 
testBookmarkPointXmlId()1357cdf0e10cSrcweir     @Test public void testBookmarkPointXmlId() throws Exception
1358cdf0e10cSrcweir     {
1359cdf0e10cSrcweir         String name = mkName("mark");
1360cdf0e10cSrcweir         StringPair id = mkId("id");
1361cdf0e10cSrcweir         TreeNode root = new TreeNode();
1362cdf0e10cSrcweir         TreeNode bkmk = new BookmarkNode(name, id);
1363cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1364cdf0e10cSrcweir         root.appendChild(bkmk);
1365cdf0e10cSrcweir         root.appendChild(text);
1366cdf0e10cSrcweir         doTest(root);
1367cdf0e10cSrcweir     }
1368cdf0e10cSrcweir 
testBookmarkXmlId()1369cdf0e10cSrcweir     @Test public void testBookmarkXmlId() throws Exception
1370cdf0e10cSrcweir     {
1371cdf0e10cSrcweir         String name = mkName("mark");
1372cdf0e10cSrcweir         StringPair id = mkId("id");
1373cdf0e10cSrcweir         TreeNode root = new TreeNode();
1374cdf0e10cSrcweir         TreeNode bkm1 = new BookmarkStartNode(name, id);
1375cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1376cdf0e10cSrcweir         TreeNode bkm2 = new BookmarkEndNode(name, id);
1377cdf0e10cSrcweir         root.appendChild(bkm1);
1378cdf0e10cSrcweir         root.appendChild(text);
1379cdf0e10cSrcweir         root.appendChild(bkm2);
1380cdf0e10cSrcweir         doTest(root);
1381cdf0e10cSrcweir     }
1382cdf0e10cSrcweir 
testRefmarkPoint()1383cdf0e10cSrcweir     @Test public void testRefmarkPoint() throws Exception
1384cdf0e10cSrcweir     {
1385cdf0e10cSrcweir         String name = mkName("refmark");
1386cdf0e10cSrcweir         TreeNode root = new TreeNode();
1387cdf0e10cSrcweir         TreeNode rfmk = new ReferenceMarkNode(name);
1388cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1389cdf0e10cSrcweir         root.appendChild(rfmk);
1390cdf0e10cSrcweir         root.appendChild(text);
1391cdf0e10cSrcweir         doTest(root);
1392cdf0e10cSrcweir     }
1393cdf0e10cSrcweir 
testRefmark()1394cdf0e10cSrcweir     @Test public void testRefmark() throws Exception
1395cdf0e10cSrcweir     {
1396cdf0e10cSrcweir         String name = mkName("refmark");
1397cdf0e10cSrcweir         TreeNode root = new TreeNode();
1398cdf0e10cSrcweir         TreeNode rfm1 = new ReferenceMarkStartNode(name);
1399cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1400cdf0e10cSrcweir         TreeNode rfm2 = new ReferenceMarkEndNode(name);
1401cdf0e10cSrcweir         root.appendChild(rfm1);
1402cdf0e10cSrcweir         root.appendChild(text);
1403cdf0e10cSrcweir         root.appendChild(rfm2);
1404cdf0e10cSrcweir         doTest(root);
1405cdf0e10cSrcweir     }
1406cdf0e10cSrcweir 
testToxmarkPoint()1407cdf0e10cSrcweir     @Test public void testToxmarkPoint() throws Exception
1408cdf0e10cSrcweir     {
1409cdf0e10cSrcweir         String name = mkName("toxmark");
1410cdf0e10cSrcweir         TreeNode root = new TreeNode();
1411cdf0e10cSrcweir         TreeNode txmk = new DocumentIndexMarkNode(name);
1412cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1413cdf0e10cSrcweir         root.appendChild(txmk);
1414cdf0e10cSrcweir         root.appendChild(text);
1415cdf0e10cSrcweir         doTest(root);
1416cdf0e10cSrcweir     }
1417cdf0e10cSrcweir 
testToxmark()1418cdf0e10cSrcweir     @Test public void testToxmark() throws Exception
1419cdf0e10cSrcweir     {
1420cdf0e10cSrcweir         String name = mkName("toxmark");
1421cdf0e10cSrcweir         TreeNode root = new TreeNode();
1422cdf0e10cSrcweir         TreeNode txm1 = new DocumentIndexMarkStartNode(name);
1423cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1424cdf0e10cSrcweir         TreeNode txm2 = new DocumentIndexMarkEndNode(name);
1425cdf0e10cSrcweir         root.appendChild(txm1);
1426cdf0e10cSrcweir         root.appendChild(text);
1427cdf0e10cSrcweir         root.appendChild(txm2);
1428cdf0e10cSrcweir         doTest(root);
1429cdf0e10cSrcweir     }
1430cdf0e10cSrcweir 
testHyperlink()1431cdf0e10cSrcweir     @Test public void testHyperlink() throws Exception
1432cdf0e10cSrcweir     {
1433cdf0e10cSrcweir         String name = mkName("url");
1434cdf0e10cSrcweir         TreeNode root = new TreeNode();
1435cdf0e10cSrcweir         TreeNode href = new HyperlinkNode(name);
1436cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1437cdf0e10cSrcweir         href.appendChild(text);
1438cdf0e10cSrcweir         root.appendChild(href);
1439cdf0e10cSrcweir         doTest(root);
1440cdf0e10cSrcweir     }
1441cdf0e10cSrcweir 
testHyperlinkEmpty()1442cdf0e10cSrcweir     @Test public void testHyperlinkEmpty() throws Exception
1443cdf0e10cSrcweir     {
1444cdf0e10cSrcweir         String name = mkName("url");
1445cdf0e10cSrcweir         TreeNode root = new TreeNode();
1446cdf0e10cSrcweir         TreeNode href = new HyperlinkNode(name);
1447cdf0e10cSrcweir         TreeNode text = new TextNode("");
1448cdf0e10cSrcweir         href.appendChild(text);
1449cdf0e10cSrcweir         root.appendChild(href);
1450cdf0e10cSrcweir         doTest(root);
1451cdf0e10cSrcweir     }
1452cdf0e10cSrcweir 
testRuby()1453cdf0e10cSrcweir     @Test public void testRuby() throws Exception
1454cdf0e10cSrcweir     {
1455cdf0e10cSrcweir         String name = mkName("ruby");
1456cdf0e10cSrcweir         TreeNode root = new TreeNode();
1457cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name);
1458cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1459cdf0e10cSrcweir         ruby.appendChild(text);
1460cdf0e10cSrcweir         root.appendChild(ruby);
1461cdf0e10cSrcweir         doTest(root);
1462cdf0e10cSrcweir     }
1463cdf0e10cSrcweir 
testRubyEmpty()1464cdf0e10cSrcweir     @Test public void testRubyEmpty() throws Exception
1465cdf0e10cSrcweir     {
1466cdf0e10cSrcweir         // BUG: #i91534#
1467cdf0e10cSrcweir         String name = mkName("ruby");
1468cdf0e10cSrcweir         TreeNode root = new TreeNode();
1469cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name);
1470cdf0e10cSrcweir         root.appendChild(ruby);
1471cdf0e10cSrcweir         doTest(root);
1472cdf0e10cSrcweir     }
1473cdf0e10cSrcweir 
testMeta()1474cdf0e10cSrcweir     @Test public void testMeta() throws Exception
1475cdf0e10cSrcweir     {
1476cdf0e10cSrcweir         StringPair id = new StringPair("content.xml", mkName("id"));
1477cdf0e10cSrcweir         TreeNode root = new TreeNode();
1478cdf0e10cSrcweir         TreeNode meta = new MetaNode(id);
1479cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1480cdf0e10cSrcweir         root.appendChild(new TextNode("123"));
1481cdf0e10cSrcweir         meta.appendChild(text);
1482cdf0e10cSrcweir         root.appendChild(meta);
1483cdf0e10cSrcweir         doTest(root);
1484cdf0e10cSrcweir     }
1485cdf0e10cSrcweir 
testMetaEmpty()1486cdf0e10cSrcweir     @Test public void testMetaEmpty() throws Exception
1487cdf0e10cSrcweir     {
1488cdf0e10cSrcweir         StringPair id = new StringPair("content.xml", mkName("id"));
1489cdf0e10cSrcweir         TreeNode root = new TreeNode();
1490cdf0e10cSrcweir         TreeNode meta = new MetaNode(id);
1491cdf0e10cSrcweir //        TreeNode text = new TextNode("");
1492cdf0e10cSrcweir //        meta.appendChild(text);
1493cdf0e10cSrcweir         root.appendChild(meta);
1494cdf0e10cSrcweir         doTest(root);
1495cdf0e10cSrcweir     }
1496cdf0e10cSrcweir 
testMetaField()1497cdf0e10cSrcweir     @Test public void testMetaField() throws Exception
1498cdf0e10cSrcweir     {
1499cdf0e10cSrcweir         StringPair id = new StringPair("content.xml", mkName("id"));
1500cdf0e10cSrcweir         TreeNode root = new TreeNode();
1501cdf0e10cSrcweir         TreeNode meta = new MetaFieldNode(id);
1502cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
1503cdf0e10cSrcweir         root.appendChild(new TextNode("123"));
1504cdf0e10cSrcweir         meta.appendChild(text);
1505cdf0e10cSrcweir         root.appendChild(meta);
1506cdf0e10cSrcweir         doTest(root);
1507cdf0e10cSrcweir     }
1508cdf0e10cSrcweir 
testMetaFieldEmpty()1509cdf0e10cSrcweir     @Test public void testMetaFieldEmpty() throws Exception
1510cdf0e10cSrcweir     {
1511cdf0e10cSrcweir         StringPair id = new StringPair("content.xml", mkName("id"));
1512cdf0e10cSrcweir         TreeNode root = new TreeNode();
1513cdf0e10cSrcweir         TreeNode meta = new MetaFieldNode(id);
1514cdf0e10cSrcweir //        TreeNode text = new TextNode("");
1515cdf0e10cSrcweir //        meta.appendChild(text);
1516cdf0e10cSrcweir         root.appendChild(meta);
1517cdf0e10cSrcweir         doTest(root);
1518cdf0e10cSrcweir     }
1519cdf0e10cSrcweir 
testBookmark1()1520cdf0e10cSrcweir     @Test public void testBookmark1() throws Exception
1521cdf0e10cSrcweir     {
1522cdf0e10cSrcweir         String name1 = mkName("mark");
1523cdf0e10cSrcweir         String name2 = mkName("mark");
1524cdf0e10cSrcweir         String name3 = mkName("mark");
1525cdf0e10cSrcweir         TreeNode root = new TreeNode();
1526cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name1) );
1527cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name2) );
1528cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name3) );
1529cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1530cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name1) );
1531cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1532cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name3) );
1533cdf0e10cSrcweir         doTest(root);
1534cdf0e10cSrcweir     }
1535cdf0e10cSrcweir 
testBookmark2()1536cdf0e10cSrcweir     @Test public void testBookmark2() throws Exception
1537cdf0e10cSrcweir     {
1538cdf0e10cSrcweir         String name1 = mkName("mark");
1539cdf0e10cSrcweir         String name2 = mkName("mark");
1540cdf0e10cSrcweir         String name3 = mkName("mark");
1541cdf0e10cSrcweir         TreeNode root = new TreeNode();
1542cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name1) );
1543cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1544cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name2) );
1545cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name3) );
1546cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name1) );
1547cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1548cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name3) );
1549cdf0e10cSrcweir         doTest(root);
1550cdf0e10cSrcweir     }
1551cdf0e10cSrcweir 
testRefMark2()1552cdf0e10cSrcweir     @Test public void testRefMark2() throws Exception
1553cdf0e10cSrcweir     {
1554cdf0e10cSrcweir         String name1 = mkName("refmark");
1555cdf0e10cSrcweir         TreeNode root = new TreeNode();
1556cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name1) );
1557cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1558cdf0e10cSrcweir         // BUG: #i102541# (this is actually not unoportenum's fault)
1559cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name1) );
1560cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1561cdf0e10cSrcweir         doTest(root);
1562cdf0e10cSrcweir     }
1563cdf0e10cSrcweir 
testRefMark3()1564cdf0e10cSrcweir     @Test public void testRefMark3() throws Exception
1565cdf0e10cSrcweir     {
1566cdf0e10cSrcweir         // BUG: #i107672# (non-deterministic; depends on pointer ordering)
1567cdf0e10cSrcweir         String name1 = mkName("refmark");
1568cdf0e10cSrcweir         String name2 = mkName("refmark");
1569cdf0e10cSrcweir         String name3 = mkName("refmark");
1570cdf0e10cSrcweir         String name4 = mkName("refmark");
1571cdf0e10cSrcweir         String name5 = mkName("refmark");
1572cdf0e10cSrcweir         String name6 = mkName("refmark");
1573cdf0e10cSrcweir         String name7 = mkName("refmark");
1574cdf0e10cSrcweir         TreeNode root = new TreeNode();
1575cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name1) );
1576cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name2) );
1577cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name3) );
1578cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name4) );
1579cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name5) );
1580cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name6) );
1581cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name7) );
1582cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1583cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name7) );
1584cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name6) );
1585cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name5) );
1586cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name4) );
1587cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name3) );
1588cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name2) );
1589cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name1) );
1590cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1591cdf0e10cSrcweir         doTest(root);
1592cdf0e10cSrcweir     }
1593cdf0e10cSrcweir 
testToxMark2()1594cdf0e10cSrcweir     @Test public void testToxMark2() throws Exception
1595cdf0e10cSrcweir     {
1596cdf0e10cSrcweir         String name1 = mkName("toxmark");
1597cdf0e10cSrcweir         TreeNode root = new TreeNode();
1598cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name1) );
1599cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1600cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name1) );
1601cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1602cdf0e10cSrcweir         doTest(root);
1603cdf0e10cSrcweir     }
1604cdf0e10cSrcweir 
testToxMark3()1605cdf0e10cSrcweir     @Test public void testToxMark3() throws Exception
1606cdf0e10cSrcweir     {
1607cdf0e10cSrcweir         // BUG: #i107672# (non-deterministic; depends on pointer ordering)
1608cdf0e10cSrcweir         String name1 = mkName("toxmark");
1609cdf0e10cSrcweir         String name2 = mkName("toxmark");
1610cdf0e10cSrcweir         String name3 = mkName("toxmark");
1611cdf0e10cSrcweir         String name4 = mkName("toxmark");
1612cdf0e10cSrcweir         String name5 = mkName("toxmark");
1613cdf0e10cSrcweir         String name6 = mkName("toxmark");
1614cdf0e10cSrcweir         String name7 = mkName("toxmark");
1615cdf0e10cSrcweir         TreeNode root = new TreeNode();
1616cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name1) );
1617cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name2) );
1618cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name3) );
1619cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name4) );
1620cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name5) );
1621cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name6) );
1622cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name7) );
1623cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1624cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name7) );
1625cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name6) );
1626cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name5) );
1627cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name4) );
1628cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name3) );
1629cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name2) );
1630cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name1) );
1631cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1632cdf0e10cSrcweir         doTest(root);
1633cdf0e10cSrcweir     }
1634cdf0e10cSrcweir 
testMarks1()1635cdf0e10cSrcweir     @Test public void testMarks1() throws Exception
1636cdf0e10cSrcweir     {
1637cdf0e10cSrcweir         String name1 = mkName("bookmark");
1638cdf0e10cSrcweir         String name2 = mkName("toxmark");
1639cdf0e10cSrcweir         String name3 = mkName("refmark");
1640cdf0e10cSrcweir         String name4 = mkName("toxmark");
1641cdf0e10cSrcweir         TreeNode root = new TreeNode();
1642cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name1) );
1643cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name2) );
1644cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name3) );
1645cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1646cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name1) );
1647cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name4) );
1648cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1649cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name4) );
1650cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name3) );
1651cdf0e10cSrcweir         doTest(root);
1652cdf0e10cSrcweir     }
1653cdf0e10cSrcweir 
testMarks2()1654cdf0e10cSrcweir     @Test public void testMarks2() throws Exception
1655cdf0e10cSrcweir     {
1656cdf0e10cSrcweir         String name1 = mkName("bookmark");
1657cdf0e10cSrcweir         String name2 = mkName("refmark");
1658cdf0e10cSrcweir         String name3 = mkName("refmark");
1659cdf0e10cSrcweir         String name4 = mkName("toxmark");
1660cdf0e10cSrcweir         String name5 = mkName("refmark");
1661cdf0e10cSrcweir         TreeNode root = new TreeNode();
1662cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name1) );
1663cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name2) );
1664cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name3) );
1665cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1666cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name4) );
1667cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name5) );
1668cdf0e10cSrcweir         // BUG: #i102541# (this is actually not unoportenum's fault)
1669cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name3) );
1670cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1671cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name4) );
1672cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name1) );
1673cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name5) );
1674cdf0e10cSrcweir         doTest(root);
1675cdf0e10cSrcweir     }
1676cdf0e10cSrcweir 
testMarks3()1677cdf0e10cSrcweir     @Test public void testMarks3() throws Exception
1678cdf0e10cSrcweir     {
1679cdf0e10cSrcweir         String name1 = mkName("bookmark");
1680cdf0e10cSrcweir         String name2 = mkName("refmark");
1681cdf0e10cSrcweir         String name3 = mkName("refmark");
1682cdf0e10cSrcweir         String name4 = mkName("toxmark");
1683cdf0e10cSrcweir         String name5 = mkName("refmark");
1684cdf0e10cSrcweir         TreeNode root = new TreeNode();
1685cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name1) );
1686cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name2) );
1687cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name3) );
1688cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1689cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name4) );
1690cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkStartNode(name5) );
1691cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name3) );
1692cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1693cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name4) );
1694cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name1) );
1695cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkEndNode(name5) );
1696cdf0e10cSrcweir         doTest(root);
1697cdf0e10cSrcweir     }
1698cdf0e10cSrcweir 
testFrameMark1()1699cdf0e10cSrcweir     @Test public void testFrameMark1() throws Exception
1700cdf0e10cSrcweir     {
1701cdf0e10cSrcweir         String name1 = mkName("bookmark");
1702cdf0e10cSrcweir         String name2 = mkName("frame");
1703cdf0e10cSrcweir         TreeNode root = new TreeNode();
1704cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1705cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name1) );
1706cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1707cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AS_CHARACTER) );
1708cdf0e10cSrcweir         doTest(root);
1709cdf0e10cSrcweir     }
1710cdf0e10cSrcweir 
testFrameMark2()1711cdf0e10cSrcweir     @Test public void testFrameMark2() throws Exception
1712cdf0e10cSrcweir     {
1713cdf0e10cSrcweir         // BUG: #i98530#
1714cdf0e10cSrcweir         String name1 = mkName("bookmark");
1715cdf0e10cSrcweir         String name2 = mkName("frame");
1716cdf0e10cSrcweir         TreeNode root = new TreeNode();
1717cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1718cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name1) );
1719cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1720cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AT_CHARACTER) );
1721cdf0e10cSrcweir         doTest(root);
1722cdf0e10cSrcweir     }
1723cdf0e10cSrcweir 
testFrameMark3()1724cdf0e10cSrcweir     @Test public void testFrameMark3() throws Exception
1725cdf0e10cSrcweir     {
1726cdf0e10cSrcweir         String name1 = mkName("frame");
1727cdf0e10cSrcweir         String name2 = mkName("bookmark");
1728cdf0e10cSrcweir         TreeNode root = new TreeNode();
1729cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1730cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AS_CHARACTER) );
1731cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1732cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name2) );
1733cdf0e10cSrcweir         doTest(root);
1734cdf0e10cSrcweir     }
1735cdf0e10cSrcweir 
testFrameMark4()1736cdf0e10cSrcweir     @Test public void testFrameMark4() throws Exception
1737cdf0e10cSrcweir     {
1738cdf0e10cSrcweir         String name1 = mkName("frame");
1739cdf0e10cSrcweir         String name2 = mkName("bookmark");
1740cdf0e10cSrcweir         TreeNode root = new TreeNode();
1741cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1742cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AT_CHARACTER) );
1743cdf0e10cSrcweir         root.appendChild( new TextNode("de") );
1744cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name2) );
1745cdf0e10cSrcweir         doTest(root);
1746cdf0e10cSrcweir     }
1747cdf0e10cSrcweir 
testFrames1()1748cdf0e10cSrcweir     @Test public void testFrames1() throws Exception
1749cdf0e10cSrcweir     {
1750cdf0e10cSrcweir         String name1 = mkName("frame");
1751cdf0e10cSrcweir         String name2 = mkName("frame");
1752cdf0e10cSrcweir         String name3 = mkName("frame");
1753cdf0e10cSrcweir         TreeNode root = new TreeNode();
1754cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AT_CHARACTER) );
1755cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AT_CHARACTER) );
1756cdf0e10cSrcweir         root.appendChild( new FrameNode(name3, AT_CHARACTER) );
1757cdf0e10cSrcweir         doTest(root);
1758cdf0e10cSrcweir     }
1759cdf0e10cSrcweir 
testFrames2()1760cdf0e10cSrcweir     @Test public void testFrames2() throws Exception
1761cdf0e10cSrcweir     {
1762cdf0e10cSrcweir         String name1 = mkName("frame");
1763cdf0e10cSrcweir         String name2 = mkName("frame");
1764cdf0e10cSrcweir         String name3 = mkName("frame");
1765cdf0e10cSrcweir         TreeNode root = new TreeNode();
1766cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AS_CHARACTER) );
1767cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AS_CHARACTER) );
1768cdf0e10cSrcweir         root.appendChild( new FrameNode(name3, AS_CHARACTER) );
1769cdf0e10cSrcweir         doTest(root);
1770cdf0e10cSrcweir     }
1771cdf0e10cSrcweir 
testFrames3()1772cdf0e10cSrcweir     @Test public void testFrames3() throws Exception
1773cdf0e10cSrcweir     {
1774cdf0e10cSrcweir         String name1 = mkName("frame");
1775cdf0e10cSrcweir         String name2 = mkName("frame");
1776cdf0e10cSrcweir         String name3 = mkName("frame");
1777cdf0e10cSrcweir         TreeNode root = new TreeNode();
1778cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AT_CHARACTER) );
1779cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AS_CHARACTER) );
1780cdf0e10cSrcweir         root.appendChild( new FrameNode(name3, AT_CHARACTER) );
1781cdf0e10cSrcweir         doTest(root);
1782cdf0e10cSrcweir     }
1783cdf0e10cSrcweir 
testFrames4()1784cdf0e10cSrcweir     @Test public void testFrames4() throws Exception
1785cdf0e10cSrcweir     {
1786cdf0e10cSrcweir         String name1 = mkName("frame");
1787cdf0e10cSrcweir         String name2 = mkName("frame");
1788cdf0e10cSrcweir         String name3 = mkName("frame");
1789cdf0e10cSrcweir         TreeNode root = new TreeNode();
1790cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AT_CHARACTER) );
1791cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AT_CHARACTER) );
1792cdf0e10cSrcweir         root.appendChild( new FrameNode(name3, AS_CHARACTER) );
1793cdf0e10cSrcweir         doTest(root);
1794cdf0e10cSrcweir     }
1795cdf0e10cSrcweir 
testFrames5()1796cdf0e10cSrcweir     @Test public void testFrames5() throws Exception
1797cdf0e10cSrcweir     {
1798cdf0e10cSrcweir         String name1 = mkName("frame");
1799cdf0e10cSrcweir         String name2 = mkName("frame");
1800cdf0e10cSrcweir         String name3 = mkName("frame");
1801cdf0e10cSrcweir         TreeNode root = new TreeNode();
1802cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AS_CHARACTER) );
1803cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AT_CHARACTER) );
1804cdf0e10cSrcweir         root.appendChild( new FrameNode(name3, AT_CHARACTER) );
1805cdf0e10cSrcweir         doTest(root);
1806cdf0e10cSrcweir     }
1807cdf0e10cSrcweir 
testRubyHyperlink1()1808cdf0e10cSrcweir     @Test public void testRubyHyperlink1() throws Exception
1809cdf0e10cSrcweir     {
1810cdf0e10cSrcweir         String name1 = mkName("ruby");
1811cdf0e10cSrcweir         String name2 = mkName("url");
1812cdf0e10cSrcweir         TreeNode root = new TreeNode();
1813cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name1);
1814cdf0e10cSrcweir         TreeNode href = new HyperlinkNode(name2);
1815cdf0e10cSrcweir         href.appendChild( new TextNode("abc") );
1816cdf0e10cSrcweir         ruby.appendChild(href);
1817cdf0e10cSrcweir         root.appendChild(ruby);
1818cdf0e10cSrcweir         doTest(root);
1819cdf0e10cSrcweir     }
1820cdf0e10cSrcweir 
testRubyHyperlink2()1821cdf0e10cSrcweir     @Test public void testRubyHyperlink2() throws Exception
1822cdf0e10cSrcweir     {
1823cdf0e10cSrcweir         String name1 = mkName("url");
1824cdf0e10cSrcweir         String name2 = mkName("ruby");
1825cdf0e10cSrcweir         TreeNode root = new TreeNode();
1826cdf0e10cSrcweir         TreeNode href = new HyperlinkNode(name1);
1827cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name2);
1828cdf0e10cSrcweir         ruby.appendChild( new TextNode("abc") );
1829cdf0e10cSrcweir         href.appendChild(ruby);
1830cdf0e10cSrcweir         root.appendChild(href);
1831cdf0e10cSrcweir         doTest(root);
1832cdf0e10cSrcweir     }
1833cdf0e10cSrcweir 
testEnd1()1834cdf0e10cSrcweir     @Test public void testEnd1() throws Exception
1835cdf0e10cSrcweir     {
1836cdf0e10cSrcweir         String name1 = mkName("bookmark");
1837cdf0e10cSrcweir         String name2 = mkName("toxmark");
1838cdf0e10cSrcweir         String name3 = mkName("refmark");
1839cdf0e10cSrcweir         TreeNode root = new TreeNode();
1840cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1841cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name1) );
1842cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name2) );
1843cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name3) );
1844cdf0e10cSrcweir         doTest(root);
1845cdf0e10cSrcweir     }
1846cdf0e10cSrcweir 
testEnd2()1847cdf0e10cSrcweir     @Test public void testEnd2() throws Exception
1848cdf0e10cSrcweir     {
1849cdf0e10cSrcweir         String name1 = mkName("bookmark");
1850cdf0e10cSrcweir         String name2 = mkName("frame");
1851cdf0e10cSrcweir         String name3 = mkName("refmark");
1852cdf0e10cSrcweir         String name4 = mkName("frame");
1853cdf0e10cSrcweir         String name5 = mkName("frame");
1854cdf0e10cSrcweir         TreeNode root = new TreeNode();
1855cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1856cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name1) );
1857cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AT_CHARACTER) );
1858cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name3) );
1859cdf0e10cSrcweir         root.appendChild( new FrameNode(name4, AT_CHARACTER) );
1860cdf0e10cSrcweir         root.appendChild( new FrameNode(name5, AT_CHARACTER) );
1861cdf0e10cSrcweir         doTest(root);
1862cdf0e10cSrcweir     }
1863cdf0e10cSrcweir 
testEnd3()1864cdf0e10cSrcweir     @Test public void testEnd3() throws Exception
1865cdf0e10cSrcweir     {
1866cdf0e10cSrcweir         String name1 = mkName("ftn");
1867cdf0e10cSrcweir         String name2 = mkName("toxmark");
1868cdf0e10cSrcweir         TreeNode root = new TreeNode();
1869cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1870cdf0e10cSrcweir         root.appendChild( new FootnoteNode(name1) );
1871cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name2) );
1872cdf0e10cSrcweir         doTest(root);
1873cdf0e10cSrcweir     }
1874cdf0e10cSrcweir 
testEnd4()1875cdf0e10cSrcweir     @Test public void testEnd4() throws Exception
1876cdf0e10cSrcweir     {
1877cdf0e10cSrcweir         String name1 = mkName("bookmark");
1878cdf0e10cSrcweir         String name2 = mkName("frame");
1879cdf0e10cSrcweir         TreeNode root = new TreeNode();
1880cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name1) );
1881cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1882cdf0e10cSrcweir         root.appendChild( new FrameNode(name2, AS_CHARACTER) );
1883cdf0e10cSrcweir         root.appendChild( new BookmarkEndNode(name1) );
1884cdf0e10cSrcweir         doTest(root);
1885cdf0e10cSrcweir     }
1886cdf0e10cSrcweir 
testEnd5()1887cdf0e10cSrcweir     @Test public void testEnd5() throws Exception
1888cdf0e10cSrcweir     {
1889cdf0e10cSrcweir         String name1 = mkName("refmark");
1890cdf0e10cSrcweir         String name2 = mkName("ruby");
1891cdf0e10cSrcweir         TreeNode root = new TreeNode();
1892cdf0e10cSrcweir         root.appendChild( new ReferenceMarkStartNode(name1) );
1893cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1894cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name2);
1895cdf0e10cSrcweir         ruby.appendChild( new TextFieldNode("de") );
1896cdf0e10cSrcweir         root.appendChild(ruby);
1897cdf0e10cSrcweir         root.appendChild( new ReferenceMarkEndNode(name1) );
1898cdf0e10cSrcweir         doTest(root);
1899cdf0e10cSrcweir     }
1900cdf0e10cSrcweir 
testEmpty1()1901cdf0e10cSrcweir     @Test public void testEmpty1() throws Exception
1902cdf0e10cSrcweir     {
1903cdf0e10cSrcweir         String name1 = mkName("refmark");
1904cdf0e10cSrcweir         String name2 = mkName("toxmark");
1905cdf0e10cSrcweir         String name3 = mkName("bookmark");
1906cdf0e10cSrcweir         String name4 = mkName("frame");
1907cdf0e10cSrcweir         String name7 = mkName("refmark");
1908cdf0e10cSrcweir         String name8 = mkName("toxmark");
1909cdf0e10cSrcweir         String name9 = mkName("bookmark");
1910cdf0e10cSrcweir         String nameA = mkName("frame");
1911cdf0e10cSrcweir         TreeNode root = new TreeNode();
1912cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name1) );
1913cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name2) );
1914cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name3) );
1915cdf0e10cSrcweir         root.appendChild( new FrameNode(name4, AT_CHARACTER) );
1916cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name7) );
1917cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name8) );
1918cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name9) );
1919cdf0e10cSrcweir         root.appendChild( new FrameNode(nameA, AT_CHARACTER) );
1920cdf0e10cSrcweir         doTest(root);
1921cdf0e10cSrcweir     }
1922cdf0e10cSrcweir 
testEmpty2()1923cdf0e10cSrcweir     @Test public void testEmpty2() throws Exception
1924cdf0e10cSrcweir     {
1925cdf0e10cSrcweir         String name3 = mkName("bookmark");
1926cdf0e10cSrcweir         String name4 = mkName("frame");
1927cdf0e10cSrcweir         String name9 = mkName("bookmark");
1928cdf0e10cSrcweir         String nameA = mkName("frame");
1929cdf0e10cSrcweir         TreeNode root = new TreeNode();
1930cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name3) );
1931cdf0e10cSrcweir         root.appendChild( new FrameNode(name4, AT_CHARACTER) );
1932cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name9) );
1933cdf0e10cSrcweir         root.appendChild( new FrameNode(nameA, AT_CHARACTER) );
1934cdf0e10cSrcweir         doTest(root);
1935cdf0e10cSrcweir     }
1936cdf0e10cSrcweir 
testEmpty3()1937cdf0e10cSrcweir     @Test public void testEmpty3() throws Exception
1938cdf0e10cSrcweir     {
1939cdf0e10cSrcweir         String name1 = mkName("refmark");
1940cdf0e10cSrcweir         String name2 = mkName("toxmark");
1941cdf0e10cSrcweir         String name3 = mkName("bookmark");
1942cdf0e10cSrcweir         String name4 = mkName("frame");
1943cdf0e10cSrcweir         String name5 = mkName("url");
1944cdf0e10cSrcweir         String name6 = mkName("ruby");
1945cdf0e10cSrcweir         String name7 = mkName("refmark");
1946cdf0e10cSrcweir         String name8 = mkName("toxmark");
1947cdf0e10cSrcweir         String name9 = mkName("bookmark");
1948cdf0e10cSrcweir         String nameA = mkName("frame");
1949cdf0e10cSrcweir         TreeNode root = new TreeNode();
1950cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name1) );
1951cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name2) );
1952cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name3) );
1953cdf0e10cSrcweir         root.appendChild( new FrameNode(name4, AT_CHARACTER) );
1954cdf0e10cSrcweir         /* currently empty hyperlinks may get eaten...
1955cdf0e10cSrcweir         TreeNode href = new HyperlinkNode(name5);
1956cdf0e10cSrcweir         href.appendChild( new TextNode("") );
1957cdf0e10cSrcweir         root.appendChild(href);
1958cdf0e10cSrcweir         */
1959cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name6);
1960cdf0e10cSrcweir         root.appendChild(ruby);
1961cdf0e10cSrcweir         root.appendChild( new ReferenceMarkNode(name7) );
1962cdf0e10cSrcweir         root.appendChild( new DocumentIndexMarkNode(name8) );
1963cdf0e10cSrcweir         root.appendChild( new BookmarkNode(name9) );
1964cdf0e10cSrcweir         root.appendChild( new FrameNode(nameA, AT_CHARACTER) );
1965cdf0e10cSrcweir         doTest(root);
1966cdf0e10cSrcweir     }
1967cdf0e10cSrcweir 
test1()1968cdf0e10cSrcweir     @Test public void test1() throws Exception
1969cdf0e10cSrcweir     {
1970cdf0e10cSrcweir         String name1 = mkName("frame");
1971cdf0e10cSrcweir         String name2 = mkName("bookmark");
1972cdf0e10cSrcweir         String name3 = mkName("ruby");
1973cdf0e10cSrcweir         String name4 = mkName("ftn");
1974cdf0e10cSrcweir         String name5 = mkName("frame");
1975cdf0e10cSrcweir         TreeNode root = new TreeNode();
1976cdf0e10cSrcweir         root.appendChild( new FrameNode(name1, AT_CHARACTER) );
1977cdf0e10cSrcweir         root.appendChild( new BookmarkStartNode(name2) );
1978cdf0e10cSrcweir         root.appendChild( new TextNode("abc") );
1979cdf0e10cSrcweir         TreeNode ruby = new RubyNode(name3);
1980cdf0e10cSrcweir         ruby.appendChild( new TextNode("de") );
1981cdf0e10cSrcweir         ruby.appendChild( new FootnoteNode(name4) );
1982cdf0e10cSrcweir         ruby.appendChild( new BookmarkEndNode(name2) );
1983cdf0e10cSrcweir         root.appendChild(ruby);
1984cdf0e10cSrcweir         root.appendChild( new TextNode("fg") );
1985cdf0e10cSrcweir         root.appendChild( new FrameNode(name5, AT_CHARACTER) );
1986cdf0e10cSrcweir         root.appendChild( new TextFieldNode("h") );
1987cdf0e10cSrcweir         doTest(root);
1988cdf0e10cSrcweir     }
1989cdf0e10cSrcweir 
1990cdf0e10cSrcweir     /* some range tests for the insertion: these are for the current
1991cdf0e10cSrcweir        API which treats hyperlinks and rubys not as entities, but as formatting
1992cdf0e10cSrcweir        attributes; if these ever become entities, they should not be split!
1993cdf0e10cSrcweir      */
1994cdf0e10cSrcweir 
testRange1()1995cdf0e10cSrcweir     @Test public void testRange1() throws Exception
1996cdf0e10cSrcweir     {
1997cdf0e10cSrcweir         String name1 = mkName("url");
1998cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
1999cdf0e10cSrcweir         TreeNode text = new TextNode("12345");
2000cdf0e10cSrcweir         inserter.insertRange(new Range(0, 0, text));
2001cdf0e10cSrcweir         TreeNode url1 = new HyperlinkNode(name1);
2002cdf0e10cSrcweir         Range range1 = new Range(0, 5, url1);
2003cdf0e10cSrcweir         inserter.insertRange(range1);
2004cdf0e10cSrcweir         TreeNode root = new TreeNode();
2005cdf0e10cSrcweir         root.appendChild( url1 );
2006cdf0e10cSrcweir         url1.appendChild( text );
2007cdf0e10cSrcweir         doTest(root, false);
2008cdf0e10cSrcweir     }
2009cdf0e10cSrcweir 
testRangeHyperlinkHyperlink()2010cdf0e10cSrcweir     @Test public void testRangeHyperlinkHyperlink() throws Exception
2011cdf0e10cSrcweir     {
2012cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2013cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2014cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2015cdf0e10cSrcweir         TreeNode url1 = new HyperlinkNode( mkName("url") );
2016cdf0e10cSrcweir         inserter.insertRange( new Range(1, 4, url1) );
2017cdf0e10cSrcweir         // overlap left
2018cdf0e10cSrcweir         TreeNode url2 = new HyperlinkNode( mkName("url") );
2019cdf0e10cSrcweir         inserter.insertRange( new Range(0, 2, url2) );
2020cdf0e10cSrcweir         TreeNode root = new TreeNode()
2021cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("12") ) )
2022cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("34") ) )
2023cdf0e10cSrcweir             .appendChild( new TextNode("56789") );
2024cdf0e10cSrcweir         doTest(root, false);
2025cdf0e10cSrcweir         // overlap right
2026cdf0e10cSrcweir         TreeNode url3 = new HyperlinkNode( mkName("url") );
2027cdf0e10cSrcweir         inserter.insertRange( new Range(3, 7, url3) );
2028cdf0e10cSrcweir         root = new TreeNode()
2029cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("12") ) )
2030cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("3") ) )
2031cdf0e10cSrcweir             .appendChild( url3.dup().appendChild( new TextNode("4567") ) )
2032cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2033cdf0e10cSrcweir         doTest(root, false);
2034cdf0e10cSrcweir         // around
2035cdf0e10cSrcweir         TreeNode url4 = new HyperlinkNode( mkName("url") );
2036cdf0e10cSrcweir         inserter.insertRange( new Range(3, 7, url4) );
2037cdf0e10cSrcweir         root = new TreeNode()
2038cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("12") ) )
2039cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("3") ) )
2040cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("4567") ) )
2041cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2042cdf0e10cSrcweir         doTest(root, false);
2043cdf0e10cSrcweir         // inside
2044cdf0e10cSrcweir         TreeNode url5 = new HyperlinkNode( mkName("url") );
2045cdf0e10cSrcweir         inserter.insertRange( new Range(4, 6, url5) );
2046cdf0e10cSrcweir         root = new TreeNode()
2047cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("12") ) )
2048cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("3") ) )
2049cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("4") ) )
2050cdf0e10cSrcweir             .appendChild( url5.dup().appendChild( new TextNode("56") ) )
2051cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("7") ) )
2052cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2053cdf0e10cSrcweir         doTest(root, false);
2054cdf0e10cSrcweir         // empty
2055cdf0e10cSrcweir         TreeNode url6 = new HyperlinkNode( mkName("url") );
2056cdf0e10cSrcweir         inserter.insertRange( new Range(7, 7, url6) );
2057cdf0e10cSrcweir         root = new TreeNode()
2058cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("12") ) )
2059cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("3") ) )
2060cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("4") ) )
2061cdf0e10cSrcweir             .appendChild( url5.dup().appendChild( new TextNode("56") ) )
2062cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("7") ) )
2063cdf0e10cSrcweir // this one gets eaten, but we still need to test inserting it (#i106930#)
2064cdf0e10cSrcweir //            .appendChild( url6.dup().appendChild( new TextNode("") ) )
2065cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2066cdf0e10cSrcweir         doTest(root, false);
2067cdf0e10cSrcweir     }
2068cdf0e10cSrcweir 
testRangeHyperlinkRuby()2069cdf0e10cSrcweir     @Test public void testRangeHyperlinkRuby() throws Exception
2070cdf0e10cSrcweir     {
2071cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2072cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2073cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2074cdf0e10cSrcweir         TreeNode url1 = new HyperlinkNode( mkName("url") );
2075cdf0e10cSrcweir         inserter.insertRange( new Range(1, 4, url1) );
2076cdf0e10cSrcweir         // overlap left
2077cdf0e10cSrcweir         TreeNode rby2 = new RubyNode( mkName("ruby") );
2078cdf0e10cSrcweir         inserter.insertRange( new Range(0, 2, rby2) );
2079cdf0e10cSrcweir         TreeNode root = new TreeNode()
2080cdf0e10cSrcweir             .appendChild( rby2.dup()
2081cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2082cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2083cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("34") ) )
2084cdf0e10cSrcweir             .appendChild( new TextNode("56789") );
2085cdf0e10cSrcweir         doTest(root, false);
2086cdf0e10cSrcweir         // overlap right
2087cdf0e10cSrcweir         TreeNode rby3 = new RubyNode( mkName("ruby") );
2088cdf0e10cSrcweir         inserter.insertRange( new Range(3, 5, rby3) );
2089cdf0e10cSrcweir         root = new TreeNode()
2090cdf0e10cSrcweir             .appendChild( rby2.dup()
2091cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2092cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2093cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("3") ) )
2094cdf0e10cSrcweir             .appendChild( rby3.dup()
2095cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("4") ) )
2096cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2097cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2098cdf0e10cSrcweir         doTest(root, false);
2099cdf0e10cSrcweir         // around
2100cdf0e10cSrcweir         TreeNode rby4 = new RubyNode( mkName("ruby") );
2101cdf0e10cSrcweir         inserter.insertRange( new Range(2, 3, rby4) );
2102cdf0e10cSrcweir         root = new TreeNode()
2103cdf0e10cSrcweir             .appendChild( rby2.dup()
2104cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2105cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2106cdf0e10cSrcweir             .appendChild( rby4.dup()
2107cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("3") ) ) )
2108cdf0e10cSrcweir             .appendChild( rby3.dup()
2109cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("4") ) )
2110cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2111cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2112cdf0e10cSrcweir         doTest(root, false);
2113cdf0e10cSrcweir         // inside
2114cdf0e10cSrcweir         TreeNode url5 = new HyperlinkNode( mkName("url") );
2115cdf0e10cSrcweir         inserter.insertRange( new Range(6, 9, url5) );
2116cdf0e10cSrcweir         TreeNode rby6 = new RubyNode( mkName("ruby") );
2117cdf0e10cSrcweir         inserter.insertRange( new Range(7, 8, rby6) );
2118cdf0e10cSrcweir         root = new TreeNode()
2119cdf0e10cSrcweir             .appendChild( rby2.dup()
2120cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2121cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2122cdf0e10cSrcweir             .appendChild( rby4.dup()
2123cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("3") ) ) )
2124cdf0e10cSrcweir             .appendChild( rby3.dup()
2125cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("4") ) )
2126cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2127cdf0e10cSrcweir             .appendChild( new TextNode("6") )
2128cdf0e10cSrcweir             .appendChild( url5.dup().appendChild( new TextNode("7") ) )
2129cdf0e10cSrcweir             .appendChild( rby6.dup()
2130cdf0e10cSrcweir                 .appendChild( url5.dup().appendChild( new TextNode("8") ) ) )
2131cdf0e10cSrcweir             .appendChild( url5.dup().appendChild( new TextNode("9") ) );
2132cdf0e10cSrcweir         doTest(root, false);
2133cdf0e10cSrcweir     }
2134cdf0e10cSrcweir 
testRangeRubyHyperlink()2135cdf0e10cSrcweir     @Test public void testRangeRubyHyperlink() throws Exception
2136cdf0e10cSrcweir     {
2137cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2138cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2139cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2140cdf0e10cSrcweir         TreeNode rby1 = new RubyNode( mkName("ruby") );
2141cdf0e10cSrcweir         inserter.insertRange( new Range(1, 6, rby1) );
2142cdf0e10cSrcweir         // overlap left
2143cdf0e10cSrcweir         TreeNode url2 = new HyperlinkNode( mkName("url") );
2144cdf0e10cSrcweir         inserter.insertRange( new Range(0, 3, url2) );
2145cdf0e10cSrcweir         TreeNode root = new TreeNode()
2146cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2147cdf0e10cSrcweir             .appendChild( rby1.dup()
2148cdf0e10cSrcweir                 .appendChild( url2.dup().appendChild( new TextNode("23") ) )
2149cdf0e10cSrcweir                 .appendChild( new TextNode("456") ) )
2150cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2151cdf0e10cSrcweir         doTest(root, false);
2152cdf0e10cSrcweir         // overlap right
2153cdf0e10cSrcweir         TreeNode url3 = new HyperlinkNode( mkName("url") );
2154cdf0e10cSrcweir         inserter.insertRange( new Range(5, 7, url3) );
2155cdf0e10cSrcweir         root = new TreeNode()
2156cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2157cdf0e10cSrcweir             .appendChild( rby1.dup()
2158cdf0e10cSrcweir                 .appendChild( url2.dup().appendChild( new TextNode("23") ) )
2159cdf0e10cSrcweir                 .appendChild( new TextNode("45") )
2160cdf0e10cSrcweir                 .appendChild( url3.dup().appendChild( new TextNode("6") ) ) )
2161cdf0e10cSrcweir             .appendChild( url3.dup().appendChild( new TextNode("7") ) )
2162cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2163cdf0e10cSrcweir         doTest(root, false);
2164cdf0e10cSrcweir         // around (not quite, due to API)
2165cdf0e10cSrcweir         TreeNode url4 = new HyperlinkNode( mkName("url") );
2166cdf0e10cSrcweir         inserter.insertRange( new Range(1, 8, url4) );
2167cdf0e10cSrcweir         root = new TreeNode()
2168cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2169cdf0e10cSrcweir             .appendChild( rby1.dup()
2170cdf0e10cSrcweir                 .appendChild( url4.dup()
2171cdf0e10cSrcweir                     .appendChild( new TextNode("23456") ) ) )
2172cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("78") ) )
2173cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2174cdf0e10cSrcweir         doTest(root, false);
2175cdf0e10cSrcweir         // inside
2176cdf0e10cSrcweir         TreeNode url5 = new HyperlinkNode( mkName("url") );
2177cdf0e10cSrcweir         inserter.insertRange( new Range(3, 5, url5) );
2178cdf0e10cSrcweir         root = new TreeNode()
2179cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2180cdf0e10cSrcweir             .appendChild( rby1.dup()
2181cdf0e10cSrcweir                 .appendChild( url4.dup()
2182cdf0e10cSrcweir                     .appendChild( new TextNode("23") ) )
2183cdf0e10cSrcweir                 .appendChild( url5.dup()
2184cdf0e10cSrcweir                     .appendChild( new TextNode("45") ) )
2185cdf0e10cSrcweir                 .appendChild( url4.dup()
2186cdf0e10cSrcweir                     .appendChild( new TextNode("6") ) ) )
2187cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("78") ) )
2188cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2189cdf0e10cSrcweir         doTest(root, false);
2190cdf0e10cSrcweir     }
2191cdf0e10cSrcweir 
testRangeRubyRuby()2192cdf0e10cSrcweir     @Test public void testRangeRubyRuby() throws Exception
2193cdf0e10cSrcweir     {
2194cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2195cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2196cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2197cdf0e10cSrcweir         TreeNode rby1 = new RubyNode( mkName("ruby") );
2198cdf0e10cSrcweir         inserter.insertRange( new Range(1, 4, rby1) );
2199cdf0e10cSrcweir         // overlap left
2200cdf0e10cSrcweir         TreeNode rby2 = new RubyNode( mkName("ruby") );
2201cdf0e10cSrcweir         inserter.insertRange( new Range(0, 2, rby2) );
2202cdf0e10cSrcweir         TreeNode root = new TreeNode()
2203cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("12") ) )
2204cdf0e10cSrcweir             .appendChild( rby1.dup().appendChild( new TextNode("34") ) )
2205cdf0e10cSrcweir             .appendChild( new TextNode("56789") );
2206cdf0e10cSrcweir         doTest(root, false);
2207cdf0e10cSrcweir         // overlap right
2208cdf0e10cSrcweir         TreeNode rby3 = new RubyNode( mkName("ruby") );
2209cdf0e10cSrcweir         inserter.insertRange( new Range(3, 7, rby3) );
2210cdf0e10cSrcweir         root = new TreeNode()
2211cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("12") ) )
2212cdf0e10cSrcweir             .appendChild( rby1.dup().appendChild( new TextNode("3") ) )
2213cdf0e10cSrcweir             .appendChild( rby3.dup().appendChild( new TextNode("4567") ) )
2214cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2215cdf0e10cSrcweir         doTest(root, false);
2216cdf0e10cSrcweir         // around
2217cdf0e10cSrcweir         TreeNode rby4 = new RubyNode( mkName("ruby") );
2218cdf0e10cSrcweir         inserter.insertRange( new Range(3, 7, rby4) );
2219cdf0e10cSrcweir         root = new TreeNode()
2220cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("12") ) )
2221cdf0e10cSrcweir             .appendChild( rby1.dup().appendChild( new TextNode("3") ) )
2222cdf0e10cSrcweir             .appendChild( rby4.dup().appendChild( new TextNode("4567") ) )
2223cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2224cdf0e10cSrcweir         doTest(root, false);
2225cdf0e10cSrcweir         // inside
2226cdf0e10cSrcweir         TreeNode rby5 = new RubyNode( mkName("ruby") );
2227cdf0e10cSrcweir         inserter.insertRange( new Range(4, 6, rby5) );
2228cdf0e10cSrcweir         root = new TreeNode()
2229cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("12") ) )
2230cdf0e10cSrcweir             .appendChild( rby1.dup().appendChild( new TextNode("3") ) )
2231cdf0e10cSrcweir             .appendChild( rby4.dup().appendChild( new TextNode("4") ) )
2232cdf0e10cSrcweir             .appendChild( rby5.dup().appendChild( new TextNode("56") ) )
2233cdf0e10cSrcweir             .appendChild( rby4.dup().appendChild( new TextNode("7") ) )
2234cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2235cdf0e10cSrcweir         doTest(root, false);
2236cdf0e10cSrcweir     }
2237cdf0e10cSrcweir 
testRangeHyperlinkMeta()2238cdf0e10cSrcweir     @Test public void testRangeHyperlinkMeta() throws Exception
2239cdf0e10cSrcweir     {
2240cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2241cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2242cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2243cdf0e10cSrcweir         TreeNode url1 = new HyperlinkNode( mkName("url") );
2244cdf0e10cSrcweir         inserter.insertRange( new Range(1, 4, url1) );
2245cdf0e10cSrcweir         // overlap left
2246cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2247cdf0e10cSrcweir         inserter.insertRange( new Range(0, 2, met2) );
2248cdf0e10cSrcweir         TreeNode root = new TreeNode()
2249cdf0e10cSrcweir             .appendChild( met2.dup()
2250cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2251cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2252cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("34") ) )
2253cdf0e10cSrcweir             .appendChild( new TextNode("56789") );
2254cdf0e10cSrcweir         doTest(root, false);
2255cdf0e10cSrcweir         // overlap right
2256cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2257cdf0e10cSrcweir         inserter.insertRange( new Range(4/*-1*/, 6/*-1*/, met3) );
2258cdf0e10cSrcweir         root = new TreeNode()
2259cdf0e10cSrcweir             .appendChild( met2.dup()
2260cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2261cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2262cdf0e10cSrcweir             .appendChild( url1.dup().appendChild( new TextNode("3") ) )
2263cdf0e10cSrcweir             .appendChild( met3.dup()
2264cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("4") ) )
2265cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2266cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2267cdf0e10cSrcweir         doTest(root, false);
2268cdf0e10cSrcweir         // around
2269cdf0e10cSrcweir         TreeNode met4 = new MetaNode( mkId("id") );
2270cdf0e10cSrcweir         inserter.insertRange( new Range(3/*-1*/, 4/*-1*/, met4) );
2271cdf0e10cSrcweir         root = new TreeNode()
2272cdf0e10cSrcweir             .appendChild( met2.dup()
2273cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2274cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2275cdf0e10cSrcweir             .appendChild( met4.dup()
2276cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("3") ) ) )
2277cdf0e10cSrcweir             .appendChild( met3.dup()
2278cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("4") ) )
2279cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2280cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2281cdf0e10cSrcweir         doTest(root, false);
2282cdf0e10cSrcweir         // inside
2283cdf0e10cSrcweir         TreeNode url5 = new HyperlinkNode( mkName("url") );
2284cdf0e10cSrcweir         inserter.insertRange( new Range(9/*-3*/, 12/*-3*/, url5) );
2285cdf0e10cSrcweir         TreeNode met6 = new MetaNode( mkId("id") );
2286cdf0e10cSrcweir         inserter.insertRange( new Range(10/*-3*/, 11/*-3*/, met6) );
2287cdf0e10cSrcweir         root = new TreeNode()
2288cdf0e10cSrcweir             .appendChild( met2.dup()
2289cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2290cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("2") ) ) )
2291cdf0e10cSrcweir             .appendChild( met4.dup()
2292cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("3") ) ) )
2293cdf0e10cSrcweir             .appendChild( met3.dup()
2294cdf0e10cSrcweir                 .appendChild( url1.dup().appendChild( new TextNode("4") ) )
2295cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2296cdf0e10cSrcweir             .appendChild( new TextNode("6") )
2297cdf0e10cSrcweir             .appendChild( url5.dup().appendChild( new TextNode("7") ) )
2298cdf0e10cSrcweir             .appendChild( met6.dup()
2299cdf0e10cSrcweir                 .appendChild( url5.dup().appendChild( new TextNode("8") ) ) )
2300cdf0e10cSrcweir             .appendChild( url5.dup().appendChild( new TextNode("9") ) );
2301cdf0e10cSrcweir         doTest(root, false);
2302cdf0e10cSrcweir     }
2303cdf0e10cSrcweir 
testRangeRubyMeta()2304cdf0e10cSrcweir     @Test public void testRangeRubyMeta() throws Exception
2305cdf0e10cSrcweir     {
2306cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2307cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2308cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2309cdf0e10cSrcweir         TreeNode rby1 = new RubyNode( mkName("ruby") );
2310cdf0e10cSrcweir         inserter.insertRange( new Range(1, 4, rby1) );
2311cdf0e10cSrcweir         // overlap left
2312cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2313cdf0e10cSrcweir         inserter.insertRange( new Range(0, 2, met2) );
2314cdf0e10cSrcweir         TreeNode root = new TreeNode()
2315cdf0e10cSrcweir             .appendChild( met2.dup()
2316cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2317cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("2") ) ) )
2318cdf0e10cSrcweir             .appendChild( rby1.dup().appendChild( new TextNode("34") ) )
2319cdf0e10cSrcweir             .appendChild( new TextNode("56789") );
2320cdf0e10cSrcweir         doTest(root, false);
2321cdf0e10cSrcweir         // overlap right
2322cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2323cdf0e10cSrcweir         inserter.insertRange( new Range(4/*-1*/, 6/*-1*/, met3) );
2324cdf0e10cSrcweir         root = new TreeNode()
2325cdf0e10cSrcweir             .appendChild( met2.dup()
2326cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2327cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("2") ) ) )
2328cdf0e10cSrcweir             .appendChild( rby1.dup().appendChild( new TextNode("3") ) )
2329cdf0e10cSrcweir             .appendChild( met3.dup()
2330cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("4") ) )
2331cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2332cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2333cdf0e10cSrcweir         doTest(root, false);
2334cdf0e10cSrcweir         // around
2335cdf0e10cSrcweir         TreeNode met4 = new MetaNode( mkId("id") );
2336cdf0e10cSrcweir         inserter.insertRange( new Range(3/*-1*/, 4/*-1*/, met4) );
2337cdf0e10cSrcweir         root = new TreeNode()
2338cdf0e10cSrcweir             .appendChild( met2.dup()
2339cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2340cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("2") ) ) )
2341cdf0e10cSrcweir             .appendChild( met4.dup()
2342cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("3") ) ) )
2343cdf0e10cSrcweir             .appendChild( met3.dup()
2344cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("4") ) )
2345cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2346cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2347cdf0e10cSrcweir         doTest(root, false);
2348cdf0e10cSrcweir         // inside
2349cdf0e10cSrcweir         TreeNode rby5 = new RubyNode( mkName("ruby") );
2350cdf0e10cSrcweir         inserter.insertRange( new Range(9/*-3*/, 12/*-3*/, rby5) );
2351cdf0e10cSrcweir         TreeNode met6 = new MetaNode( mkId("id") );
2352cdf0e10cSrcweir         inserter.insertRange( new Range(10/*-3*/, 11/*-3*/, met6) );
2353cdf0e10cSrcweir         root = new TreeNode()
2354cdf0e10cSrcweir             .appendChild( met2.dup()
2355cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2356cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("2") ) ) )
2357cdf0e10cSrcweir             .appendChild( met4.dup()
2358cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("3") ) ) )
2359cdf0e10cSrcweir             .appendChild( met3.dup()
2360cdf0e10cSrcweir                 .appendChild( rby1.dup().appendChild( new TextNode("4") ) )
2361cdf0e10cSrcweir                 .appendChild( new TextNode("5") ) )
2362cdf0e10cSrcweir             .appendChild( new TextNode("6") )
2363cdf0e10cSrcweir             .appendChild( rby5.dup()
2364cdf0e10cSrcweir                 .appendChild( new TextNode("7") )
2365cdf0e10cSrcweir                 .appendChild( met6.dup()
2366cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) )
2367cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2368cdf0e10cSrcweir         doTest(root, false);
2369cdf0e10cSrcweir     }
2370cdf0e10cSrcweir 
testRangeMetaHyperlink()2371cdf0e10cSrcweir     @Test public void testRangeMetaHyperlink() throws Exception
2372cdf0e10cSrcweir     {
2373cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2374cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2375cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2376cdf0e10cSrcweir         TreeNode met1 = new MetaNode( mkId("id") );
2377cdf0e10cSrcweir         inserter.insertRange( new Range(1, 6, met1) );
2378cdf0e10cSrcweir         // overlap left
2379cdf0e10cSrcweir         TreeNode url2 = new HyperlinkNode( mkName("url") );
2380cdf0e10cSrcweir         inserter.insertRange( new Range(0, 4/*-1*/, url2) );
2381cdf0e10cSrcweir         TreeNode root = new TreeNode()
2382cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2383cdf0e10cSrcweir             .appendChild( met1.dup()
2384cdf0e10cSrcweir                 .appendChild( url2.dup().appendChild( new TextNode("23") ) )
2385cdf0e10cSrcweir                 .appendChild( new TextNode("456") ) )
2386cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2387cdf0e10cSrcweir         doTest(root, false);
2388cdf0e10cSrcweir         // overlap right
2389cdf0e10cSrcweir         TreeNode url3 = new HyperlinkNode( mkName("url") );
2390cdf0e10cSrcweir         inserter.insertRange( new Range(6/*-1*/, 8/*-1*/, url3) );
2391cdf0e10cSrcweir         root = new TreeNode()
2392cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2393cdf0e10cSrcweir             .appendChild( met1.dup()
2394cdf0e10cSrcweir                 .appendChild( url2.dup().appendChild( new TextNode("23") ) )
2395cdf0e10cSrcweir                 .appendChild( new TextNode("45") )
2396cdf0e10cSrcweir                 .appendChild( url3.dup().appendChild( new TextNode("6") ) ) )
2397cdf0e10cSrcweir             .appendChild( url3.dup().appendChild( new TextNode("7") ) )
2398cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2399cdf0e10cSrcweir         doTest(root, false);
2400cdf0e10cSrcweir         // around (not quite, due to API)
2401cdf0e10cSrcweir         TreeNode url4 = new HyperlinkNode( mkName("url") );
2402cdf0e10cSrcweir         inserter.insertRange( new Range(1, 9/*-1*/, url4) );
2403cdf0e10cSrcweir         root = new TreeNode()
2404cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2405cdf0e10cSrcweir             .appendChild( met1.dup()
2406cdf0e10cSrcweir                 .appendChild( url4.dup()
2407cdf0e10cSrcweir                     .appendChild( new TextNode("23456") ) ) )
2408cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("78") ) )
2409cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2410cdf0e10cSrcweir         doTest(root, false);
2411cdf0e10cSrcweir         // inside
2412cdf0e10cSrcweir         TreeNode url5 = new HyperlinkNode( mkName("url") );
2413cdf0e10cSrcweir         inserter.insertRange( new Range(4/*-1*/, 6/*-1*/, url5) );
2414cdf0e10cSrcweir         root = new TreeNode()
2415cdf0e10cSrcweir             .appendChild( url2.dup().appendChild( new TextNode("1") ) )
2416cdf0e10cSrcweir             .appendChild( met1.dup()
2417cdf0e10cSrcweir                 .appendChild( url4.dup()
2418cdf0e10cSrcweir                     .appendChild( new TextNode("23") ) )
2419cdf0e10cSrcweir                 .appendChild( url5.dup()
2420cdf0e10cSrcweir                     .appendChild( new TextNode("45") ) )
2421cdf0e10cSrcweir                 .appendChild( url4.dup()
2422cdf0e10cSrcweir                     .appendChild( new TextNode("6") ) ) )
2423cdf0e10cSrcweir             .appendChild( url4.dup().appendChild( new TextNode("78") ) )
2424cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2425cdf0e10cSrcweir         doTest(root, false);
2426cdf0e10cSrcweir     }
2427cdf0e10cSrcweir 
testRangeMetaRuby()2428cdf0e10cSrcweir     @Test public void testRangeMetaRuby() throws Exception
2429cdf0e10cSrcweir     {
2430cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2431cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2432cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2433cdf0e10cSrcweir         TreeNode met1 = new MetaNode( mkId("id") );
2434cdf0e10cSrcweir         inserter.insertRange( new Range(1, 5, met1) );
2435cdf0e10cSrcweir         // overlap left
2436cdf0e10cSrcweir         TreeNode rby2 = new RubyNode( mkName("ruby") );
2437cdf0e10cSrcweir         inserter.insertRange( new Range(0, 3/*-1*/, rby2) );
2438cdf0e10cSrcweir         TreeNode root = new TreeNode()
2439cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("1") ) )
2440cdf0e10cSrcweir             .appendChild( met1.dup()
2441cdf0e10cSrcweir                 .appendChild( rby2.dup().appendChild( new TextNode("2") ) )
2442cdf0e10cSrcweir                 .appendChild( new TextNode("345") ) )
2443cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2444cdf0e10cSrcweir         doTest(root, false);
2445cdf0e10cSrcweir         // overlap right
2446cdf0e10cSrcweir         TreeNode rby3 = new RubyNode( mkName("ruby") );
2447cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-1*/, 7/*-1*/, rby3) );
2448cdf0e10cSrcweir         root = new TreeNode()
2449cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("1") ) )
2450cdf0e10cSrcweir             .appendChild( met1.dup()
2451cdf0e10cSrcweir                 .appendChild( rby2.dup().appendChild( new TextNode("2") ) )
2452cdf0e10cSrcweir                 .appendChild( new TextNode("34") )
2453cdf0e10cSrcweir                 .appendChild( rby3.dup().appendChild( new TextNode("5") ) ) )
2454cdf0e10cSrcweir             .appendChild( rby3.dup().appendChild( new TextNode("6") ) )
2455cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2456cdf0e10cSrcweir         doTest(root, false);
2457cdf0e10cSrcweir         // around
2458cdf0e10cSrcweir         TreeNode rby4 = new RubyNode( mkName("ruby") );
2459cdf0e10cSrcweir         inserter.insertRange( new Range(1, 7/*-1*/, rby4) );
2460cdf0e10cSrcweir         root = new TreeNode()
2461cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("1") ) )
2462cdf0e10cSrcweir             .appendChild( rby4.dup()
2463cdf0e10cSrcweir                 .appendChild( met1.dup()
2464cdf0e10cSrcweir                     .appendChild( new TextNode("2345") ) )
2465cdf0e10cSrcweir                 .appendChild( new TextNode("6") ) )
2466cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2467cdf0e10cSrcweir         doTest(root, false);
2468cdf0e10cSrcweir         // inside
2469cdf0e10cSrcweir         TreeNode met5 = new MetaNode( mkId("id") );
2470cdf0e10cSrcweir         inserter.insertRange( new Range(7/*-1*/, 9/*-1*/, met5) );
2471cdf0e10cSrcweir         TreeNode rby6 = new RubyNode( mkName("ruby") );
2472cdf0e10cSrcweir         inserter.insertRange( new Range(9/*-2*/, 10/*-2*/, rby6) );
2473cdf0e10cSrcweir         root = new TreeNode()
2474cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("1") ) )
2475cdf0e10cSrcweir             .appendChild( rby4.dup()
2476cdf0e10cSrcweir                 .appendChild( met1.dup()
2477cdf0e10cSrcweir                     .appendChild( new TextNode("2345") ) )
2478cdf0e10cSrcweir                 .appendChild( new TextNode("6") ) )
2479cdf0e10cSrcweir             .appendChild( met5.dup()
2480cdf0e10cSrcweir                 .appendChild( new TextNode("7") )
2481cdf0e10cSrcweir                 .appendChild( rby6.dup()
2482cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) ) )
2483cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2484cdf0e10cSrcweir         doTest(root, false);
2485cdf0e10cSrcweir         // inside, with invalid range that includes the dummy char
2486cdf0e10cSrcweir         TreeNode rby7 = new RubyNode( mkName("ruby") );
2487cdf0e10cSrcweir         inserter.insertRange( new Range(7/*-1*/, 9/*-2*/, rby7) );
2488cdf0e10cSrcweir         root = new TreeNode()
2489cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("1") ) )
2490cdf0e10cSrcweir             .appendChild( rby4.dup()
2491cdf0e10cSrcweir                 .appendChild( met1.dup()
2492cdf0e10cSrcweir                     .appendChild( new TextNode("2345") ) )
2493cdf0e10cSrcweir                 .appendChild( new TextNode("6") ) )
2494cdf0e10cSrcweir             .appendChild( met5.dup()
2495cdf0e10cSrcweir                 .appendChild( rby7.dup()
2496cdf0e10cSrcweir                     .appendChild( new TextNode("7") ) )
2497cdf0e10cSrcweir                 .appendChild( rby6.dup()
2498cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) ) )
2499cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2500cdf0e10cSrcweir         doTest(root, false);
2501cdf0e10cSrcweir         // around, at same position as meta
2502cdf0e10cSrcweir         TreeNode rby8 = new RubyNode( mkName("ruby") );
2503cdf0e10cSrcweir         inserter.insertRange( new Range(7/*-1*/, 10/*-2*/, rby8) );
2504cdf0e10cSrcweir         root = new TreeNode()
2505cdf0e10cSrcweir             .appendChild( rby2.dup().appendChild( new TextNode("1") ) )
2506cdf0e10cSrcweir             .appendChild( rby4.dup()
2507cdf0e10cSrcweir                 .appendChild( met1.dup()
2508cdf0e10cSrcweir                     .appendChild( new TextNode("2345") ) )
2509cdf0e10cSrcweir                 .appendChild( new TextNode("6") ) )
2510cdf0e10cSrcweir             .appendChild( rby8.dup()
2511cdf0e10cSrcweir                 .appendChild( met5.dup()
2512cdf0e10cSrcweir                     .appendChild( new TextNode("78") ) ) )
2513cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2514cdf0e10cSrcweir         doTest(root, false);
2515cdf0e10cSrcweir     }
2516cdf0e10cSrcweir 
testRangeMetaMeta()2517cdf0e10cSrcweir     @Test public void testRangeMetaMeta() throws Exception
2518cdf0e10cSrcweir     {
2519cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2520cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2521cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2522cdf0e10cSrcweir         TreeNode met1 = new MetaNode( mkId("id") );
2523cdf0e10cSrcweir         inserter.insertRange( new Range(3, 6, met1) );
2524cdf0e10cSrcweir         // overlap left
2525cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2526cdf0e10cSrcweir         try {
2527cdf0e10cSrcweir             inserter.insertRange( new Range(0, 4, met2) );
2528cdf0e10cSrcweir             fail("testRangeMetaMeta: overlap left allowed");
2529cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
2530cdf0e10cSrcweir         TreeNode root = new TreeNode()
2531cdf0e10cSrcweir             .appendChild( new TextNode("123") )
2532cdf0e10cSrcweir             .appendChild( met1.dup().appendChild( new TextNode("456") ) )
2533cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2534cdf0e10cSrcweir         doTest(root, false);
2535cdf0e10cSrcweir         // overlap right
2536cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2537cdf0e10cSrcweir         try {
2538cdf0e10cSrcweir             inserter.insertRange( new Range(5/*-1*/, 8/*-1*/, met3) );
2539cdf0e10cSrcweir             fail("testRangeMetaMeta: overlap right allowed");
2540cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
2541cdf0e10cSrcweir         root = new TreeNode()
2542cdf0e10cSrcweir             .appendChild( new TextNode("123") )
2543cdf0e10cSrcweir             .appendChild( met1.dup().appendChild( new TextNode("456") ) )
2544cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2545cdf0e10cSrcweir         doTest(root, false);
2546cdf0e10cSrcweir         // around
2547cdf0e10cSrcweir         TreeNode met4 = new MetaNode( mkId("id") );
2548cdf0e10cSrcweir         inserter.insertRange( new Range(3, 7/*-1*/, met4) );
2549cdf0e10cSrcweir         root = new TreeNode()
2550cdf0e10cSrcweir             .appendChild( new TextNode("123") )
2551cdf0e10cSrcweir             .appendChild( met4.dup()
2552cdf0e10cSrcweir                 .appendChild( met1.dup().appendChild( new TextNode("456") ) ) )
2553cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2554cdf0e10cSrcweir         doTest(root, false);
2555cdf0e10cSrcweir         // inside
2556cdf0e10cSrcweir         TreeNode met5 = new MetaNode( mkId("id") );
2557cdf0e10cSrcweir         inserter.insertRange( new Range(6/*-2*/, 8/*-2*/, met5) );
2558cdf0e10cSrcweir         root = new TreeNode()
2559cdf0e10cSrcweir             .appendChild( new TextNode("123") )
2560cdf0e10cSrcweir             .appendChild( met4.dup()
2561cdf0e10cSrcweir                 .appendChild( met1.dup()
2562cdf0e10cSrcweir                     .appendChild( new TextNode("4") )
2563cdf0e10cSrcweir                     .appendChild( met5.dup()
2564cdf0e10cSrcweir                         .appendChild( new TextNode("56") ) ) ) )
2565cdf0e10cSrcweir             .appendChild( new TextNode("789") );
2566cdf0e10cSrcweir         doTest(root, false);
2567cdf0e10cSrcweir     }
2568cdf0e10cSrcweir 
testRange2()2569cdf0e10cSrcweir     @Test public void testRange2() throws Exception
2570cdf0e10cSrcweir     {
2571cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2572cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2573cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2574cdf0e10cSrcweir         TreeNode met1 = new MetaNode( mkId("id") );
2575cdf0e10cSrcweir         inserter.insertRange( new Range(1, 8, met1) );
2576cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2577cdf0e10cSrcweir         inserter.insertRange( new Range(3/*-1*/, 8/*-1*/, met2) );
2578cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2579cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-2*/, 8/*-2*/, met3) );
2580cdf0e10cSrcweir         TreeNode root = new TreeNode()
2581cdf0e10cSrcweir             .appendChild( new TextNode("1") )
2582cdf0e10cSrcweir             .appendChild( met1.dup()
2583cdf0e10cSrcweir                 .appendChild( new TextNode("2") )
2584cdf0e10cSrcweir                 .appendChild( met2.dup()
2585cdf0e10cSrcweir                     .appendChild( new TextNode("3") )
2586cdf0e10cSrcweir                     .appendChild( met3.dup()
2587cdf0e10cSrcweir                         .appendChild( new TextNode("456") ) )
2588cdf0e10cSrcweir                     .appendChild( new TextNode("7") ) )
2589cdf0e10cSrcweir                 .appendChild( new TextNode("8") ) )
2590cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2591cdf0e10cSrcweir         doTest(root, false);
2592cdf0e10cSrcweir         // split ruby at every meta start!
2593cdf0e10cSrcweir         TreeNode rby4 = new RubyNode( mkName("ruby") );
2594cdf0e10cSrcweir         inserter.insertRange( new Range(0, 7/*-3*/, rby4) );
2595cdf0e10cSrcweir         root = new TreeNode()
2596cdf0e10cSrcweir             .appendChild( rby4.dup()
2597cdf0e10cSrcweir                 .appendChild( new TextNode("1") ) )
2598cdf0e10cSrcweir             .appendChild( met1.dup()
2599cdf0e10cSrcweir                 .appendChild( rby4.dup()
2600cdf0e10cSrcweir                     .appendChild( new TextNode("2") ) )
2601cdf0e10cSrcweir                 .appendChild( met2.dup()
2602cdf0e10cSrcweir                     .appendChild( rby4.dup()
2603cdf0e10cSrcweir                         .appendChild( new TextNode("3") ) )
2604cdf0e10cSrcweir                     .appendChild( met3.dup()
2605cdf0e10cSrcweir                         .appendChild( rby4.dup()
2606cdf0e10cSrcweir                             .appendChild( new TextNode("4") ) )
2607cdf0e10cSrcweir                         .appendChild( new TextNode("56") ) )
2608cdf0e10cSrcweir                     .appendChild( new TextNode("7") ) )
2609cdf0e10cSrcweir                 .appendChild( new TextNode("8") ) )
2610cdf0e10cSrcweir             .appendChild( new TextNode("9") );
2611cdf0e10cSrcweir         doTest(root, false);
2612cdf0e10cSrcweir         // split ruby at every meta end!
2613cdf0e10cSrcweir         TreeNode rby5 = new RubyNode( mkName("ruby") );
2614cdf0e10cSrcweir         inserter.insertRange( new Range(8/*-3*/, 12/*-3*/, rby5) );
2615cdf0e10cSrcweir         root = new TreeNode()
2616cdf0e10cSrcweir             .appendChild( rby4.dup()
2617cdf0e10cSrcweir                 .appendChild( new TextNode("1") ) )
2618cdf0e10cSrcweir             .appendChild( met1.dup()
2619cdf0e10cSrcweir                 .appendChild( rby4.dup()
2620cdf0e10cSrcweir                     .appendChild( new TextNode("2") ) )
2621cdf0e10cSrcweir                 .appendChild( met2.dup()
2622cdf0e10cSrcweir                     .appendChild( rby4.dup()
2623cdf0e10cSrcweir                         .appendChild( new TextNode("3") ) )
2624cdf0e10cSrcweir                     .appendChild( met3.dup()
2625cdf0e10cSrcweir                         .appendChild( rby4.dup()
2626cdf0e10cSrcweir                             .appendChild( new TextNode("4") ) )
2627cdf0e10cSrcweir                         .appendChild( new TextNode("5") )
2628cdf0e10cSrcweir                         .appendChild( rby5.dup()
2629cdf0e10cSrcweir                             .appendChild( new TextNode("6") ) ) )
2630cdf0e10cSrcweir                     .appendChild( rby5.dup()
2631cdf0e10cSrcweir                         .appendChild( new TextNode("7") ) ) )
2632cdf0e10cSrcweir                 .appendChild( rby5.dup()
2633cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) ) )
2634cdf0e10cSrcweir             .appendChild( rby5.dup()
2635cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2636cdf0e10cSrcweir         doTest(root, false);
2637cdf0e10cSrcweir     }
2638cdf0e10cSrcweir 
testRange3()2639cdf0e10cSrcweir     @Test public void testRange3() throws Exception
2640cdf0e10cSrcweir     {
2641cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2642cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2643cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2644cdf0e10cSrcweir         TreeNode rby1 = new RubyNode( mkName("ruby") );
2645cdf0e10cSrcweir         inserter.insertRange( new Range(0, 9, rby1) );
2646cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2647cdf0e10cSrcweir         inserter.insertRange( new Range(2, 7, met2) );
2648cdf0e10cSrcweir         TreeNode root = new TreeNode()
2649cdf0e10cSrcweir             .appendChild( rby1.dup()
2650cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
2651cdf0e10cSrcweir                 .appendChild( met2.dup()
2652cdf0e10cSrcweir                     .appendChild( new TextNode("34567") ) )
2653cdf0e10cSrcweir                 .appendChild( new TextNode("89") ) );
2654cdf0e10cSrcweir         doTest(root, false);
2655cdf0e10cSrcweir         // overwrite outer ruby, split remains at inner meta!
2656cdf0e10cSrcweir         TreeNode rby3 = new RubyNode( mkName("ruby") );
2657cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-1*/, 6/*-1*/, rby3) );
2658cdf0e10cSrcweir         root = new TreeNode()
2659cdf0e10cSrcweir             .appendChild( rby1.dup()
2660cdf0e10cSrcweir                 .appendChild( new TextNode("12") ) )
2661cdf0e10cSrcweir             .appendChild( met2.dup()
2662cdf0e10cSrcweir                 .appendChild( rby1.dup()
2663cdf0e10cSrcweir                     .appendChild( new TextNode("34") ) )
2664cdf0e10cSrcweir                 .appendChild( rby3.dup()
2665cdf0e10cSrcweir                     .appendChild( new TextNode("5") ) )
2666cdf0e10cSrcweir                 .appendChild( rby1.dup()
2667cdf0e10cSrcweir                     .appendChild( new TextNode("67") ) ) )
2668cdf0e10cSrcweir             .appendChild( rby1.dup()
2669cdf0e10cSrcweir                 .appendChild( new TextNode("89") ) );
2670cdf0e10cSrcweir         doTest(root, false);
2671cdf0e10cSrcweir     }
2672cdf0e10cSrcweir 
testRange4()2673cdf0e10cSrcweir     @Test public void testRange4() throws Exception
2674cdf0e10cSrcweir     {
2675cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2676cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2677cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2678cdf0e10cSrcweir         TreeNode rby1 = new RubyNode( mkName("ruby") );
2679cdf0e10cSrcweir         inserter.insertRange( new Range(0, 9, rby1) );
2680cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2681cdf0e10cSrcweir         inserter.insertRange( new Range(1, 8, met2) );
2682cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2683cdf0e10cSrcweir         inserter.insertRange( new Range(3/*-1*/, 8/*-1*/, met3) );
2684cdf0e10cSrcweir         TreeNode met4 = new MetaNode( mkId("id") );
2685cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-2*/, 8/*-2*/, met4) );
2686cdf0e10cSrcweir         TreeNode root = new TreeNode()
2687cdf0e10cSrcweir             .appendChild( rby1.dup()
2688cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2689cdf0e10cSrcweir                 .appendChild( met2.dup()
2690cdf0e10cSrcweir                     .appendChild( new TextNode("2") )
2691cdf0e10cSrcweir                     .appendChild( met3.dup()
2692cdf0e10cSrcweir                         .appendChild( new TextNode("3") )
2693cdf0e10cSrcweir                         .appendChild( met4.dup()
2694cdf0e10cSrcweir                             .appendChild( new TextNode("456") ) )
2695cdf0e10cSrcweir                         .appendChild( new TextNode("7") ) )
2696cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) )
2697cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2698cdf0e10cSrcweir         doTest(root, false);
2699cdf0e10cSrcweir         // overwrite outer ruby, split remains at every inner meta!
2700cdf0e10cSrcweir         TreeNode rby5 = new RubyNode( mkName("ruby") );
2701cdf0e10cSrcweir         inserter.insertRange( new Range(7/*-3*/, 8/*-3*/, rby5) );
2702cdf0e10cSrcweir         root = new TreeNode()
2703cdf0e10cSrcweir             .appendChild( rby1.dup()
2704cdf0e10cSrcweir                 .appendChild( new TextNode("1") ) )
2705cdf0e10cSrcweir             .appendChild( met2.dup()
2706cdf0e10cSrcweir                 .appendChild( rby1.dup()
2707cdf0e10cSrcweir                     .appendChild( new TextNode("2") ) )
2708cdf0e10cSrcweir                 .appendChild( met3.dup()
2709cdf0e10cSrcweir                     .appendChild( rby1.dup()
2710cdf0e10cSrcweir                         .appendChild( new TextNode("3") ) )
2711cdf0e10cSrcweir                     .appendChild( met4.dup()
2712cdf0e10cSrcweir                         .appendChild( rby1.dup()
2713cdf0e10cSrcweir                             .appendChild( new TextNode("4") ) )
2714cdf0e10cSrcweir                         .appendChild( rby5.dup()
2715cdf0e10cSrcweir                             .appendChild( new TextNode("5") ) )
2716cdf0e10cSrcweir                         .appendChild( rby1.dup()
2717cdf0e10cSrcweir                             .appendChild( new TextNode("6") ) ) )
2718cdf0e10cSrcweir                     .appendChild( rby1.dup()
2719cdf0e10cSrcweir                         .appendChild( new TextNode("7") ) ) )
2720cdf0e10cSrcweir                 .appendChild( rby1.dup()
2721cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) ) )
2722cdf0e10cSrcweir             .appendChild( rby1.dup()
2723cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2724cdf0e10cSrcweir         doTest(root, false);
2725cdf0e10cSrcweir     }
2726cdf0e10cSrcweir 
testRange5()2727cdf0e10cSrcweir     @Test public void testRange5() throws Exception
2728cdf0e10cSrcweir     {
2729cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2730cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2731cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2732cdf0e10cSrcweir         TreeNode rby1 = new RubyNode( mkName("ruby") );
2733cdf0e10cSrcweir         inserter.insertRange( new Range(0, 9, rby1) );
2734cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2735cdf0e10cSrcweir         inserter.insertRange( new Range(1, 3, met2) );
2736cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2737cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-1*/, 6/*-1*/, met3) );
2738cdf0e10cSrcweir         TreeNode met4 = new MetaNode( mkId("id") );
2739cdf0e10cSrcweir         inserter.insertRange( new Range(8/*-2*/, 10/*-2*/, met4) );
2740cdf0e10cSrcweir         TreeNode root = new TreeNode()
2741cdf0e10cSrcweir             .appendChild( rby1.dup()
2742cdf0e10cSrcweir                 .appendChild( new TextNode("1") )
2743cdf0e10cSrcweir                 .appendChild( met2.dup().appendChild( new TextNode("23") ) )
2744cdf0e10cSrcweir                 .appendChild( new TextNode("4") )
2745cdf0e10cSrcweir                 .appendChild( met3.dup().appendChild( new TextNode("5") ) )
2746cdf0e10cSrcweir                 .appendChild( new TextNode("6") )
2747cdf0e10cSrcweir                 .appendChild( met4.dup().appendChild( new TextNode("78") ) )
2748cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2749cdf0e10cSrcweir         doTest(root, false);
2750cdf0e10cSrcweir         // overwrite outer ruby, but split at inner metas!
2751cdf0e10cSrcweir         TreeNode rby5 = new RubyNode( mkName("ruby") );
2752cdf0e10cSrcweir         inserter.insertRange( new Range(3/*-1*/, 10/*-3*/, rby5) );
2753cdf0e10cSrcweir         root = new TreeNode()
2754cdf0e10cSrcweir             .appendChild( rby1.dup()
2755cdf0e10cSrcweir                 .appendChild( new TextNode("1") ) )
2756cdf0e10cSrcweir             .appendChild( met2.dup()
2757cdf0e10cSrcweir                 .appendChild( rby1.dup()
2758cdf0e10cSrcweir                     .appendChild( new TextNode("2") ) )
2759cdf0e10cSrcweir                 .appendChild( rby5.dup()
2760cdf0e10cSrcweir                     .appendChild( new TextNode("3") ) ) )
2761cdf0e10cSrcweir             .appendChild( rby5.dup()
2762cdf0e10cSrcweir                 .appendChild( new TextNode("4") )
2763cdf0e10cSrcweir                 .appendChild( met3.dup()
2764cdf0e10cSrcweir                     .appendChild( new TextNode("5") ) )
2765cdf0e10cSrcweir                 .appendChild( new TextNode("6") ) )
2766cdf0e10cSrcweir             .appendChild( met4.dup()
2767cdf0e10cSrcweir                 .appendChild( rby5.dup()
2768cdf0e10cSrcweir                     .appendChild( new TextNode("7") ) )
2769cdf0e10cSrcweir                 .appendChild( rby1.dup()
2770cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) ) )
2771cdf0e10cSrcweir             .appendChild( rby1.dup()
2772cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2773cdf0e10cSrcweir         doTest(root, false);
2774cdf0e10cSrcweir     }
2775cdf0e10cSrcweir 
testRange6()2776cdf0e10cSrcweir     @Test public void testRange6() throws Exception
2777cdf0e10cSrcweir     {
2778cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2779cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2780cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2781cdf0e10cSrcweir         TreeNode met1 = new MetaNode( mkId("id") );
2782cdf0e10cSrcweir         inserter.insertRange( new Range(1, 5, met1) );
2783cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2784cdf0e10cSrcweir         inserter.insertRange( new Range(3/*-1*/, 6/*-1*/, met2) );
2785cdf0e10cSrcweir         TreeNode met3 = new MetaNode( mkId("id") );
2786cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-2*/, 7/*-2*/, met3) );
2787cdf0e10cSrcweir         TreeNode root = new TreeNode()
2788cdf0e10cSrcweir             .appendChild( new TextNode("1") )
2789cdf0e10cSrcweir             .appendChild( met1.dup()
2790cdf0e10cSrcweir                 .appendChild( new TextNode("2") )
2791cdf0e10cSrcweir                 .appendChild( met2.dup()
2792cdf0e10cSrcweir                     .appendChild( new TextNode("3") )
2793cdf0e10cSrcweir                     .appendChild( met3.dup()
2794cdf0e10cSrcweir                         .appendChild( new TextNode("45") ) ) ) )
2795cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2796cdf0e10cSrcweir         doTest(root, false);
2797cdf0e10cSrcweir         // split at 3 metas, all at same position
2798cdf0e10cSrcweir         TreeNode rby4 = new RubyNode( mkName("ruby") );
2799cdf0e10cSrcweir         inserter.insertRange( new Range(7/*-3*/, 10/*-3*/, rby4) );
2800cdf0e10cSrcweir         root = new TreeNode()
2801cdf0e10cSrcweir             .appendChild( new TextNode("1") )
2802cdf0e10cSrcweir             .appendChild( met1.dup()
2803cdf0e10cSrcweir                 .appendChild( new TextNode("2") )
2804cdf0e10cSrcweir                 .appendChild( met2.dup()
2805cdf0e10cSrcweir                     .appendChild( new TextNode("3") )
2806cdf0e10cSrcweir                     .appendChild( met3.dup()
2807cdf0e10cSrcweir                         .appendChild( new TextNode("4") )
2808cdf0e10cSrcweir                         .appendChild( rby4.dup()
2809cdf0e10cSrcweir                             .appendChild( new TextNode("5") ) ) ) ) )
2810cdf0e10cSrcweir             .appendChild( rby4.dup()
2811cdf0e10cSrcweir                 .appendChild( new TextNode("67") ) )
2812cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2813cdf0e10cSrcweir         doTest(root, false);
2814cdf0e10cSrcweir     }
2815cdf0e10cSrcweir 
testRange7()2816cdf0e10cSrcweir     @Test public void testRange7() throws Exception
2817cdf0e10cSrcweir     {
2818cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2819cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2820cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2821cdf0e10cSrcweir         TreeNode url1 = new HyperlinkNode( mkName("url") );
2822cdf0e10cSrcweir         inserter.insertRange( new Range(1, 5, url1) );
2823cdf0e10cSrcweir         TreeNode met2 = new MetaNode( mkId("id") );
2824cdf0e10cSrcweir         inserter.insertRange( new Range(3, 5, met2) );
2825cdf0e10cSrcweir         TreeNode root = new TreeNode()
2826cdf0e10cSrcweir             .appendChild( new TextNode("1") )
2827cdf0e10cSrcweir             .appendChild( url1.dup()
2828cdf0e10cSrcweir                 .appendChild( new TextNode("23") ) )
2829cdf0e10cSrcweir             .appendChild( met2.dup()
2830cdf0e10cSrcweir                 .appendChild( url1.dup()
2831cdf0e10cSrcweir                     .appendChild( new TextNode("45") ) ) )
2832cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
2833cdf0e10cSrcweir         doTest(root, false);
2834cdf0e10cSrcweir         // this should result in not splitting the hyperlink, but due to API
2835cdf0e10cSrcweir         // we can't tell :(
2836cdf0e10cSrcweir         TreeNode rby3 = new RubyNode( mkName("ruby") );
2837cdf0e10cSrcweir         inserter.insertRange( new Range(5/*-1*/, 8/*-1*/, rby3) );
2838cdf0e10cSrcweir         root = new TreeNode()
2839cdf0e10cSrcweir             .appendChild( new TextNode("1") )
2840cdf0e10cSrcweir             .appendChild( url1.dup()
2841cdf0e10cSrcweir                 .appendChild( new TextNode("23") ) )
2842cdf0e10cSrcweir             .appendChild( met2.dup()
2843cdf0e10cSrcweir                 .appendChild( url1.dup()
2844cdf0e10cSrcweir                     .appendChild( new TextNode("4") ) )
2845cdf0e10cSrcweir                 .appendChild( rby3.dup()
2846cdf0e10cSrcweir                     .appendChild( url1.dup()
2847cdf0e10cSrcweir                         .appendChild( new TextNode("5") ) ) ) )
2848cdf0e10cSrcweir             .appendChild( rby3.dup()
2849cdf0e10cSrcweir                 .appendChild( new TextNode("67") ) )
2850cdf0e10cSrcweir             .appendChild( new TextNode("89") );
2851cdf0e10cSrcweir         doTest(root, false);
2852cdf0e10cSrcweir     }
2853cdf0e10cSrcweir 
2854cdf0e10cSrcweir     /* TODO: test partial selection, test UNDO/REDO */
2855cdf0e10cSrcweir 
2856cdf0e10cSrcweir     // #i109601# NestedTextContent and XChild
testMetaXChild()2857cdf0e10cSrcweir     @Test public void testMetaXChild() throws Exception
2858cdf0e10cSrcweir     {
2859cdf0e10cSrcweir         StringPair id1 = new StringPair("content.xml", mkName("id"));
2860cdf0e10cSrcweir         StringPair id2 = new StringPair("content.xml", mkName("id"));
2861cdf0e10cSrcweir         StringPair id3 = new StringPair("content.xml", mkName("id"));
2862cdf0e10cSrcweir         StringPair id4 = new StringPair("content.xml", mkName("id"));
2863cdf0e10cSrcweir         StringPair id5 = new StringPair("content.xml", mkName("id"));
2864cdf0e10cSrcweir         StringPair id6 = new StringPair("content.xml", mkName("id"));
2865cdf0e10cSrcweir         TreeNode meta1 = new MetaNode(id1);
2866cdf0e10cSrcweir         TreeNode meta2 = new MetaNode(id2);
2867cdf0e10cSrcweir         TreeNode meta3 = new MetaFieldNode(id3);
2868cdf0e10cSrcweir         TreeNode meta4 = new MetaNode(id4);
2869cdf0e10cSrcweir         TreeNode meta5 = new MetaNode(id5);
2870cdf0e10cSrcweir         TreeNode meta6 = new MetaFieldNode(id6);
2871cdf0e10cSrcweir         TreeNode root = new TreeNode()
2872cdf0e10cSrcweir             .appendChild( meta1.dup()
2873cdf0e10cSrcweir                 .appendChild( new TextNode("1") ) )
2874cdf0e10cSrcweir             .appendChild( new TextNode("2") )
2875cdf0e10cSrcweir             .appendChild( meta2.dup()
2876cdf0e10cSrcweir                 .appendChild( meta3.dup()
2877cdf0e10cSrcweir                     .appendChild( new TextNode("34") )
2878cdf0e10cSrcweir                     .appendChild( meta4.dup()
2879cdf0e10cSrcweir                         .appendChild( new TextNode("56") ) )
2880cdf0e10cSrcweir                     .appendChild( meta5.dup() )
2881cdf0e10cSrcweir                     .appendChild( new TextNode("7") ) ) )
2882cdf0e10cSrcweir             .appendChild( new TextNode("8") )
2883cdf0e10cSrcweir             .appendChild( meta6.dup()
2884cdf0e10cSrcweir                 .appendChild( new TextNode("9") ) );
2885cdf0e10cSrcweir 
2886cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2887cdf0e10cSrcweir         TreeNode text = new TextNode("123456789");
2888cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2889cdf0e10cSrcweir         XTextContent xMeta1 = inserter.insertRange( new Range(0, 1, meta1) );
2890cdf0e10cSrcweir         XTextContent xMeta2 = inserter.insertRange( new Range(3, 8, meta2) );
2891cdf0e10cSrcweir         XTextContent xMeta3 = inserter.insertRange( new Range(4, 9, meta3) );
2892cdf0e10cSrcweir         XTextContent xMeta4 = inserter.insertRange( new Range(7, 9, meta4) );
2893cdf0e10cSrcweir         XTextContent xMeta5 = inserter.insertRange( new Range(10, 10, meta5) );
2894cdf0e10cSrcweir         XTextContent xMeta6 = inserter.insertRange( new Range(13, 14, meta6) );
2895cdf0e10cSrcweir 
2896cdf0e10cSrcweir         doTest(root, false);
2897cdf0e10cSrcweir 
2898cdf0e10cSrcweir         XText xDocText = m_xDoc.getText();
2899cdf0e10cSrcweir         XTextCursor xDocTextCursor = xDocText.createTextCursor();
2900cdf0e10cSrcweir         XParagraphCursor xParagraphCursor = (XParagraphCursor)
2901cdf0e10cSrcweir             UnoRuntime.queryInterface(XParagraphCursor.class, xDocTextCursor);
2902cdf0e10cSrcweir         xParagraphCursor.gotoNextParagraph(false); // second paragraph
2903cdf0e10cSrcweir         // X12XX34X56X78X9
2904cdf0e10cSrcweir         // 1  23  4  5  6
2905cdf0e10cSrcweir         //  1       452  6
2906cdf0e10cSrcweir         //            3
2907cdf0e10cSrcweir         StringPair [] nestedTextContent = new StringPair[] {
2908cdf0e10cSrcweir             null,
2909cdf0e10cSrcweir             id1,
2910cdf0e10cSrcweir             id1,
2911cdf0e10cSrcweir             null,
2912cdf0e10cSrcweir             id2,
2913cdf0e10cSrcweir             id3,
2914cdf0e10cSrcweir             id3,
2915cdf0e10cSrcweir             id3,
2916cdf0e10cSrcweir             id4,
2917cdf0e10cSrcweir             id4,
2918cdf0e10cSrcweir             id4,
2919cdf0e10cSrcweir             id5,
2920cdf0e10cSrcweir             id3,
2921cdf0e10cSrcweir             null,
2922cdf0e10cSrcweir             id6,
2923cdf0e10cSrcweir             id6,
2924cdf0e10cSrcweir         };
2925cdf0e10cSrcweir         XPropertySet xPropertySet = (XPropertySet)
2926cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xDocTextCursor);
2927cdf0e10cSrcweir         for (int i = 0; i < nestedTextContent.length; ++i) {
2928cdf0e10cSrcweir             Object oNTC = xPropertySet.getPropertyValue("NestedTextContent");
2929cdf0e10cSrcweir             XTextContent xNTC = (XTextContent)
2930cdf0e10cSrcweir                 UnoRuntime.queryInterface(XTextContent.class, oNTC);
2931cdf0e10cSrcweir             if (null == nestedTextContent[i]) {
2932cdf0e10cSrcweir                 assertNull("unexpected NestedTextContent at: " + i, xNTC);
2933cdf0e10cSrcweir             } else {
2934cdf0e10cSrcweir                 XMetadatable xMetadatable = (XMetadatable)
2935cdf0e10cSrcweir                     UnoRuntime.queryInterface(XMetadatable.class, xNTC);
2936cdf0e10cSrcweir                 StringPair xmlid = xMetadatable.getMetadataReference();
2937cdf0e10cSrcweir                 assertTrue("wrong NestedTextContent at: " + i,
2938cdf0e10cSrcweir                     MetaNode.eq(nestedTextContent[i], xmlid));
2939cdf0e10cSrcweir             }
2940cdf0e10cSrcweir             xDocTextCursor.goRight((short)1, false);
2941cdf0e10cSrcweir         }
2942cdf0e10cSrcweir 
2943cdf0e10cSrcweir         XChild xChild1 = (XChild)
2944cdf0e10cSrcweir             UnoRuntime.queryInterface(XChild.class, xMeta1);
2945cdf0e10cSrcweir         XChild xChild2 = (XChild)
2946cdf0e10cSrcweir             UnoRuntime.queryInterface(XChild.class, xMeta2);
2947cdf0e10cSrcweir         XChild xChild3 = (XChild)
2948cdf0e10cSrcweir             UnoRuntime.queryInterface(XChild.class, xMeta3);
2949cdf0e10cSrcweir         XChild xChild4 = (XChild)
2950cdf0e10cSrcweir             UnoRuntime.queryInterface(XChild.class, xMeta4);
2951cdf0e10cSrcweir         XChild xChild5 = (XChild)
2952cdf0e10cSrcweir             UnoRuntime.queryInterface(XChild.class, xMeta5);
2953cdf0e10cSrcweir         XChild xChild6 = (XChild)
2954cdf0e10cSrcweir             UnoRuntime.queryInterface(XChild.class, xMeta6);
2955cdf0e10cSrcweir         try {
2956cdf0e10cSrcweir             xChild1.setParent(xChild4);
2957cdf0e10cSrcweir             fail("setParent(): allowed?");
2958cdf0e10cSrcweir         } catch (NoSupportException e) { /* expected */ }
2959cdf0e10cSrcweir         assertNull("getParent(): not null", xChild1.getParent());
2960cdf0e10cSrcweir         assertNull("getParent(): not null", xChild2.getParent());
2961cdf0e10cSrcweir         assertNull("getParent(): not null", xChild6.getParent());
2962cdf0e10cSrcweir         {
2963cdf0e10cSrcweir             Object xParent3 = xChild3.getParent();
2964cdf0e10cSrcweir             assertNotNull("getParent(): null", xParent3);
2965cdf0e10cSrcweir             XMetadatable xMetadatable = (XMetadatable)
2966cdf0e10cSrcweir                 UnoRuntime.queryInterface(XMetadatable.class, xParent3);
2967cdf0e10cSrcweir             StringPair xmlid = xMetadatable.getMetadataReference();
2968cdf0e10cSrcweir             assertTrue("getParent(): wrong", MetaNode.eq(xmlid, id2));
2969cdf0e10cSrcweir         }{
2970cdf0e10cSrcweir             Object xParent4 = xChild4.getParent();
2971cdf0e10cSrcweir             assertNotNull("getParent(): null", xParent4);
2972cdf0e10cSrcweir             XMetadatable xMetadatable = (XMetadatable)
2973cdf0e10cSrcweir                 UnoRuntime.queryInterface(XMetadatable.class, xParent4);
2974cdf0e10cSrcweir             StringPair xmlid = xMetadatable.getMetadataReference();
2975cdf0e10cSrcweir             assertTrue("getParent(): wrong", MetaNode.eq(xmlid, id3));
2976cdf0e10cSrcweir         }{
2977cdf0e10cSrcweir             Object xParent5 = xChild5.getParent();
2978cdf0e10cSrcweir             assertNotNull("getParent(): null", xParent5);
2979cdf0e10cSrcweir             XMetadatable xMetadatable = (XMetadatable)
2980cdf0e10cSrcweir                 UnoRuntime.queryInterface(XMetadatable.class, xParent5);
2981cdf0e10cSrcweir             StringPair xmlid = xMetadatable.getMetadataReference();
2982cdf0e10cSrcweir             assertTrue("getParent(): wrong", MetaNode.eq(xmlid, id3));
2983cdf0e10cSrcweir         }
2984cdf0e10cSrcweir     }
2985cdf0e10cSrcweir 
2986cdf0e10cSrcweir     /** test SwXMeta XText interface */
testMetaXText()2987cdf0e10cSrcweir     @Test public void testMetaXText() throws Exception
2988cdf0e10cSrcweir     {
2989cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
2990cdf0e10cSrcweir         TreeNode text = new TextNode("12AB6789");
2991cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
2992cdf0e10cSrcweir         MetaNode meta = new MetaNode( mkId("id") );
2993cdf0e10cSrcweir //        inserter.insertRange( new Range(3, 5, met2) );
2994cdf0e10cSrcweir         XTextContent xMeta = inserter.makeMeta();
2995cdf0e10cSrcweir 
2996cdf0e10cSrcweir         XText xDocText = m_xDoc.getText();
2997cdf0e10cSrcweir         XTextCursor xDocTextCursor = xDocText.createTextCursor();
2998cdf0e10cSrcweir         xDocTextCursor.goRight((short)3, false);
2999cdf0e10cSrcweir         xDocTextCursor.goRight((short)2, true);
3000cdf0e10cSrcweir         xDocText.insertTextContent(xDocTextCursor, xMeta, true);
3001cdf0e10cSrcweir //        xMeta.attach(xDocTextCursor);
3002cdf0e10cSrcweir 
3003cdf0e10cSrcweir         XMetadatable xMetadatable = (XMetadatable)
3004cdf0e10cSrcweir             UnoRuntime.queryInterface(XMetadatable.class, xMeta);
3005cdf0e10cSrcweir         xMetadatable.setMetadataReference(meta.getXmlId());
3006cdf0e10cSrcweir         XText xText = (XText) UnoRuntime.queryInterface(XText.class, xMeta);
3007cdf0e10cSrcweir 
3008cdf0e10cSrcweir         XText xParentText = xText.getText();
3009cdf0e10cSrcweir         assertNotNull("getText(): no parent", xParentText);
3010cdf0e10cSrcweir 
3011cdf0e10cSrcweir         XTextRange xStart = xText.getStart();
3012cdf0e10cSrcweir         assertNotNull("getStart(): no start", xStart);
3013cdf0e10cSrcweir 
3014cdf0e10cSrcweir         XTextRange xEnd = xText.getEnd();
3015cdf0e10cSrcweir         assertNotNull("getEnd(): no end", xEnd);
3016cdf0e10cSrcweir 
3017cdf0e10cSrcweir         xText.setString("45");
3018cdf0e10cSrcweir 
3019cdf0e10cSrcweir         {
3020cdf0e10cSrcweir             String string = xText.getString();
3021cdf0e10cSrcweir             assertEquals("getString(): invalid string returned",
3022cdf0e10cSrcweir                          "45", string);
3023cdf0e10cSrcweir         }
3024cdf0e10cSrcweir 
3025cdf0e10cSrcweir         XTextCursor xTextCursor = xText.createTextCursor();
3026cdf0e10cSrcweir         assertNotNull("createTextCursor(): failed", xTextCursor);
3027cdf0e10cSrcweir 
3028cdf0e10cSrcweir         try {
3029cdf0e10cSrcweir             xText.createTextCursorByRange(null);
3030cdf0e10cSrcweir             fail("createTextCursorByRange(): null allowed?");
3031cdf0e10cSrcweir         } catch (RuntimeException e) { /* expected */ }
3032cdf0e10cSrcweir 
3033cdf0e10cSrcweir         XTextCursor xTextCursorStart = xText.createTextCursorByRange(xStart);
3034cdf0e10cSrcweir         assertNotNull("createTextCursorByRange(): failed for start",
3035cdf0e10cSrcweir                       xTextCursorStart);
3036cdf0e10cSrcweir 
3037cdf0e10cSrcweir         XTextCursor xTextCursorEnd = xText.createTextCursorByRange(xEnd);
3038cdf0e10cSrcweir         assertNotNull("createTextCursorByRange(): failed for end",
3039cdf0e10cSrcweir                       xTextCursorEnd);
3040cdf0e10cSrcweir 
3041cdf0e10cSrcweir         // move outside meta
3042cdf0e10cSrcweir         xDocTextCursor.gotoStart(false);
3043cdf0e10cSrcweir 
3044cdf0e10cSrcweir         try {
3045cdf0e10cSrcweir             xText.insertString(null, "foo", false);
3046cdf0e10cSrcweir             fail("insertString(): null allowed?");
3047cdf0e10cSrcweir         } catch (RuntimeException e) { /* expected */ }
3048cdf0e10cSrcweir 
3049cdf0e10cSrcweir         try {
3050cdf0e10cSrcweir             xText.insertString(xDocTextCursor, "foo", false);
3051cdf0e10cSrcweir             fail("insertString(): cursor outside allowed?");
3052cdf0e10cSrcweir         } catch (RuntimeException e) { /* expected */ }
3053cdf0e10cSrcweir 
3054cdf0e10cSrcweir         xStart = xText.getStart();
3055cdf0e10cSrcweir         xText.insertString(xStart, "A", false);
3056cdf0e10cSrcweir         {
3057cdf0e10cSrcweir             String string = xText.getString();
3058cdf0e10cSrcweir             assertEquals("getString(): invalid string returned",
3059cdf0e10cSrcweir                          "A45", string);
3060cdf0e10cSrcweir         }
3061cdf0e10cSrcweir 
3062cdf0e10cSrcweir         xText.insertString(xEnd, "B", false);
3063cdf0e10cSrcweir         {
3064cdf0e10cSrcweir             String string = xText.getString();
3065cdf0e10cSrcweir             assertEquals("getString(): invalid string returned",
3066cdf0e10cSrcweir                          "A45B", string);
3067cdf0e10cSrcweir         }
3068cdf0e10cSrcweir 
3069cdf0e10cSrcweir         try {
3070cdf0e10cSrcweir             xText.insertControlCharacter(null, HARD_HYPHEN, false);
3071cdf0e10cSrcweir             fail("insertControlCharacter(): null allowed?");
3072cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
3073cdf0e10cSrcweir 
3074cdf0e10cSrcweir         xStart = xText.getStart();
3075cdf0e10cSrcweir         try {
3076cdf0e10cSrcweir             xText.insertControlCharacter(xDocTextCursor, HARD_HYPHEN, false);
3077cdf0e10cSrcweir             fail("insertControlCharacter(): cursor outside allowed?");
3078cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
3079cdf0e10cSrcweir 
3080cdf0e10cSrcweir         xText.insertControlCharacter(xStart, HARD_HYPHEN, false);
3081cdf0e10cSrcweir         {
3082cdf0e10cSrcweir             String string = xText.getString();
3083cdf0e10cSrcweir             assertEquals("getString(): invalid string returned",
3084cdf0e10cSrcweir                          '\u2011' + "A45B", string);
3085cdf0e10cSrcweir         }
3086cdf0e10cSrcweir 
3087cdf0e10cSrcweir         xText.insertControlCharacter(xEnd, HARD_HYPHEN, false);
3088cdf0e10cSrcweir         {
3089cdf0e10cSrcweir             String string = xText.getString();
3090cdf0e10cSrcweir             assertEquals("getString(): invalid string returned",
3091cdf0e10cSrcweir                          '\u2011' + "A45B" + '\u2011', string);
3092cdf0e10cSrcweir         }
3093cdf0e10cSrcweir 
3094cdf0e10cSrcweir         xText.setString("45");
3095cdf0e10cSrcweir 
3096cdf0e10cSrcweir         try {
3097cdf0e10cSrcweir             xText.insertTextContent(null, xMeta, false);
3098cdf0e10cSrcweir             fail("insertTextContent(): null range allowed?");
3099cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
3100cdf0e10cSrcweir 
3101cdf0e10cSrcweir         try {
3102cdf0e10cSrcweir             xText.insertTextContent(xStart, null, false);
3103cdf0e10cSrcweir             fail("insertTextContent(): null content allowed?");
3104cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
3105cdf0e10cSrcweir 
3106cdf0e10cSrcweir         try {
3107cdf0e10cSrcweir             xText.insertTextContent(xDocTextCursor, xMeta, false);
3108cdf0e10cSrcweir             fail("insertTextContent(): cursor outside allowed?");
3109cdf0e10cSrcweir         } catch (com.sun.star.lang.IllegalArgumentException e) { /* ignore */ }
3110cdf0e10cSrcweir 
3111cdf0e10cSrcweir         TextFieldNode field1 = new TextFieldNode( "f1" );
3112cdf0e10cSrcweir         TextFieldNode field2 = new TextFieldNode( "f2" );
3113cdf0e10cSrcweir         XTextContent xField1 = inserter.makeTextField(field1.getContent());
3114cdf0e10cSrcweir         XTextContent xField2 = inserter.makeTextField(field2.getContent());
3115cdf0e10cSrcweir 
3116cdf0e10cSrcweir         xStart = xText.getStart();
3117cdf0e10cSrcweir         xText.insertTextContent(xStart, xField1, false);
3118cdf0e10cSrcweir 
3119cdf0e10cSrcweir         TreeNode root = new TreeNode()
3120cdf0e10cSrcweir             .appendChild( new TextNode("12") )
3121cdf0e10cSrcweir             .appendChild( meta.dup()
3122cdf0e10cSrcweir                 .appendChild( field1.dup() )
3123cdf0e10cSrcweir                 .appendChild( new TextNode("45") ) )
3124cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
3125cdf0e10cSrcweir         doTest(root, false);
3126cdf0e10cSrcweir 
3127cdf0e10cSrcweir         xText.insertTextContent(xEnd, xField2, false);
3128cdf0e10cSrcweir 
3129cdf0e10cSrcweir         root = new TreeNode()
3130cdf0e10cSrcweir             .appendChild( new TextNode("12") )
3131cdf0e10cSrcweir             .appendChild( meta.dup()
3132cdf0e10cSrcweir                 .appendChild( field1.dup() )
3133cdf0e10cSrcweir                 .appendChild( new TextNode("45") )
3134cdf0e10cSrcweir                 .appendChild( field2.dup() ) )
3135cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
3136cdf0e10cSrcweir         doTest(root, false);
3137cdf0e10cSrcweir 
3138cdf0e10cSrcweir         try {
3139cdf0e10cSrcweir             xText.removeTextContent(null);
3140cdf0e10cSrcweir             fail("removeTextContent(): null content allowed?");
3141cdf0e10cSrcweir         } catch (RuntimeException e) { /* expected */ }
3142cdf0e10cSrcweir 
3143cdf0e10cSrcweir         xText.removeTextContent(xField1);
3144cdf0e10cSrcweir 
3145cdf0e10cSrcweir         XTextRange xAnchor = xMeta.getAnchor();
3146cdf0e10cSrcweir         assertNotNull("getAnchor(): null", xAnchor);
3147cdf0e10cSrcweir 
3148cdf0e10cSrcweir         // evil test case: insert ruby around meta
3149cdf0e10cSrcweir         RubyNode ruby = new RubyNode( mkName("ruby") );
3150cdf0e10cSrcweir         inserter.insertRange( new Range(2, 6, ruby) );
3151cdf0e10cSrcweir 
3152cdf0e10cSrcweir         /* prevent caching...
3153cdf0e10cSrcweir         root = new TreeNode()
3154cdf0e10cSrcweir             .appendChild( new TextNode("12") )
3155cdf0e10cSrcweir             .appendChild( ruby.dup()
3156cdf0e10cSrcweir                 .appendChild( meta.dup()
3157cdf0e10cSrcweir                     .appendChild( new TextNode("45") )
3158cdf0e10cSrcweir                     .appendChild( field2.dup() ) ) )
3159cdf0e10cSrcweir             .appendChild( new TextNode("6789") );
3160cdf0e10cSrcweir         doTest(root, false);
3161cdf0e10cSrcweir         */
3162cdf0e10cSrcweir 
3163cdf0e10cSrcweir         XEnumerationAccess xEA = (XEnumerationAccess)
3164cdf0e10cSrcweir             UnoRuntime.queryInterface(XEnumerationAccess.class, xMeta);
3165cdf0e10cSrcweir         XEnumeration xEnum = xEA.createEnumeration();
3166cdf0e10cSrcweir         assertNotNull("createEnumeration(): returns null", xEnum);
3167cdf0e10cSrcweir         {
3168cdf0e10cSrcweir             assertTrue("hasNext(): first missing", xEnum.hasMoreElements());
3169cdf0e10cSrcweir             Object xElement = xEnum.nextElement();
3170cdf0e10cSrcweir             XTextRange xPortion = (XTextRange)
3171cdf0e10cSrcweir                 UnoRuntime.queryInterface(XTextRange.class, xElement);
3172cdf0e10cSrcweir             XPropertySet xPropSet = (XPropertySet)
3173cdf0e10cSrcweir                 UnoRuntime.queryInterface(XPropertySet.class, xPortion);
3174cdf0e10cSrcweir             String type = (String) xPropSet.getPropertyValue("TextPortionType");
3175cdf0e10cSrcweir             assertEquals("first: not text", "Text", type);
3176cdf0e10cSrcweir             String txt = xPortion.getString();
3177cdf0e10cSrcweir             assertEquals("first: text differs", "45", txt);
3178cdf0e10cSrcweir         }
3179cdf0e10cSrcweir         {
3180cdf0e10cSrcweir             assertTrue("hasNext(): second missing", xEnum.hasMoreElements());
3181cdf0e10cSrcweir             Object xElement = xEnum.nextElement();
3182cdf0e10cSrcweir             XTextRange xPortion = (XTextRange)
3183cdf0e10cSrcweir                 UnoRuntime.queryInterface(XTextRange.class, xElement);
3184cdf0e10cSrcweir             XPropertySet xPropSet = (XPropertySet)
3185cdf0e10cSrcweir                 UnoRuntime.queryInterface(XPropertySet.class, xPortion);
3186cdf0e10cSrcweir             String type = (String) xPropSet.getPropertyValue("TextPortionType");
3187cdf0e10cSrcweir             assertEquals("second: not text", "TextField", type);
3188cdf0e10cSrcweir         }
3189cdf0e10cSrcweir         // no ruby end here!!!
3190cdf0e10cSrcweir         assertFalse("hasNext(): more elements?", xEnum.hasMoreElements());
3191cdf0e10cSrcweir 
3192cdf0e10cSrcweir         XComponent xComponent = (XComponent)
3193cdf0e10cSrcweir             UnoRuntime.queryInterface(XComponent.class, xMeta);
3194cdf0e10cSrcweir         xComponent.dispose();
3195cdf0e10cSrcweir 
3196cdf0e10cSrcweir         try {
3197cdf0e10cSrcweir             XTextCursor xCursor = xText.createTextCursor();
3198cdf0e10cSrcweir             assertNull("createTextCursor(): succeeds on disposed object?",
3199cdf0e10cSrcweir                        xCursor);
3200cdf0e10cSrcweir         } catch (RuntimeException e) { /* expected */ }
3201cdf0e10cSrcweir     }
3202cdf0e10cSrcweir 
3203cdf0e10cSrcweir     /** check that cursor move methods move to positions in the meta,
3204cdf0e10cSrcweir         but do not move to positions outside the meta. */
testMetaXTextCursor()3205cdf0e10cSrcweir     @Test public void testMetaXTextCursor() throws Exception
3206cdf0e10cSrcweir     {
3207cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
3208cdf0e10cSrcweir         TreeNode text = new TextNode("Text. 12 More text here.");
3209cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
3210cdf0e10cSrcweir         MetaNode met1 = new MetaNode( mkId("id") );
3211cdf0e10cSrcweir         XTextContent xMeta = inserter.makeMeta();
3212cdf0e10cSrcweir 
3213cdf0e10cSrcweir         XText xDocText = m_xDoc.getText();
3214cdf0e10cSrcweir         XTextCursor xDocTextCursor = xDocText.createTextCursor();
3215cdf0e10cSrcweir         xDocTextCursor.goRight((short)7, false);
3216cdf0e10cSrcweir         xDocTextCursor.goRight((short)2, true);
3217cdf0e10cSrcweir         xDocText.insertTextContent(xDocTextCursor, xMeta, true);
3218cdf0e10cSrcweir         xDocTextCursor.gotoStart(true);
3219cdf0e10cSrcweir 
3220cdf0e10cSrcweir         XMetadatable xMetadatable = (XMetadatable)
3221cdf0e10cSrcweir             UnoRuntime.queryInterface(XMetadatable.class, xMeta);
3222cdf0e10cSrcweir         xMetadatable.setMetadataReference(met1.getXmlId());
3223cdf0e10cSrcweir         XText xText = (XText) UnoRuntime.queryInterface(XText.class, xMeta);
3224cdf0e10cSrcweir 
3225cdf0e10cSrcweir         XTextRange xStart = xText.getStart();
3226cdf0e10cSrcweir         assertNotNull("getStart(): no start", xStart);
3227cdf0e10cSrcweir         XTextRange xEnd = xText.getEnd();
3228cdf0e10cSrcweir         assertNotNull("getEnd(): no end", xEnd);
3229cdf0e10cSrcweir 
3230cdf0e10cSrcweir         XTextCursor xTextCursor = xText.createTextCursor();
3231cdf0e10cSrcweir         assertNotNull("createTextCursor(): no cursor", xTextCursor);
3232cdf0e10cSrcweir 
3233cdf0e10cSrcweir         // XTextCursor
3234cdf0e10cSrcweir         boolean bSuccess = false;
3235cdf0e10cSrcweir         xTextCursor.gotoStart(false);
3236cdf0e10cSrcweir         xTextCursor.gotoEnd(false);
3237cdf0e10cSrcweir         bSuccess = xTextCursor.goLeft((short)1, false);
3238cdf0e10cSrcweir         assertTrue("goLeft(): failed", bSuccess);
3239cdf0e10cSrcweir         bSuccess = xTextCursor.goLeft((short)1000, false);
3240cdf0e10cSrcweir         assertFalse("goLeft(): succeeded", bSuccess);
3241cdf0e10cSrcweir         bSuccess = xTextCursor.goRight((short)1, false);
3242cdf0e10cSrcweir         assertTrue("goRight(): failed", bSuccess);
3243cdf0e10cSrcweir         bSuccess = xTextCursor.goRight((short)1000, false);
3244cdf0e10cSrcweir         assertFalse("goRight(): succeeded", bSuccess);
3245cdf0e10cSrcweir         xTextCursor.gotoRange(xStart, false);
3246cdf0e10cSrcweir         xTextCursor.gotoRange(xEnd, false);
3247cdf0e10cSrcweir         try {
3248cdf0e10cSrcweir             xTextCursor.gotoRange(xDocTextCursor, false);
3249cdf0e10cSrcweir             fail("gotoRange(): succeeded");
3250cdf0e10cSrcweir         } catch (RuntimeException e) { /* expected */ }
3251cdf0e10cSrcweir 
3252cdf0e10cSrcweir         // XWordCursor
3253cdf0e10cSrcweir         xText.setString("Two words");
3254cdf0e10cSrcweir         xTextCursor.gotoStart(false);
3255cdf0e10cSrcweir         XWordCursor xWordCursor = (XWordCursor)
3256cdf0e10cSrcweir             UnoRuntime.queryInterface(XWordCursor.class, xTextCursor);
3257cdf0e10cSrcweir 
3258cdf0e10cSrcweir         bSuccess = xWordCursor.gotoNextWord(true);
3259cdf0e10cSrcweir         assertTrue("gotoNextWord(): failed", bSuccess);
3260cdf0e10cSrcweir         {
3261cdf0e10cSrcweir             String string = xTextCursor.getString();
3262cdf0e10cSrcweir             assertEquals("gotoNextWord(): wrong string",
3263cdf0e10cSrcweir                          "Two ", string);
3264cdf0e10cSrcweir         }
3265cdf0e10cSrcweir         bSuccess = xWordCursor.gotoNextWord(false);
3266cdf0e10cSrcweir         assertFalse("gotoNextWord(): succeeded", bSuccess);
3267cdf0e10cSrcweir         xTextCursor.collapseToEnd();
3268cdf0e10cSrcweir         bSuccess = xWordCursor.gotoPreviousWord(true);
3269cdf0e10cSrcweir         assertTrue("gotoPreviousWord(): failed", bSuccess);
3270cdf0e10cSrcweir         {
3271cdf0e10cSrcweir             String string = xTextCursor.getString();
3272cdf0e10cSrcweir             assertEquals("gotoPreviousWord(): wrong string",
3273cdf0e10cSrcweir                          "words", string);
3274cdf0e10cSrcweir         }
3275cdf0e10cSrcweir         bSuccess = xWordCursor.gotoPreviousWord(false);
3276cdf0e10cSrcweir         assertFalse("gotoPreviousWord(): succeeded", bSuccess);
3277cdf0e10cSrcweir         bSuccess = xWordCursor.gotoEndOfWord(true);
3278cdf0e10cSrcweir         assertTrue("gotoEndOfWord(): failed", bSuccess);
3279cdf0e10cSrcweir         {
3280cdf0e10cSrcweir             String string = xTextCursor.getString();
3281cdf0e10cSrcweir             assertEquals("gotoEndOfWord(): wrong string",
3282cdf0e10cSrcweir                          "Two", string);
3283cdf0e10cSrcweir         }
3284cdf0e10cSrcweir         xTextCursor.gotoEnd(false);
3285cdf0e10cSrcweir         bSuccess = xWordCursor.gotoStartOfWord(true);
3286cdf0e10cSrcweir         assertTrue("gotoStartOfWord(): failed", bSuccess);
3287cdf0e10cSrcweir         {
3288cdf0e10cSrcweir             String string = xTextCursor.getString();
3289cdf0e10cSrcweir             assertEquals("gotoStartOfWord(): wrong string",
3290cdf0e10cSrcweir                          "words", string);
3291cdf0e10cSrcweir         }
3292cdf0e10cSrcweir         xText.setString("");
3293cdf0e10cSrcweir         bSuccess = xWordCursor.gotoEndOfWord(false);
3294cdf0e10cSrcweir         assertFalse("gotoEndOfWord(): succeeded", bSuccess);
3295cdf0e10cSrcweir         bSuccess = xWordCursor.gotoStartOfWord(false);
3296cdf0e10cSrcweir         assertFalse("gotoStartOfWord(): succeeded", bSuccess);
3297cdf0e10cSrcweir 
3298cdf0e10cSrcweir         // XSentenceCursor
3299cdf0e10cSrcweir         xText.setString("This is a sentence. Another sentence.");
3300cdf0e10cSrcweir         xTextCursor.gotoStart(false);
3301cdf0e10cSrcweir         XSentenceCursor xSentenceCursor = (XSentenceCursor)
3302cdf0e10cSrcweir             UnoRuntime.queryInterface(XSentenceCursor.class, xTextCursor);
3303cdf0e10cSrcweir 
3304cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoNextSentence(true);
3305cdf0e10cSrcweir         assertTrue("gotoNextSentence(): failed", bSuccess);
3306cdf0e10cSrcweir         {
3307cdf0e10cSrcweir             String string = xTextCursor.getString();
3308cdf0e10cSrcweir             assertEquals("gotoNextSentence(): wrong string",
3309cdf0e10cSrcweir                          "This is a sentence. ", string);
3310cdf0e10cSrcweir         }
3311cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoNextSentence(false);
3312cdf0e10cSrcweir         assertFalse("gotoNextSentence(): succeeded", bSuccess);
3313cdf0e10cSrcweir         // FIXME:
3314cdf0e10cSrcweir         // the sentence cursor seems to work differently than the word cursor
3315cdf0e10cSrcweir         xText.setString("This is a sentence. Another sentence. Sentence 3.");
3316cdf0e10cSrcweir         xTextCursor.gotoEnd(false);
3317cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoPreviousSentence(true);
3318cdf0e10cSrcweir         assertTrue("gotoPreviousSentence(): failed", bSuccess);
3319cdf0e10cSrcweir         {
3320cdf0e10cSrcweir             String string = xTextCursor.getString();
3321cdf0e10cSrcweir             assertEquals("gotoPreviousSentence(): wrong string",
3322cdf0e10cSrcweir                          "Another sentence. Sentence 3.", string);
3323cdf0e10cSrcweir         }
3324cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoPreviousSentence(false);
3325cdf0e10cSrcweir         assertFalse("gotoPreviousSentence(): succeeded", bSuccess);
3326cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoEndOfSentence(true);
3327cdf0e10cSrcweir         assertTrue("gotoEndOfSentence(): failed", bSuccess);
3328cdf0e10cSrcweir         {
3329cdf0e10cSrcweir             String string = xTextCursor.getString();
3330cdf0e10cSrcweir             assertEquals("gotoEndOfSentence(): wrong string",
3331cdf0e10cSrcweir                          "This is a sentence.", string);
3332cdf0e10cSrcweir         }
3333cdf0e10cSrcweir         xTextCursor.gotoEnd(false);
3334cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoStartOfSentence(true);
3335cdf0e10cSrcweir         assertTrue("gotoStartOfSentence(): failed", bSuccess);
3336cdf0e10cSrcweir         {
3337cdf0e10cSrcweir             String string = xTextCursor.getString();
3338cdf0e10cSrcweir             assertEquals("gotoStartOfSentence(): wrong string",
3339cdf0e10cSrcweir                          "Sentence 3.", string);
3340cdf0e10cSrcweir         }
3341cdf0e10cSrcweir         xText.setString("");
3342cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoEndOfSentence(false);
3343cdf0e10cSrcweir         assertFalse("gotoEndOfSentence(): succeeded", bSuccess);
3344cdf0e10cSrcweir         bSuccess = xSentenceCursor.gotoStartOfSentence(false);
3345cdf0e10cSrcweir         assertFalse("gotoStartOfSentence(): succeeded", bSuccess);
3346cdf0e10cSrcweir 
3347cdf0e10cSrcweir         XParagraphCursor xParagraphCursor = (XParagraphCursor)
3348cdf0e10cSrcweir             UnoRuntime.queryInterface(XParagraphCursor.class, xTextCursor);
3349cdf0e10cSrcweir 
3350cdf0e10cSrcweir         // XParagraphCursor (does not make sense)
3351cdf0e10cSrcweir         bSuccess = xParagraphCursor.gotoNextParagraph(false);
3352cdf0e10cSrcweir         assertFalse("gotoNextParagraph(): succeeded", bSuccess);
3353cdf0e10cSrcweir         bSuccess = xParagraphCursor.gotoPreviousParagraph(false);
3354cdf0e10cSrcweir         assertFalse("gotoPreviousParagraph(): succeeded", bSuccess);
3355cdf0e10cSrcweir         bSuccess = xParagraphCursor.gotoStartOfParagraph(false);
3356cdf0e10cSrcweir         assertFalse("gotoStartOfParagraph(): succeeded", bSuccess);
3357cdf0e10cSrcweir         bSuccess = xParagraphCursor.gotoEndOfParagraph(false);
3358cdf0e10cSrcweir         assertFalse("gotoEndOfParagraph(): succeeded", bSuccess);
3359cdf0e10cSrcweir     }
3360cdf0e10cSrcweir 
3361cdf0e10cSrcweir 
3362cdf0e10cSrcweir     abstract class AttachHelper
3363cdf0e10cSrcweir     {
isAttribute()3364cdf0e10cSrcweir         abstract boolean isAttribute();
mkTreeNode()3365cdf0e10cSrcweir         abstract TreeNode mkTreeNode();
mkTextContent(Inserter inserter, TreeNode node)3366cdf0e10cSrcweir         abstract XTextContent mkTextContent(Inserter inserter, TreeNode node)
3367cdf0e10cSrcweir             throws Exception;
postInserted(TreeNode node, XTextContent xContent)3368cdf0e10cSrcweir         void postInserted(TreeNode node, XTextContent xContent)
3369cdf0e10cSrcweir             throws Exception { }
3370cdf0e10cSrcweir     }
3371cdf0e10cSrcweir 
testMetaXTextAttachToxMark()3372cdf0e10cSrcweir     @Test public void testMetaXTextAttachToxMark() throws Exception
3373cdf0e10cSrcweir     {
3374cdf0e10cSrcweir         doMetaXTextAttach( new AttachHelper()
3375cdf0e10cSrcweir             {
3376cdf0e10cSrcweir                 boolean isAttribute() { return true; }
3377cdf0e10cSrcweir                 TreeNode mkTreeNode() {
3378cdf0e10cSrcweir                     return new DocumentIndexMarkNode( mkName("toxmark") );
3379cdf0e10cSrcweir                 }
3380cdf0e10cSrcweir                 XTextContent mkTextContent(Inserter inserter, TreeNode node)
3381cdf0e10cSrcweir                         throws Exception {
3382cdf0e10cSrcweir                     return inserter.makeDocumentIndexMark(
3383cdf0e10cSrcweir                         ((DocumentIndexMarkNode)node).getName());
3384cdf0e10cSrcweir                 }
3385cdf0e10cSrcweir             });
3386cdf0e10cSrcweir     }
3387cdf0e10cSrcweir 
testMetaXTextAttachRefMark()3388cdf0e10cSrcweir     @Test public void testMetaXTextAttachRefMark() throws Exception
3389cdf0e10cSrcweir     {
3390cdf0e10cSrcweir         doMetaXTextAttach( new AttachHelper()
3391cdf0e10cSrcweir             {
3392cdf0e10cSrcweir                 boolean isAttribute() { return true; }
3393cdf0e10cSrcweir                 TreeNode mkTreeNode() {
3394cdf0e10cSrcweir                     return new ReferenceMarkNode( mkName("refmark") );
3395cdf0e10cSrcweir                 }
3396cdf0e10cSrcweir                 XTextContent mkTextContent(Inserter inserter, TreeNode node)
3397cdf0e10cSrcweir                         throws Exception {
3398cdf0e10cSrcweir                     return inserter.makeReferenceMark(
3399cdf0e10cSrcweir                         ((ReferenceMarkNode)node).getName());
3400cdf0e10cSrcweir                 }
3401cdf0e10cSrcweir             });
3402cdf0e10cSrcweir     }
3403cdf0e10cSrcweir 
testMetaXTextAttachTextField()3404cdf0e10cSrcweir     @Test public void testMetaXTextAttachTextField() throws Exception
3405cdf0e10cSrcweir     {
3406cdf0e10cSrcweir         doMetaXTextAttach( new AttachHelper()
3407cdf0e10cSrcweir             {
3408cdf0e10cSrcweir                 boolean isAttribute() { return false; }
3409cdf0e10cSrcweir                 TreeNode mkTreeNode() {
3410cdf0e10cSrcweir                     return new TextFieldNode( mkName("field") );
3411cdf0e10cSrcweir                 }
3412cdf0e10cSrcweir                 XTextContent mkTextContent(Inserter inserter, TreeNode node)
3413cdf0e10cSrcweir                         throws Exception {
3414cdf0e10cSrcweir                     return inserter.makeTextField(
3415cdf0e10cSrcweir                         ((TextFieldNode)node).getContent());
3416cdf0e10cSrcweir                 }
3417cdf0e10cSrcweir             });
3418cdf0e10cSrcweir     }
3419cdf0e10cSrcweir 
testMetaXTextAttachFootnote()3420cdf0e10cSrcweir     @Test public void testMetaXTextAttachFootnote() throws Exception
3421cdf0e10cSrcweir     {
3422cdf0e10cSrcweir         doMetaXTextAttach( new AttachHelper()
3423cdf0e10cSrcweir             {
3424cdf0e10cSrcweir                 boolean isAttribute() { return false; }
3425cdf0e10cSrcweir                 TreeNode mkTreeNode() {
3426cdf0e10cSrcweir                     return new FootnoteNode( mkName("ftn") );
3427cdf0e10cSrcweir                 }
3428cdf0e10cSrcweir                 XTextContent mkTextContent(Inserter inserter, TreeNode node)
3429cdf0e10cSrcweir                         throws Exception {
3430cdf0e10cSrcweir                     return inserter.makeFootnote(
3431cdf0e10cSrcweir                         ((FootnoteNode)node).getLabel());
3432cdf0e10cSrcweir                 }
3433cdf0e10cSrcweir             });
3434cdf0e10cSrcweir     }
3435cdf0e10cSrcweir 
testMetaXTextAttachMeta()3436cdf0e10cSrcweir     @Test public void testMetaXTextAttachMeta() throws Exception
3437cdf0e10cSrcweir     {
3438cdf0e10cSrcweir         doMetaXTextAttach( new AttachHelper()
3439cdf0e10cSrcweir             {
3440cdf0e10cSrcweir                 boolean isAttribute() { return true; }
3441cdf0e10cSrcweir                 TreeNode mkTreeNode() {
3442cdf0e10cSrcweir                     return new MetaNode( mkId("id") );
3443cdf0e10cSrcweir                 }
3444cdf0e10cSrcweir                 XTextContent mkTextContent(Inserter inserter, TreeNode node)
3445cdf0e10cSrcweir                         throws Exception {
3446cdf0e10cSrcweir                     return inserter.makeMeta();
3447cdf0e10cSrcweir                 }
3448cdf0e10cSrcweir                 void postInserted(TreeNode node, XTextContent xContent)
3449cdf0e10cSrcweir                         throws Exception {
3450cdf0e10cSrcweir                     XMetadatable xMetadatable = (XMetadatable)
3451cdf0e10cSrcweir                         UnoRuntime.queryInterface(XMetadatable.class, xContent);
3452cdf0e10cSrcweir                     xMetadatable.setMetadataReference(
3453cdf0e10cSrcweir                             ((MetaNode)node).getXmlId());
3454cdf0e10cSrcweir                 }
3455cdf0e10cSrcweir             });
3456cdf0e10cSrcweir     }
3457cdf0e10cSrcweir 
doMetaXTextAttach(AttachHelper helper)3458cdf0e10cSrcweir     void doMetaXTextAttach(AttachHelper helper) throws Exception
3459cdf0e10cSrcweir     {
3460cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
3461cdf0e10cSrcweir         TreeNode text = new TextNode("12AB6789");
3462cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
3463cdf0e10cSrcweir         MetaNode met1 = new MetaNode( mkId("id") );
3464cdf0e10cSrcweir         XTextContent xMeta = inserter.makeMeta();
3465cdf0e10cSrcweir 
3466cdf0e10cSrcweir         XText xDocText = m_xDoc.getText();
3467cdf0e10cSrcweir         XTextCursor xDocTextCursor = xDocText.createTextCursor();
3468cdf0e10cSrcweir         xDocTextCursor.goRight((short)3, false);
3469cdf0e10cSrcweir         xDocTextCursor.goRight((short)2, true);
3470cdf0e10cSrcweir         xDocText.insertTextContent(xDocTextCursor, xMeta, true);
3471cdf0e10cSrcweir 
3472cdf0e10cSrcweir         XMetadatable xMetadatable = (XMetadatable)
3473cdf0e10cSrcweir             UnoRuntime.queryInterface(XMetadatable.class, xMeta);
3474cdf0e10cSrcweir         xMetadatable.setMetadataReference(met1.getXmlId());
3475cdf0e10cSrcweir         XText xText = (XText) UnoRuntime.queryInterface(XText.class, xMeta);
3476cdf0e10cSrcweir         XTextRange xStart = null;
3477cdf0e10cSrcweir         XTextRange xEnd = null;
3478cdf0e10cSrcweir 
3479cdf0e10cSrcweir         {
3480cdf0e10cSrcweir             xStart = xText.getStart();
3481cdf0e10cSrcweir             xEnd = xText.getEnd();
3482cdf0e10cSrcweir 
3483cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3484cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3485cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3486cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3487cdf0e10cSrcweir 
3488cdf0e10cSrcweir             // insertTextContent with meta getStart()/getEnd()
3489cdf0e10cSrcweir             xText.insertTextContent(xStart, xContent1, false);
3490cdf0e10cSrcweir             xText.insertTextContent(xEnd  , xContent2, false);
3491cdf0e10cSrcweir 
3492cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3493cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3494cdf0e10cSrcweir 
3495cdf0e10cSrcweir             TreeNode root = new TreeNode()
3496cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3497cdf0e10cSrcweir                 .appendChild( met1.dup()
3498cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3499cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3500cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3501cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3502cdf0e10cSrcweir             doTest(root, false);
3503cdf0e10cSrcweir         }
3504cdf0e10cSrcweir         {
3505cdf0e10cSrcweir             xText.setString("AB");
3506cdf0e10cSrcweir             xStart = xText.getStart();
3507cdf0e10cSrcweir             xEnd = xText.getEnd();
3508cdf0e10cSrcweir 
3509cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3510cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3511cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3512cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3513cdf0e10cSrcweir 
3514cdf0e10cSrcweir             XTextCursor xTextCursor = xText.createTextCursor();
3515cdf0e10cSrcweir             xTextCursor.gotoStart(false);
3516cdf0e10cSrcweir 
3517cdf0e10cSrcweir             // insertTextContent with meta cursor
3518cdf0e10cSrcweir             xText.insertTextContent(xTextCursor, xContent1, false);
3519cdf0e10cSrcweir             xTextCursor.gotoEnd(false);
3520cdf0e10cSrcweir             xText.insertTextContent(xTextCursor, xContent2, false);
3521cdf0e10cSrcweir 
3522cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3523cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3524cdf0e10cSrcweir 
3525cdf0e10cSrcweir             TreeNode root = new TreeNode()
3526cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3527cdf0e10cSrcweir                 .appendChild( met1.dup()
3528cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3529cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3530cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3531cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3532cdf0e10cSrcweir             doTest(root, false);
3533cdf0e10cSrcweir         }
3534cdf0e10cSrcweir         if (!helper.isAttribute())
3535cdf0e10cSrcweir         {
3536cdf0e10cSrcweir //            xText.setString("AB");
3537cdf0e10cSrcweir             xStart = xText.getStart();
3538cdf0e10cSrcweir             xEnd = xText.getEnd();
3539cdf0e10cSrcweir 
3540cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3541cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3542cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3543cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3544cdf0e10cSrcweir 
3545cdf0e10cSrcweir             XTextCursor xTextCursor = xText.createTextCursor();
3546cdf0e10cSrcweir             xTextCursor.gotoStart(false);
3547cdf0e10cSrcweir             xTextCursor.goRight((short)1, true);
3548cdf0e10cSrcweir 
3549cdf0e10cSrcweir             // insertTextContent with meta cursor and absorb
3550cdf0e10cSrcweir             xText.insertTextContent(xTextCursor, xContent1, true);
3551cdf0e10cSrcweir             xTextCursor.gotoEnd(false);
3552cdf0e10cSrcweir             xTextCursor.goLeft((short)1, true);
3553cdf0e10cSrcweir             xText.insertTextContent(xTextCursor, xContent2, true);
3554cdf0e10cSrcweir 
3555cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3556cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3557cdf0e10cSrcweir 
3558cdf0e10cSrcweir             TreeNode root = new TreeNode()
3559cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3560cdf0e10cSrcweir                 .appendChild( met1.dup()
3561cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3562cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3563cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3564cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3565cdf0e10cSrcweir             doTest(root, false);
3566cdf0e10cSrcweir         }
3567cdf0e10cSrcweir         {
3568cdf0e10cSrcweir             xText.setString("AB");
3569cdf0e10cSrcweir             xStart = xText.getStart();
3570cdf0e10cSrcweir             xEnd = xText.getEnd();
3571cdf0e10cSrcweir 
3572cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3573cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3574cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3575cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3576cdf0e10cSrcweir 
3577cdf0e10cSrcweir             xDocTextCursor.gotoRange(xStart, false);
3578cdf0e10cSrcweir 
3579cdf0e10cSrcweir             // insertTextContent with document cursor
3580cdf0e10cSrcweir             xText.insertTextContent(xDocTextCursor, xContent1, false);
3581cdf0e10cSrcweir             xDocTextCursor.gotoRange(xEnd, false);
3582cdf0e10cSrcweir             xText.insertTextContent(xDocTextCursor, xContent2, false);
3583cdf0e10cSrcweir 
3584cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3585cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3586cdf0e10cSrcweir 
3587cdf0e10cSrcweir             TreeNode root = new TreeNode()
3588cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3589cdf0e10cSrcweir                 .appendChild( met1.dup()
3590cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3591cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3592cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3593cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3594cdf0e10cSrcweir             doTest(root, false);
3595cdf0e10cSrcweir         }
3596cdf0e10cSrcweir         if (!helper.isAttribute())
3597cdf0e10cSrcweir         {
3598cdf0e10cSrcweir //            xText.setString("AB");
3599cdf0e10cSrcweir             xStart = xText.getStart();
3600cdf0e10cSrcweir             xEnd = xText.getEnd();
3601cdf0e10cSrcweir 
3602cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3603cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3604cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3605cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3606cdf0e10cSrcweir 
3607cdf0e10cSrcweir             xDocTextCursor.gotoRange(xStart, false);
3608cdf0e10cSrcweir             xDocTextCursor.goRight((short)1, true);
3609cdf0e10cSrcweir 
3610cdf0e10cSrcweir             // insertTextContent with document cursor and absorb
3611cdf0e10cSrcweir             xText.insertTextContent(xDocTextCursor, xContent1, true);
3612cdf0e10cSrcweir             xDocTextCursor.gotoRange(xEnd, false);
3613cdf0e10cSrcweir             xDocTextCursor.goLeft((short)1, true);
3614cdf0e10cSrcweir             xText.insertTextContent(xDocTextCursor, xContent2, true);
3615cdf0e10cSrcweir 
3616cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3617cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3618cdf0e10cSrcweir 
3619cdf0e10cSrcweir             TreeNode root = new TreeNode()
3620cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3621cdf0e10cSrcweir                 .appendChild( met1.dup()
3622cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3623cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3624cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3625cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3626cdf0e10cSrcweir             doTest(root, false);
3627cdf0e10cSrcweir         }
3628cdf0e10cSrcweir         {
3629cdf0e10cSrcweir             xText.setString("AB");
3630cdf0e10cSrcweir             xStart = xText.getStart();
3631cdf0e10cSrcweir             xEnd = xText.getEnd();
3632cdf0e10cSrcweir 
3633cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3634cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3635cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3636cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3637cdf0e10cSrcweir 
3638cdf0e10cSrcweir             // attach to range from meta getStart()/getEnd()
3639cdf0e10cSrcweir             xContent1.attach(xStart);
3640cdf0e10cSrcweir             xContent2.attach(xEnd);
3641cdf0e10cSrcweir 
3642cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3643cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3644cdf0e10cSrcweir 
3645cdf0e10cSrcweir             TreeNode root = new TreeNode()
3646cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3647cdf0e10cSrcweir                 .appendChild( met1.dup()
3648cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3649cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3650cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3651cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3652cdf0e10cSrcweir             doTest(root, false);
3653cdf0e10cSrcweir         }
3654cdf0e10cSrcweir         {
3655cdf0e10cSrcweir             xText.setString("AB");
3656cdf0e10cSrcweir             xStart = xText.getStart();
3657cdf0e10cSrcweir             xEnd = xText.getEnd();
3658cdf0e10cSrcweir 
3659cdf0e10cSrcweir             TreeNode nod1 = helper.mkTreeNode();
3660cdf0e10cSrcweir             TreeNode nod2 = helper.mkTreeNode();
3661cdf0e10cSrcweir             XTextContent xContent1 = helper.mkTextContent(inserter, nod1);
3662cdf0e10cSrcweir             XTextContent xContent2 = helper.mkTextContent(inserter, nod2);
3663cdf0e10cSrcweir 
3664cdf0e10cSrcweir             XTextCursor xTextCursor = xText.createTextCursor();
3665cdf0e10cSrcweir             xTextCursor.gotoStart(false);
3666cdf0e10cSrcweir 
3667cdf0e10cSrcweir             // attach to cursor from meta XText
3668cdf0e10cSrcweir             xContent1.attach(xTextCursor);
3669cdf0e10cSrcweir             xTextCursor.gotoEnd(false);
3670cdf0e10cSrcweir             xContent2.attach(xTextCursor);
3671cdf0e10cSrcweir 
3672cdf0e10cSrcweir             helper.postInserted(nod1, xContent1);
3673cdf0e10cSrcweir             helper.postInserted(nod2, xContent2);
3674cdf0e10cSrcweir 
3675cdf0e10cSrcweir             TreeNode root = new TreeNode()
3676cdf0e10cSrcweir                 .appendChild( new TextNode("12") )
3677cdf0e10cSrcweir                 .appendChild( met1.dup()
3678cdf0e10cSrcweir                     .appendChild( nod1.dup() )
3679cdf0e10cSrcweir                     .appendChild( new TextNode("AB") )
3680cdf0e10cSrcweir                     .appendChild( nod2.dup() ) )
3681cdf0e10cSrcweir                 .appendChild( new TextNode("6789") );
3682cdf0e10cSrcweir             doTest(root, false);
3683cdf0e10cSrcweir         }
3684cdf0e10cSrcweir     }
3685cdf0e10cSrcweir 
testMetaFieldXTextField()3686cdf0e10cSrcweir     @Test public void testMetaFieldXTextField() throws Exception
3687cdf0e10cSrcweir     {
3688cdf0e10cSrcweir         com.sun.star.rdf.XRepositorySupplier xModel =
3689cdf0e10cSrcweir             (com.sun.star.rdf.XRepositorySupplier) UnoRuntime.queryInterface(
3690cdf0e10cSrcweir                 com.sun.star.rdf.XRepositorySupplier.class, m_xDoc);
3691cdf0e10cSrcweir         com.sun.star.rdf.XRepository xRepo = xModel.getRDFRepository();
3692cdf0e10cSrcweir         // for testing just add it to the first graph
3693cdf0e10cSrcweir         com.sun.star.rdf.XURI[] Graphs = xRepo.getGraphNames();
3694cdf0e10cSrcweir         com.sun.star.rdf.XNamedGraph xGraph = xRepo.getGraph(Graphs[0]);
3695cdf0e10cSrcweir         com.sun.star.rdf.XURI xOdfPrefix =
3696cdf0e10cSrcweir             com.sun.star.rdf.URI.createKnown(m_xContext,
3697cdf0e10cSrcweir                 com.sun.star.rdf.URIs.ODF_PREFIX);
3698cdf0e10cSrcweir         com.sun.star.rdf.XURI xOdfSuffix =
3699cdf0e10cSrcweir             com.sun.star.rdf.URI.createKnown(m_xContext,
3700cdf0e10cSrcweir                 com.sun.star.rdf.URIs.ODF_SUFFIX);
3701cdf0e10cSrcweir         com.sun.star.rdf.XNode xPrefix =
3702cdf0e10cSrcweir             com.sun.star.rdf.Literal.create(m_xContext, "foo");
3703cdf0e10cSrcweir         com.sun.star.rdf.XNode xSuffix =
3704cdf0e10cSrcweir             com.sun.star.rdf.Literal.create(m_xContext, "bar");
3705cdf0e10cSrcweir 
3706cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
3707cdf0e10cSrcweir         TreeNode text = new TextNode("abc");
3708cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
3709cdf0e10cSrcweir         XText xDocText = m_xDoc.getText();
3710cdf0e10cSrcweir         XTextCursor xDocTextCursor = xDocText.createTextCursor();
3711cdf0e10cSrcweir         xDocTextCursor.goRight((short)1, false);
3712cdf0e10cSrcweir         xDocTextCursor.goRight((short)3, true);
3713cdf0e10cSrcweir 
3714cdf0e10cSrcweir         XTextField xMetaField = inserter.makeMetaField();
3715cdf0e10cSrcweir 
3716cdf0e10cSrcweir         xDocText.insertTextContent(xDocTextCursor, xMetaField, true);
3717cdf0e10cSrcweir 
3718cdf0e10cSrcweir         XMetadatable xMetadatable = (XMetadatable)
3719cdf0e10cSrcweir             UnoRuntime.queryInterface(XMetadatable.class, xMetaField);
3720cdf0e10cSrcweir         xMetadatable.ensureMetadataReference();
3721cdf0e10cSrcweir 
3722cdf0e10cSrcweir         xGraph.addStatement(xMetadatable, xOdfPrefix, xPrefix);
3723cdf0e10cSrcweir         xGraph.addStatement(xMetadatable, xOdfSuffix, xSuffix);
3724cdf0e10cSrcweir         assertEquals("getPresentation(): wrong",
3725cdf0e10cSrcweir                      "fooabcbar", xMetaField.getPresentation(false));
3726cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
3727cdf0e10cSrcweir     }
3728cdf0e10cSrcweir 
testMetaFieldXPropertySet()3729cdf0e10cSrcweir     @Test public void testMetaFieldXPropertySet() throws Exception
3730cdf0e10cSrcweir     {
3731cdf0e10cSrcweir         RangeInserter inserter = new RangeInserter(m_xDoc);
3732cdf0e10cSrcweir         TreeNode text = new TextNode("123");
3733cdf0e10cSrcweir         inserter.insertRange( new Range(0, 0, text) );
3734cdf0e10cSrcweir         XText xDocText = m_xDoc.getText();
3735cdf0e10cSrcweir         XTextCursor xDocTextCursor = xDocText.createTextCursor();
3736cdf0e10cSrcweir         xDocTextCursor.goRight((short)1, false);
3737cdf0e10cSrcweir         xDocTextCursor.goRight((short)3, true);
3738cdf0e10cSrcweir 
3739cdf0e10cSrcweir         XTextField xMetaField = inserter.makeMetaField();
3740cdf0e10cSrcweir 
3741cdf0e10cSrcweir         xDocText.insertTextContent(xDocTextCursor, xMetaField, true);
3742cdf0e10cSrcweir 
3743cdf0e10cSrcweir         XPropertySet xPropertySet = (XPropertySet)
3744cdf0e10cSrcweir             UnoRuntime.queryInterface(XPropertySet.class, xMetaField);
3745cdf0e10cSrcweir         assertNotNull("PropertySet: not supported?", xPropertySet);
3746cdf0e10cSrcweir         XPropertySetInfo xPropertySetInfo = xPropertySet.getPropertySetInfo();
3747cdf0e10cSrcweir         assertTrue("hasPropertyByName(\"NumberFormat\"):",
3748cdf0e10cSrcweir                    xPropertySetInfo.hasPropertyByName("NumberFormat"));
3749cdf0e10cSrcweir         assertTrue("hasPropertyByName(\"IsFixedLanguage\"):",
3750cdf0e10cSrcweir                    xPropertySetInfo.hasPropertyByName("IsFixedLanguage"));
3751cdf0e10cSrcweir 
3752cdf0e10cSrcweir         int def = (Integer) xPropertySet.getPropertyValue("NumberFormat");
3753cdf0e10cSrcweir         System.out.println("NumberFormat: default is " + def);
3754cdf0e10cSrcweir         short INT = com.sun.star.i18n.NumberFormatIndex.NUMBER_INT;
3755cdf0e10cSrcweir         xPropertySet.setPropertyValue("NumberFormat", INT);
3756cdf0e10cSrcweir         xPropertySet.setPropertyValue("IsFixedLanguage", true);
3757cdf0e10cSrcweir         int format = (Integer) xPropertySet.getPropertyValue("NumberFormat");
3758cdf0e10cSrcweir         assertEquals("NumberFormat: failed", INT, format);
3759cdf0e10cSrcweir         boolean isFixed = (Boolean)
3760cdf0e10cSrcweir             xPropertySet.getPropertyValue("IsFixedLanguage");
3761cdf0e10cSrcweir         assertTrue("IsFixedLanguage: failed", isFixed);
3762cdf0e10cSrcweir     }
3763cdf0e10cSrcweir 
testLoadStore()3764cdf0e10cSrcweir     @Test public void testLoadStore() throws Exception
3765cdf0e10cSrcweir     {
3766cdf0e10cSrcweir         XTextDocument xComp = null;
3767cdf0e10cSrcweir         String filename = "TESTMETA.odt";
3768cdf0e10cSrcweir         String file;
3769cdf0e10cSrcweir         try {
3770cdf0e10cSrcweir             file = TestDocument.getUrl(filename);
3771cdf0e10cSrcweir             xComp = doLoad(file);
3772cdf0e10cSrcweir             if (xComp != null)
3773cdf0e10cSrcweir             {
3774cdf0e10cSrcweir                 checkLoadMeta(xComp);
3775cdf0e10cSrcweir                 file = m_TmpDir + filename;
3776cdf0e10cSrcweir                 doStore(xComp, file);
3777cdf0e10cSrcweir                 close(xComp);
3778cdf0e10cSrcweir                 xComp = doLoad(file);
3779cdf0e10cSrcweir                 checkLoadMeta(xComp);
3780cdf0e10cSrcweir             }
3781cdf0e10cSrcweir         } finally {
3782cdf0e10cSrcweir             close(xComp);
3783cdf0e10cSrcweir         }
3784cdf0e10cSrcweir     }
3785cdf0e10cSrcweir 
doStore(XComponent xComp, String file)3786cdf0e10cSrcweir     private void doStore(XComponent xComp, String file) throws Exception
3787cdf0e10cSrcweir     {
3788cdf0e10cSrcweir         System.out.println("Storing test document...");
3789cdf0e10cSrcweir 
3790cdf0e10cSrcweir         XStorable xStor = (XStorable) UnoRuntime.queryInterface(
3791cdf0e10cSrcweir                     XStorable.class, xComp);
3792cdf0e10cSrcweir 
3793cdf0e10cSrcweir         xStor.storeToURL(file, new PropertyValue[0]);
3794cdf0e10cSrcweir 
3795cdf0e10cSrcweir         System.out.println("...done");
3796cdf0e10cSrcweir     }
3797cdf0e10cSrcweir 
doLoad(String file)3798cdf0e10cSrcweir     public XTextDocument doLoad(String file) throws Exception
3799cdf0e10cSrcweir     {
3800cdf0e10cSrcweir         XComponent xComp = null;
3801cdf0e10cSrcweir 
3802cdf0e10cSrcweir         System.out.println("Loading test document...");
3803cdf0e10cSrcweir 
3804cdf0e10cSrcweir         PropertyValue[] loadProps = new PropertyValue[1];
3805cdf0e10cSrcweir         loadProps[0] = new PropertyValue();
3806cdf0e10cSrcweir         loadProps[0].Name = "Hidden";
3807cdf0e10cSrcweir         loadProps[0].Value = new Boolean(true);
3808cdf0e10cSrcweir 
3809cdf0e10cSrcweir         xComp = util.DesktopTools.loadDoc(m_xMSF, file, loadProps);
3810cdf0e10cSrcweir //        xComp =  util.DesktopTools.getCLoader(m_xMSF).loadComponentFromURL(file, "_blank", 0, loadProps);
3811cdf0e10cSrcweir 
3812cdf0e10cSrcweir         XTextDocument xTextDoc = (XTextDocument)
3813cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextDocument.class, xComp);
3814cdf0e10cSrcweir 
3815cdf0e10cSrcweir         assertNotNull("cannot load: " + file, xTextDoc);
3816cdf0e10cSrcweir 
3817cdf0e10cSrcweir         System.out.println("...done");
3818cdf0e10cSrcweir 
3819cdf0e10cSrcweir         return xTextDoc;
3820cdf0e10cSrcweir     }
3821cdf0e10cSrcweir 
checkLoadMeta(XTextDocument xTextDoc)3822cdf0e10cSrcweir     public void checkLoadMeta(XTextDocument xTextDoc) throws Exception
3823cdf0e10cSrcweir     {
3824cdf0e10cSrcweir         XText xText = xTextDoc.getText();
3825cdf0e10cSrcweir 
3826cdf0e10cSrcweir         System.out.println("Checking meta(-field)s in loaded test document...");
3827cdf0e10cSrcweir 
3828cdf0e10cSrcweir         TreeNode root = new TreeNode()
3829cdf0e10cSrcweir             .appendChild( new RubyNode("ruby1")
3830cdf0e10cSrcweir                 .appendChild( new TextNode("1") ) )
3831cdf0e10cSrcweir             .appendChild( new MetaNode(mkId_("id1"))
3832cdf0e10cSrcweir                 .appendChild( new TextNode("2") ) )
3833cdf0e10cSrcweir             .appendChild( new MetaFieldNode(mkId_("id2"))
3834cdf0e10cSrcweir                 .appendChild( new TextNode("3") ) )
3835cdf0e10cSrcweir             .appendChild( new RubyNode("ruby2")
3836cdf0e10cSrcweir                 .appendChild( new MetaNode(mkId_("id3"))
3837cdf0e10cSrcweir                     .appendChild( new TextNode("4") ) ) )
3838cdf0e10cSrcweir             .appendChild( new RubyNode("ruby3")
3839cdf0e10cSrcweir                 .appendChild( new MetaFieldNode(mkId_("id4"))
3840cdf0e10cSrcweir                     .appendChild( new TextNode("5") ) ) )
3841cdf0e10cSrcweir             .appendChild( new MetaNode(mkId_("id5"))
3842cdf0e10cSrcweir                 .appendChild( new RubyNode("ruby4")
3843cdf0e10cSrcweir                     .appendChild( new TextNode("6") ) ) )
3844cdf0e10cSrcweir             .appendChild( new MetaFieldNode(mkId_("id6"))
3845cdf0e10cSrcweir                 .appendChild( new RubyNode("ruby5")
3846cdf0e10cSrcweir                     .appendChild( new TextNode("7") ) ) )
3847cdf0e10cSrcweir             .appendChild( new MetaNode(mkId_("id7"))
3848cdf0e10cSrcweir                 .appendChild( new MetaNode(mkId_("id8"))
3849cdf0e10cSrcweir                     .appendChild( new TextNode("8") ) ) )
3850cdf0e10cSrcweir             .appendChild( new MetaNode(mkId_("id9"))
3851cdf0e10cSrcweir                 .appendChild( new MetaFieldNode(mkId_("id10"))
3852cdf0e10cSrcweir                     .appendChild( new TextNode("9") ) ) )
3853cdf0e10cSrcweir             .appendChild( new MetaFieldNode(mkId_("id11"))
3854cdf0e10cSrcweir                 .appendChild( new MetaNode(mkId_("id12"))
3855cdf0e10cSrcweir                     .appendChild( new TextNode("10") ) ) )
3856cdf0e10cSrcweir             .appendChild( new MetaFieldNode(mkId_("id13"))
3857cdf0e10cSrcweir                 .appendChild( new MetaFieldNode(mkId_("id14"))
3858cdf0e10cSrcweir                     .appendChild( new TextNode("11") ) ) )
3859cdf0e10cSrcweir             .appendChild( new MetaNode(mkId_("id15"))
3860cdf0e10cSrcweir                 .appendChild( new RubyNode("ruby6")
3861cdf0e10cSrcweir                     .appendChild( new MetaFieldNode(mkId_("id16"))
3862cdf0e10cSrcweir                         .appendChild( new TextNode("12") ) ) ) )
3863cdf0e10cSrcweir             .appendChild( new MetaNode(mkId_("")) {
3864cdf0e10cSrcweir                                 public boolean equals(Object other) {
3865cdf0e10cSrcweir                                     return (other instanceof MetaNode);
3866cdf0e10cSrcweir                                 } }
3867cdf0e10cSrcweir                 .appendChild( new TextNode("13") ) )
3868cdf0e10cSrcweir             .appendChild( new TextNode(" X X ") );
3869cdf0e10cSrcweir         doTest(xTextDoc, root, false);
3870cdf0e10cSrcweir 
3871cdf0e10cSrcweir         System.out.println("...done");
3872cdf0e10cSrcweir     }
3873cdf0e10cSrcweir 
testLoadStoreXmlid()3874cdf0e10cSrcweir     @Test public void testLoadStoreXmlid() throws Exception
3875cdf0e10cSrcweir     {
3876cdf0e10cSrcweir         XTextDocument xComp = null;
3877cdf0e10cSrcweir         String filename = "TESTXMLID.odt";
3878cdf0e10cSrcweir         String file;
3879cdf0e10cSrcweir         try {
3880cdf0e10cSrcweir             file = TestDocument.getUrl(filename);
3881cdf0e10cSrcweir             xComp = doLoad(file);
3882cdf0e10cSrcweir             if (xComp != null)
3883cdf0e10cSrcweir             {
3884cdf0e10cSrcweir                 checkLoadXmlId(xComp);
3885cdf0e10cSrcweir                 file = m_TmpDir + filename;
3886cdf0e10cSrcweir                 doStore(xComp, file);
3887cdf0e10cSrcweir                 close(xComp);
3888cdf0e10cSrcweir                 xComp = doLoad(file);
3889cdf0e10cSrcweir                 checkLoadXmlId(xComp);
3890cdf0e10cSrcweir             }
3891cdf0e10cSrcweir         } finally {
3892cdf0e10cSrcweir             close(xComp);
3893cdf0e10cSrcweir         }
3894cdf0e10cSrcweir     }
3895cdf0e10cSrcweir 
checkLoadXmlId(XTextDocument xTextDoc)3896cdf0e10cSrcweir     public void checkLoadXmlId(XTextDocument xTextDoc) throws Exception
3897cdf0e10cSrcweir     {
3898cdf0e10cSrcweir         XText xText = xTextDoc.getText();
3899cdf0e10cSrcweir 
3900cdf0e10cSrcweir         System.out.println("Checking bookmarks in loaded test document...");
3901cdf0e10cSrcweir 
3902cdf0e10cSrcweir         XRepositorySupplier xRS = (XRepositorySupplier)
3903cdf0e10cSrcweir             UnoRuntime.queryInterface(XRepositorySupplier.class, xTextDoc);
3904cdf0e10cSrcweir         XDocumentRepository xRepo = (XDocumentRepository)
3905cdf0e10cSrcweir             UnoRuntime.queryInterface(XDocumentRepository.class,
3906cdf0e10cSrcweir                 xRS.getRDFRepository());
3907cdf0e10cSrcweir         XBookmarksSupplier xBMS = (XBookmarksSupplier)
3908cdf0e10cSrcweir             UnoRuntime.queryInterface(XBookmarksSupplier.class, xTextDoc);
3909cdf0e10cSrcweir         XNameAccess xBookmarks = xBMS.getBookmarks();
3910cdf0e10cSrcweir         XMetadatable xMark1 = (XMetadatable) UnoRuntime.queryInterface(
3911cdf0e10cSrcweir                 XMetadatable.class, xBookmarks.getByName("mk1"));
3912cdf0e10cSrcweir         assertTrue("mark1",
3913cdf0e10cSrcweir                 eq(xMark1.getMetadataReference(),
3914cdf0e10cSrcweir                     new StringPair("content.xml", "id90")));
3915cdf0e10cSrcweir 
3916cdf0e10cSrcweir         XMetadatable xMark2 = (XMetadatable) UnoRuntime.queryInterface(
3917cdf0e10cSrcweir                 XMetadatable.class, xBookmarks.getByName("mk2"));
3918cdf0e10cSrcweir         Pair<Statement[], Boolean> result = xRepo.getStatementRDFa(xMark2);
3919cdf0e10cSrcweir         assertTrue("mark2", (result.First.length == 1)
3920cdf0e10cSrcweir             && result.First[0].Subject.getStringValue().equals("uri:foo")
3921cdf0e10cSrcweir             && result.First[0].Predicate.getStringValue().equals("uri:bar")
3922cdf0e10cSrcweir             && result.First[0].Object.getStringValue().contains("a fooish bar")
3923cdf0e10cSrcweir             );
3924cdf0e10cSrcweir 
3925cdf0e10cSrcweir         XMetadatable xMark3 = (XMetadatable) UnoRuntime.queryInterface(
3926cdf0e10cSrcweir                 XMetadatable.class, xBookmarks.getByName("mk3"));
3927cdf0e10cSrcweir         assertTrue("mark3",
3928cdf0e10cSrcweir                 eq(xMark3.getMetadataReference(),
3929cdf0e10cSrcweir                     new StringPair("content.xml", "id91")));
3930cdf0e10cSrcweir 
3931cdf0e10cSrcweir         System.out.println("...done");
3932cdf0e10cSrcweir 
3933cdf0e10cSrcweir         System.out.println("Checking sections in loaded test document...");
3934cdf0e10cSrcweir 
3935cdf0e10cSrcweir         XTextSectionsSupplier xTSS = (XTextSectionsSupplier)
3936cdf0e10cSrcweir             UnoRuntime.queryInterface(XTextSectionsSupplier.class, xTextDoc);
3937cdf0e10cSrcweir 
3938cdf0e10cSrcweir         XNameAccess xSections = xTSS.getTextSections();
3939cdf0e10cSrcweir 
3940cdf0e10cSrcweir         XMetadatable xSection1 = (XMetadatable) UnoRuntime.queryInterface(
3941cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Section 1"));
3942cdf0e10cSrcweir         assertTrue("idsection1", eq(xSection1.getMetadataReference(),
3943cdf0e10cSrcweir                     new StringPair("content.xml", "idSection1")));
3944cdf0e10cSrcweir 
3945cdf0e10cSrcweir         XMetadatable xSection2 = (XMetadatable) UnoRuntime.queryInterface(
3946cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Section 2"));
3947cdf0e10cSrcweir         assertTrue("idSection2", eq(xSection2.getMetadataReference(),
3948cdf0e10cSrcweir                     new StringPair("content.xml", "idSection2")));
3949cdf0e10cSrcweir 
3950cdf0e10cSrcweir         XMetadatable xSection3 = (XMetadatable) UnoRuntime.queryInterface(
3951cdf0e10cSrcweir                 XMetadatable.class,
3952cdf0e10cSrcweir                 xSections.getByName("Table of Contents1_Head"));
3953cdf0e10cSrcweir         assertTrue("idTOCTitle", eq(xSection3.getMetadataReference(),
3954cdf0e10cSrcweir                     new StringPair("content.xml", "idTOCTitle")));
3955cdf0e10cSrcweir 
3956cdf0e10cSrcweir         XMetadatable xSection4 = (XMetadatable) UnoRuntime.queryInterface(
3957cdf0e10cSrcweir                 XMetadatable.class,
3958cdf0e10cSrcweir                 xSections.getByName("Alphabetical Index1_Head"));
3959cdf0e10cSrcweir         assertTrue("idAITitle", eq(xSection4.getMetadataReference(),
3960cdf0e10cSrcweir                     new StringPair("content.xml", "idAITitle")));
3961cdf0e10cSrcweir 
3962cdf0e10cSrcweir         XMetadatable xSection5 = (XMetadatable) UnoRuntime.queryInterface(
3963cdf0e10cSrcweir                 XMetadatable.class,
3964cdf0e10cSrcweir                 xSections.getByName("Illustration Index1_Head"));
3965cdf0e10cSrcweir         assertTrue("idIITitle", eq(xSection5.getMetadataReference(),
3966cdf0e10cSrcweir                     new StringPair("content.xml", "idIITitle")));
3967cdf0e10cSrcweir 
3968cdf0e10cSrcweir         XMetadatable xSection6 = (XMetadatable) UnoRuntime.queryInterface(
3969cdf0e10cSrcweir                 XMetadatable.class,
3970cdf0e10cSrcweir                 xSections.getByName("Index of Tables1_Head"));
3971cdf0e10cSrcweir         assertTrue("idIOTTitle", eq(xSection6.getMetadataReference(),
3972cdf0e10cSrcweir                     new StringPair("content.xml", "idIOTTitle")));
3973cdf0e10cSrcweir 
3974cdf0e10cSrcweir         XMetadatable xSection7 = (XMetadatable) UnoRuntime.queryInterface(
3975cdf0e10cSrcweir                 XMetadatable.class,
3976cdf0e10cSrcweir                 xSections.getByName("User-Defined1_Head"));
3977cdf0e10cSrcweir         assertTrue("idUDTitle", eq(xSection7.getMetadataReference(),
3978cdf0e10cSrcweir                     new StringPair("content.xml", "idUDTitle")));
3979cdf0e10cSrcweir 
3980cdf0e10cSrcweir         XMetadatable xSection8 = (XMetadatable) UnoRuntime.queryInterface(
3981cdf0e10cSrcweir                 XMetadatable.class,
3982cdf0e10cSrcweir                 xSections.getByName("Table of Objects1_Head"));
3983cdf0e10cSrcweir         assertTrue("idTOOTitle", eq(xSection8.getMetadataReference(),
3984cdf0e10cSrcweir                     new StringPair("content.xml", "idTOOTitle")));
3985cdf0e10cSrcweir 
3986cdf0e10cSrcweir         XMetadatable xSection9 = (XMetadatable) UnoRuntime.queryInterface(
3987cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Bibliography1_Head"));
3988cdf0e10cSrcweir         assertTrue("idBibTitle", eq(xSection9.getMetadataReference(),
3989cdf0e10cSrcweir                     new StringPair("content.xml", "idBibTitle")));
3990cdf0e10cSrcweir 
3991cdf0e10cSrcweir         System.out.println("...done");
3992cdf0e10cSrcweir 
3993cdf0e10cSrcweir         System.out.println("Checking indexes in loaded test document...");
3994cdf0e10cSrcweir 
3995cdf0e10cSrcweir         XDocumentIndexesSupplier xDIS = (XDocumentIndexesSupplier)
3996cdf0e10cSrcweir             UnoRuntime.queryInterface(XDocumentIndexesSupplier.class, xTextDoc);
3997cdf0e10cSrcweir         XIndexAccess xIndexesIA = xDIS.getDocumentIndexes();
3998cdf0e10cSrcweir         XNameAccess xIndexes =
3999cdf0e10cSrcweir             UnoRuntime.queryInterface(XNameAccess.class, xIndexesIA);
4000cdf0e10cSrcweir 
4001cdf0e10cSrcweir         XMetadatable xIndex1 = (XMetadatable) UnoRuntime.queryInterface(
4002cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("Table of Contents1"));
4003cdf0e10cSrcweir         assertTrue("idTOC", eq(xIndex1.getMetadataReference(),
4004cdf0e10cSrcweir                     new StringPair("content.xml", "idTOC")));
4005cdf0e10cSrcweir         XMetadatable xIndex1s = (XMetadatable) UnoRuntime.queryInterface(
4006cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Table of Contents1"));
4007cdf0e10cSrcweir         assertTrue("idTOC", eq(xIndex1s.getMetadataReference(),
4008cdf0e10cSrcweir                     new StringPair("content.xml", "idTOC")));
4009cdf0e10cSrcweir 
4010cdf0e10cSrcweir         XMetadatable xIndex2 = (XMetadatable) UnoRuntime.queryInterface(
4011cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("Alphabetical Index1"));
4012cdf0e10cSrcweir         assertTrue("idAI", eq(xIndex2.getMetadataReference(),
4013cdf0e10cSrcweir                     new StringPair("content.xml", "idAI")));
4014cdf0e10cSrcweir         XMetadatable xIndex2s = (XMetadatable) UnoRuntime.queryInterface(
4015cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Alphabetical Index1"));
4016cdf0e10cSrcweir         assertTrue("idAI", eq(xIndex2s.getMetadataReference(),
4017cdf0e10cSrcweir                     new StringPair("content.xml", "idAI")));
4018cdf0e10cSrcweir 
4019cdf0e10cSrcweir         XMetadatable xIndex3 = (XMetadatable) UnoRuntime.queryInterface(
4020cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("Illustration Index1"));
4021cdf0e10cSrcweir         assertTrue("idII", eq(xIndex3.getMetadataReference(),
4022cdf0e10cSrcweir                     new StringPair("content.xml", "idII")));
4023cdf0e10cSrcweir         XMetadatable xIndex3s = (XMetadatable) UnoRuntime.queryInterface(
4024cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Illustration Index1"));
4025cdf0e10cSrcweir         assertTrue("idII", eq(xIndex3s.getMetadataReference(),
4026cdf0e10cSrcweir                     new StringPair("content.xml", "idII")));
4027cdf0e10cSrcweir 
4028cdf0e10cSrcweir         XMetadatable xIndex4 = (XMetadatable) UnoRuntime.queryInterface(
4029cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("Index of Tables1"));
4030cdf0e10cSrcweir         assertTrue("idIOT", eq(xIndex4.getMetadataReference(),
4031cdf0e10cSrcweir                     new StringPair("content.xml", "idIOT")));
4032cdf0e10cSrcweir         XMetadatable xIndex4s = (XMetadatable) UnoRuntime.queryInterface(
4033cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Index of Tables1"));
4034cdf0e10cSrcweir         assertTrue("idIOT", eq(xIndex4s.getMetadataReference(),
4035cdf0e10cSrcweir                     new StringPair("content.xml", "idIOT")));
4036cdf0e10cSrcweir 
4037cdf0e10cSrcweir         XMetadatable xIndex5 = (XMetadatable) UnoRuntime.queryInterface(
4038cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("User-Defined1"));
4039cdf0e10cSrcweir         assertTrue("idUD", eq(xIndex5.getMetadataReference(),
4040cdf0e10cSrcweir                     new StringPair("content.xml", "idUD")));
4041cdf0e10cSrcweir         XMetadatable xIndex5s = (XMetadatable) UnoRuntime.queryInterface(
4042cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("User-Defined1"));
4043cdf0e10cSrcweir         assertTrue("idUD", eq(xIndex5s.getMetadataReference(),
4044cdf0e10cSrcweir                     new StringPair("content.xml", "idUD")));
4045cdf0e10cSrcweir 
4046cdf0e10cSrcweir         XMetadatable xIndex6 = (XMetadatable) UnoRuntime.queryInterface(
4047cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("Table of Objects1"));
4048cdf0e10cSrcweir         assertTrue("idTOO", eq(xIndex6.getMetadataReference(),
4049cdf0e10cSrcweir                     new StringPair("content.xml", "idTOO")));
4050cdf0e10cSrcweir         XMetadatable xIndex6s = (XMetadatable) UnoRuntime.queryInterface(
4051cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Table of Objects1"));
4052cdf0e10cSrcweir         assertTrue("idTOO", eq(xIndex6s.getMetadataReference(),
4053cdf0e10cSrcweir                     new StringPair("content.xml", "idTOO")));
4054cdf0e10cSrcweir 
4055cdf0e10cSrcweir         XMetadatable xIndex7 = (XMetadatable) UnoRuntime.queryInterface(
4056cdf0e10cSrcweir                 XMetadatable.class, xIndexes.getByName("Bibliography1"));
4057cdf0e10cSrcweir         assertTrue("idBib", eq(xIndex7.getMetadataReference(),
4058cdf0e10cSrcweir                     new StringPair("content.xml", "idBib")));
4059cdf0e10cSrcweir         XMetadatable xIndex7s = (XMetadatable) UnoRuntime.queryInterface(
4060cdf0e10cSrcweir                 XMetadatable.class, xSections.getByName("Bibliography1"));
4061cdf0e10cSrcweir         assertTrue("idBib", eq(xIndex7s.getMetadataReference(),
4062cdf0e10cSrcweir                     new StringPair("content.xml", "idBib")));
4063cdf0e10cSrcweir 
4064cdf0e10cSrcweir         System.out.println("...done");
4065cdf0e10cSrcweir     }
4066cdf0e10cSrcweir 
close(XComponent i_comp)4067cdf0e10cSrcweir     static void close(XComponent i_comp)
4068cdf0e10cSrcweir     {
4069cdf0e10cSrcweir         try {
4070cdf0e10cSrcweir             XCloseable xClos = (XCloseable) UnoRuntime.queryInterface(
4071cdf0e10cSrcweir                         XCloseable.class, i_comp);
4072cdf0e10cSrcweir             if (xClos != null) xClos.close(true);
4073cdf0e10cSrcweir         } catch (Exception e) {
4074cdf0e10cSrcweir         }
4075cdf0e10cSrcweir     }
4076cdf0e10cSrcweir 
doTest(TreeNode intree)4077cdf0e10cSrcweir     private void doTest(TreeNode intree) throws Exception
4078cdf0e10cSrcweir     {
4079cdf0e10cSrcweir         doTest(m_xDoc, intree, true);
4080cdf0e10cSrcweir     }
4081cdf0e10cSrcweir 
doTest(TreeNode intree, boolean insert)4082cdf0e10cSrcweir     private void doTest(TreeNode intree, boolean insert) throws Exception
4083cdf0e10cSrcweir     {
4084cdf0e10cSrcweir         doTest(m_xDoc, intree, insert);
4085cdf0e10cSrcweir     }
4086cdf0e10cSrcweir 
doTest(XTextDocument xDoc, TreeNode intree, boolean insert)4087cdf0e10cSrcweir     private void doTest(XTextDocument xDoc, TreeNode intree,
4088cdf0e10cSrcweir             boolean insert) throws Exception
4089cdf0e10cSrcweir     {
4090cdf0e10cSrcweir         dumpTree(intree, "I: ");
4091cdf0e10cSrcweir 
4092cdf0e10cSrcweir         if (insert) {
4093cdf0e10cSrcweir             new TreeInserter(xDoc).insertTree(intree);
4094cdf0e10cSrcweir         }
4095cdf0e10cSrcweir 
4096cdf0e10cSrcweir //Thread.sleep(10000);
4097cdf0e10cSrcweir 
4098cdf0e10cSrcweir         XText xText = xDoc.getText();
4099cdf0e10cSrcweir         XEnumerationAccess xTextEA = (XEnumerationAccess)
4100cdf0e10cSrcweir             UnoRuntime.queryInterface(XEnumerationAccess.class, xText);
4101cdf0e10cSrcweir         XEnumeration xTextEnum = xTextEA.createEnumeration();
4102cdf0e10cSrcweir         // skip to right paragraph
4103cdf0e10cSrcweir         xTextEnum.nextElement(); // skip first -- always empty!
4104cdf0e10cSrcweir         Object xElement = xTextEnum.nextElement(); // second contains test case
4105cdf0e10cSrcweir         XEnumerationAccess xEA = (XEnumerationAccess)
4106cdf0e10cSrcweir             UnoRuntime.queryInterface(XEnumerationAccess.class, xElement);
4107cdf0e10cSrcweir         XEnumeration xEnum = xEA.createEnumeration();
4108cdf0e10cSrcweir         TreeNode outtree = new EnumConverter().convert(xEnum);
4109cdf0e10cSrcweir 
4110cdf0e10cSrcweir         dumpTree(outtree, "O: ");
4111cdf0e10cSrcweir 
4112cdf0e10cSrcweir         new FuzzyTester().doTest(intree, outtree);
4113cdf0e10cSrcweir     }
4114cdf0e10cSrcweir 
dumpTree(TreeNode tree)4115cdf0e10cSrcweir     private void dumpTree(TreeNode tree) { dumpTree(tree, "> "); }
4116cdf0e10cSrcweir 
dumpTree(TreeNode tree, String prefix)4117cdf0e10cSrcweir     private void dumpTree(TreeNode tree, String prefix)
4118cdf0e10cSrcweir     {
4119cdf0e10cSrcweir         System.out.println(prefix + tree.toString());
4120cdf0e10cSrcweir         TreeNodeEnum children = tree.createEnumeration();
4121cdf0e10cSrcweir         while (children.hasNext()) {
4122cdf0e10cSrcweir             TreeNode node = children.next();
4123cdf0e10cSrcweir             dumpTree(node, prefix + "  ");
4124cdf0e10cSrcweir         }
4125cdf0e10cSrcweir     }
4126cdf0e10cSrcweir 
mkName(String prefix)4127cdf0e10cSrcweir     private String mkName(String prefix)
4128cdf0e10cSrcweir     {
4129cdf0e10cSrcweir         return prefix + String.valueOf(m_Count++);
4130cdf0e10cSrcweir     }
4131cdf0e10cSrcweir 
mkId(String prefix)4132cdf0e10cSrcweir     private StringPair mkId(String prefix)
4133cdf0e10cSrcweir     {
4134cdf0e10cSrcweir         return new StringPair("content.xml", mkName(prefix));
4135cdf0e10cSrcweir     }
4136cdf0e10cSrcweir 
mkId_(String id)4137cdf0e10cSrcweir     private StringPair mkId_(String id)
4138cdf0e10cSrcweir     {
4139cdf0e10cSrcweir         return new StringPair("content.xml", id);
4140cdf0e10cSrcweir     }
4141cdf0e10cSrcweir 
eq(StringPair i_Left, StringPair i_Right)4142cdf0e10cSrcweir     static boolean eq(StringPair i_Left, StringPair i_Right)
4143cdf0e10cSrcweir     {
4144cdf0e10cSrcweir         return ((i_Left.First).equals(i_Right.First)) &&
4145cdf0e10cSrcweir             ((i_Left.Second).equals(i_Right.Second));
4146cdf0e10cSrcweir     }
4147cdf0e10cSrcweir 
setUpConnection()4148cdf0e10cSrcweir     @BeforeClass public static void setUpConnection() throws Exception {
4149cdf0e10cSrcweir         connection.setUp();
4150cdf0e10cSrcweir     }
4151cdf0e10cSrcweir 
tearDownConnection()4152cdf0e10cSrcweir     @AfterClass public static void tearDownConnection()
4153cdf0e10cSrcweir         throws InterruptedException, com.sun.star.uno.Exception
4154cdf0e10cSrcweir     {
4155cdf0e10cSrcweir         connection.tearDown();
4156cdf0e10cSrcweir     }
4157cdf0e10cSrcweir 
4158cdf0e10cSrcweir     private static final OfficeConnection connection = new OfficeConnection();
4159cdf0e10cSrcweir }
4160cdf0e10cSrcweir 
4161