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