1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package util; 29 30 import java.io.PrintWriter ; 31 import java.util.Vector ; 32 import java.util.Hashtable ; 33 import java.util.Enumeration ; 34 import java.util.HashSet ; 35 36 // access the implementations via names 37 import com.sun.star.uno.XInterface; 38 import com.sun.star.io.XOutputStream; 39 import com.sun.star.io.XInputStream; 40 import com.sun.star.io.XActiveDataSource; 41 import com.sun.star.ucb.XSimpleFileAccess; 42 import com.sun.star.lang.XMultiServiceFactory; 43 import com.sun.star.xml.sax.XDocumentHandler; 44 import com.sun.star.uno.Any; 45 import com.sun.star.uno.Type; 46 import com.sun.star.uno.UnoRuntime; 47 import com.sun.star.beans.PropertyValue; 48 import com.sun.star.xml.sax.XLocator; 49 import com.sun.star.xml.sax.XAttributeList; 50 import com.sun.star.xml.sax.XParser ; 51 import com.sun.star.xml.sax.InputSource ; 52 import com.sun.star.lang.XComponent; 53 import com.sun.star.document.XExporter; 54 import com.sun.star.document.XImporter; 55 import com.sun.star.document.XFilter; 56 57 58 public class XMLTools { 59 60 /** 61 * The implementation of <code>com.sun.star.xml.sax.XAttributeList</code> 62 * where attributes and their values can be added. 63 */ 64 public static class AttributeList implements XAttributeList { 65 private static class Attribute { 66 public String Name ; 67 public String Type ; 68 public String Value ; 69 } 70 private Hashtable attrByName = new Hashtable() ; 71 private Vector attributes = new Vector() ; 72 private PrintWriter log = null ; 73 74 /** 75 * Creates a class instance. 76 */ 77 public AttributeList() {} 78 79 /** 80 * Constructs a list which will report to <code>log</code> 81 * specified about each <code>XDocumentHandler</code> method 82 * call. 83 */ 84 public AttributeList(PrintWriter log) { 85 this.log = log ; 86 } 87 88 public AttributeList(XAttributeList list) { 89 if (list == null) return ; 90 for (short i = 0; i < list.getLength(); i++) { 91 add(list.getNameByIndex(i), list.getTypeByIndex(i), 92 list.getValueByIndex(i)) ; 93 } 94 } 95 96 /** 97 * Adds an attribute with type and value specified. 98 * @param name The attribute name. 99 * @param type Value type (usually 'CDATA' used). 100 * @param value Attribute value. 101 */ 102 public void add(String name, String type, String value) { 103 Attribute attr = new Attribute() ; 104 attr.Name = name ; 105 attr.Type = type ; 106 attr.Value = value ; 107 attributes.add(attr) ; 108 attrByName.put(attr.Name, attr) ; 109 } 110 111 /** 112 * Adds an attribute with value specified. As a type of 113 * value 'CDATA' string specified. 114 * @param name The attribute name. 115 * @param value Attribute value. 116 */ 117 public void add(String name, String value) { 118 add(name, "CDATA", value) ; 119 } 120 121 /** 122 * Clears all attributes added before. 123 */ 124 public void clear() { 125 attrByName.clear() ; 126 attributes.clear() ; 127 } 128 129 /*************************************** 130 * XAttributeList methods 131 ****************************************/ 132 133 public short getLength() { 134 if (log != null) 135 log.println("getLength() called -> " + attributes.size()) ; 136 return (short) attributes.size() ; 137 } 138 139 public String getNameByIndex(short idx) { 140 String name = ((Attribute) attributes.get(idx)).Name ; 141 if (log != null) 142 log.println("getNameByIndex(" + idx + ") called -> '" + 143 name + "'") ; 144 return name ; 145 } 146 147 public String getTypeByIndex(short idx) { 148 String type = ((Attribute) attributes.get(idx)).Type ; 149 if (log != null) 150 log.println("getTypeByIndex(" + idx + ") called -> '" + 151 type + "'") ; 152 return type; 153 } 154 155 public String getTypeByName(String name) { 156 String type = ((Attribute) attrByName.get(name)).Type ; 157 if (log != null) 158 log.println("getTypeByName('" + name + "') called -> '" + 159 type + "'") ; 160 return type; 161 } 162 public String getValueByIndex(short idx) { 163 String value = ((Attribute) attributes.get(idx)).Value ; 164 if (log != null) 165 log.println("getValueByIndex(" + idx + ") called -> '" + 166 value + "'") ; 167 return value; 168 } 169 170 public String getValueByName(String name) { 171 String value = ((Attribute) attrByName.get(name)).Value ; 172 if (log != null) 173 log.println("getValueByName('" + name + "') called -> '" + 174 value + "'") ; 175 return value; 176 } 177 } 178 179 /** 180 * This class writes all XML data handled into a stream specified 181 * in the constructor. 182 */ 183 public static class XMLWriter implements XDocumentHandler { 184 private PrintWriter _log = null ; 185 private String align = "" ; 186 187 /** 188 * Creates a SAX handler which writes all XML data 189 * handled into a <code>log</code> stream specified. 190 */ 191 public XMLWriter(PrintWriter log) { 192 _log = log ; 193 } 194 195 /** 196 * Creates a SAX handler which does nothing. 197 */ 198 public XMLWriter() { 199 } 200 201 public void processingInstruction(String appl, String data) { 202 if (_log == null) return ; 203 _log.println(align + "<?" + appl + " " + data + "?>") ; 204 } 205 public void startDocument() { 206 if (_log == null) return ; 207 _log.println("START DOCUMENT:") ; 208 } 209 public void endDocument() { 210 if (_log == null) return ; 211 _log.println("END DOCUMENT:") ; 212 } 213 public void setDocumentLocator(XLocator loc) { 214 if (_log == null) return ; 215 _log.println("DOCUMENT LOCATOR: ('" + loc.getPublicId() + 216 "','" + loc.getSystemId() + "')") ; 217 } 218 public void startElement(String name, XAttributeList attr) { 219 if (_log == null) return ; 220 _log.print(align + "<" + name + " ") ; 221 if (attr != null) { 222 short attrLen = attr.getLength() ; 223 for (short i = 0; i < attrLen; i++) { 224 if (i != 0) _log.print(align + " ") ; 225 _log.print(attr.getNameByIndex(i) + "[" + 226 attr.getTypeByIndex(i) + "]=\"" + 227 attr.getValueByIndex(i) + "\"") ; 228 if (i+1 != attrLen) { 229 _log.println() ; 230 } 231 } 232 } 233 _log.println(">") ; 234 235 align += " " ; 236 } 237 238 public void endElement(String name) { 239 if (_log == null) return ; 240 align = align.substring(3) ; 241 _log.println(align + "</" + name + ">") ; 242 } 243 244 public void characters(String chars) { 245 if (_log == null) return ; 246 _log.println(align + chars) ; 247 } 248 public void ignorableWhitespace(String sp) { 249 if (_log == null) return ; 250 _log.println(sp) ; 251 } 252 } 253 254 /** 255 * Checks if the XML structure is well formed (i.e. all tags opened must be 256 * closed and all tags opened inside a tag must be closed 257 * inside the same tag). It also checks parameters passed. 258 * If any collisions found appropriate error message is 259 * output into a stream specified. No XML data output, i.e. 260 * no output will be performed if no errors occur.<p> 261 * After document is completed there is a way to cehck 262 * if the XML data and structure was valid. 263 */ 264 public static class XMLWellFormChecker extends XMLWriter { 265 protected boolean docStarted = false ; 266 protected boolean docEnded = false ; 267 protected Vector tagStack = new Vector() ; 268 protected boolean wellFormed = true ; 269 protected boolean noOtherErrors = true ; 270 protected PrintWriter log = null ; 271 protected boolean printXMLData = false ; 272 273 public XMLWellFormChecker(PrintWriter log) { 274 super() ; 275 this.log = log ; 276 } 277 278 public XMLWellFormChecker(PrintWriter log_, boolean printXMLData) { 279 super(printXMLData ? log_ : null) ; 280 this.printXMLData = printXMLData ; 281 this.log = log_ ; 282 } 283 284 /** 285 * Reset all values. This is important e.g. for test of XFilter 286 * interface, where 'filter()' method istbstarted twice. 287 */ 288 public void reset() { 289 docStarted = false ; 290 docEnded = false ; 291 tagStack = new Vector() ; 292 wellFormed = true ; 293 noOtherErrors = true ; 294 PrintWriter log = null ; 295 printXMLData = false ; 296 } 297 298 public void startDocument() { 299 super.startDocument(); 300 301 if (docStarted) { 302 printError("Document is started twice.") ; 303 wellFormed = false ; 304 } 305 306 docStarted = true ; 307 } 308 public void endDocument() { 309 super.endDocument(); 310 if (!docStarted) { 311 wellFormed = false ; 312 printError("Document ended but not started.") ; 313 } 314 docEnded = true ; 315 } 316 public void startElement(String name, XAttributeList attr) { 317 super.startElement(name, attr); 318 if (attr == null) { 319 printError("attribute list passed as parameter to startElement()"+ 320 " method has null value for tag <" + name + ">") ; 321 noOtherErrors = false ; 322 } 323 tagStack.add(0, name) ; 324 } 325 public void endElement(String name) { 326 super.endElement(name); 327 if (wellFormed) { 328 if (tagStack.size() == 0) { 329 wellFormed = false ; 330 printError("No tags to close (bad closing tag </" + name + ">)") ; 331 } else { 332 String startTag = (String) tagStack.elementAt(0) ; 333 tagStack.remove(0) ; 334 if (!startTag.equals(name)) { 335 wellFormed = false ; 336 printError("Bad closing tag: </" + name + 337 ">; tag expected: </" + startTag + ">"); 338 } 339 } 340 } 341 } 342 343 /** 344 * Checks if there were no errors during document handling. 345 * I.e. startDocument() and endDocument() must be called, 346 * XML must be well formed, paramters must be valid. 347 */ 348 public boolean isWellFormed() { 349 if (!docEnded) { 350 printError("Document was not ended.") ; 351 wellFormed = false ; 352 } 353 354 return wellFormed && noOtherErrors ; 355 } 356 357 /** 358 * Prints error message and all tags where error occured inside. 359 * Also prints "Tag trace" in case if the full XML data isn't 360 * printed. 361 */ 362 public void printError(String msg) { 363 log.println("!!! Error: " + msg) ; 364 if (printXMLData) return ; 365 log.println(" Tag trace :") ; 366 for (int i = 0; i < tagStack.size(); i++) { 367 String tag = (String) tagStack.elementAt(i) ; 368 log.println(" <" + tag + ">") ; 369 } 370 } 371 } 372 373 /** 374 * Beside structure of XML this class also can check existence 375 * of tags, inner tags, and character data. After document 376 * completion there is a way to check if required tags and 377 * character data was found. If there any error occurs an 378 * appropriate message is output. 379 */ 380 public static class XMLTagsChecker extends XMLWellFormChecker { 381 protected Hashtable tags = new Hashtable() ; 382 protected Hashtable chars = new Hashtable() ; 383 protected boolean allOK = true ; 384 385 public XMLTagsChecker(PrintWriter log) { 386 super(log) ; 387 } 388 389 /** 390 * Adds a tag name which must be contained in the XML data. 391 */ 392 public void addTag(String tag) { 393 tags.put(tag, "") ; 394 } 395 /** 396 * Adds a tag name which must be contained in the XML data and 397 * must be inside the tag with name <code>outerTag</code>. 398 */ 399 public void addTagEnclosed(String tag, String outerTag) { 400 tags.put(tag, outerTag) ; 401 } 402 /** 403 * Adds a character data which must be contained in the XML data. 404 */ 405 public void addCharacters(String ch) { 406 chars.put(ch, "") ; 407 } 408 /** 409 * Adds a character data which must be contained in the XML data and 410 * must be inside the tag with name <code>outerTag</code>. 411 */ 412 public void addCharactersEnclosed(String ch, String outerTag) { 413 chars.put(ch, outerTag) ; 414 } 415 416 public void startElement(String name, XAttributeList attrs) { 417 super.startElement(name, attrs) ; 418 if (tags.containsKey(name)) { 419 String outerTag = (String) tags.get(name); 420 if (!outerTag.equals("")) { 421 boolean isInTag = false ; 422 for (int i = 0; i < tagStack.size(); i++) { 423 if (outerTag.equals((String) tagStack.elementAt(i))) { 424 isInTag = true ; 425 break ; 426 } 427 } 428 if (!isInTag) { 429 printError("Required tag <" + name + "> found, but is not enclosed in tag <" + 430 outerTag + ">") ; 431 allOK = false ; 432 } 433 } 434 tags.remove(name) ; 435 } 436 } 437 438 public void characters(String ch) { 439 super.characters(ch) ; 440 441 if (chars.containsKey(ch)) { 442 String outerTag = (String) chars.get(ch); 443 if (!outerTag.equals("")) { 444 boolean isInTag = false ; 445 for (int i = 0; i < tagStack.size(); i++) { 446 if (outerTag.equals((String) tagStack.elementAt(i))) { 447 isInTag = true ; 448 break ; 449 } 450 } 451 if (!isInTag) { 452 printError("Required characters '" + ch + "' found, but are not enclosed in tag <" + 453 outerTag + ">") ; 454 allOK = false ; 455 } 456 } 457 chars.remove(ch) ; 458 } 459 } 460 461 /** 462 * Checks if the XML data was valid and well formed and if 463 * all necessary tags and character data was found. 464 */ 465 public boolean checkTags() { 466 allOK &= isWellFormed() ; 467 468 Enumeration badTags = tags.keys() ; 469 Enumeration badChars = chars.keys() ; 470 471 if (badTags.hasMoreElements()) { 472 allOK = false ; 473 log.println("Required tags were not found in export :") ; 474 while(badTags.hasMoreElements()) { 475 log.println(" <" + ((String) badTags.nextElement()) + ">") ; 476 } 477 } 478 if (badChars.hasMoreElements()) { 479 allOK = false ; 480 log.println("Required characters were not found in export :") ; 481 while(badChars.hasMoreElements()) { 482 log.println(" <" + ((String) badChars.nextElement()) + ">") ; 483 } 484 } 485 reset(); 486 return allOK ; 487 } 488 } 489 490 /** 491 * Represents an XML tag which must be found in XML data written. 492 * This tag can contain only its name or tag name and attribute 493 * name, or attribute value additionally. 494 */ 495 public static class Tag { 496 private String name = null; 497 private String[][] attrList = new String[0][3] ; 498 499 /** 500 * Creates tag which has only a name. Attributes don't make sense. 501 * @param tagName The name of the tag. 502 */ 503 public Tag(String tagName) { 504 name = tagName ; 505 } 506 507 /** 508 * Creates a tag with the name specified, which must have an 509 * attribute with name specified. The value of this attribute 510 * doesn't make sense. 511 * @param tagName The name of the tag. 512 * @param attrName The name of attribute which must be contained 513 * in the tag. 514 */ 515 public Tag(String tagName, String attrName) { 516 name = tagName ; 517 attrList = new String[1][3] ; 518 attrList[0][0] = attrName ; 519 } 520 521 /** 522 * Creates a tag with the name specified, which must have an 523 * attribute with the value specified. The type of value 524 * assumed to be 'CDATA'. 525 * @param tagName The name of the tag. 526 * @param attrName The name of attribute which must be contained 527 * in the tag. 528 * @param attrValue Attribute value. 529 */ 530 public Tag(String tagName, String attrName, String attrValue) { 531 name = tagName ; 532 attrList = new String[1][3] ; 533 attrList[0][0] = attrName ; 534 attrList[0][1] = "CDATA" ; 535 attrList[0][2] = attrValue ; 536 } 537 538 /** 539 * Creates a tag with the name specified, which must have 540 * attributes specified. The value of thesee attributes 541 * doesn't make sense. 542 * @param tagName The name of the tag. 543 * @param attrNames Array with names of attributes which must 544 * be contained in the tag. 545 */ 546 public Tag(String tagName, String[] attrNames) { 547 name = tagName ; 548 attrList = new String[attrNames.length][3] ; 549 for (int i = 0; i < attrNames.length; i++) { 550 attrList[i][0] = attrNames[i] ; 551 } 552 } 553 554 /** 555 * Creates a tag with the name specified, which must have an 556 * attributes with their values specified. The type of all values 557 * assumed to be 'CDATA'. 558 * @param tagName The name of the tag. 559 * @param attrValues An array with attribute names and their values. 560 * <code>attrValues[N][0]</code> element contains the name of Nth 561 * attribute, and <code>attrValues[N][1]</code> element contains 562 * value of Nth attribute, if value is <code>null</code> then the 563 * attribute value can be any. 564 */ 565 public Tag(String tagName, String[][] attrValues) { 566 name = tagName ; 567 attrList = new String[attrValues.length][3] ; 568 for (int i = 0; i < attrValues.length; i++) { 569 attrList[i][0] = attrValues[i][0] ; 570 attrList[i][1] = "CDATA" ; 571 attrList[i][2] = attrValues[i][1] ; 572 } 573 } 574 575 /** 576 * Gets tag String description. 577 */ 578 public String toString() { 579 String ret = "<" + name ; 580 for (int i = 0; i < attrList.length; i++) { 581 ret += " " + attrList[i][0] + "="; 582 if (attrList[i][2] == null) { 583 ret += "(not specified)"; 584 } else { 585 ret += "\"" + attrList[i][2] + "\""; 586 } 587 } 588 ret += ">"; 589 590 return ret ; 591 } 592 593 protected boolean checkAttr(int attrListIdx, XAttributeList list) { 594 short j = 0 ; 595 int listLen = list.getLength(); 596 while(j < listLen) { 597 if (attrList[attrListIdx][0].equals(list.getNameByIndex(j))) { 598 if (attrList[attrListIdx][2] == null) return true ; 599 return attrList[attrListIdx][2].equals(list.getValueByIndex(j)) ; 600 } 601 j++ ; 602 } 603 return false ; 604 } 605 606 /** 607 * Checks if this tag matches tag passed in parameters. 608 * I.e. if tag specifies only it's name it mathes if names 609 * are equal (attributes don't make sense). If there are 610 * some attributes names specified in this tag method checks 611 * if all names present in attribute list <code>list</code> 612 * (attributes' values don't make sense). If attributes specified 613 * with values method checks if these attributes exist and 614 * have appropriate values. 615 */ 616 public boolean isMatchTo(String tagName, XAttributeList list) { 617 if (!name.equals(tagName)) return false; 618 boolean result = true ; 619 for (int i = 0; i < attrList.length; i++) { 620 result &= checkAttr(i, list) ; 621 } 622 return result ; 623 } 624 } 625 626 /** 627 * Class realises extended XML data checking. It has possibilities 628 * to check if a tag exists, if it has some attributes with 629 * values, and if this tag is contained in another tag (which 630 * also can specify any attributes). It can check if some 631 * character data exists inside any tag specified. 632 */ 633 public static class XMLChecker extends XMLWellFormChecker { 634 protected HashSet tagSet = new HashSet() ; 635 protected Vector tags = new Vector() ; 636 protected Vector chars = new Vector() ; 637 protected Vector tagStack = new Vector() ; 638 protected Vector attrStack = new Vector() ; 639 640 public XMLChecker(PrintWriter log, boolean writeXML) { 641 super(log, writeXML) ; 642 } 643 644 public void addTag(Tag tag) { 645 tags.add(new Tag[] {tag, null}) ; 646 tagSet.add(tag.name) ; 647 } 648 649 public void addTagEnclosed(Tag tag, Tag outerTag) { 650 tags.add(new Tag[] {tag, outerTag}) ; 651 tagSet.add(tag.name) ; 652 } 653 654 public void addCharacters(String ch) { 655 chars.add(new Object[] {ch.trim(), null}) ; 656 } 657 658 public void addCharactersEnclosed(String ch, Tag outerTag) { 659 chars.add(new Object[] {ch.trim(), outerTag}) ; 660 } 661 662 public void startElement(String name, XAttributeList attr) { 663 try { 664 super.startElement(name, attr); 665 666 if (tagSet.contains(name)) { 667 for (int i = 0; i < tags.size(); i++) { 668 Tag[] tag = (Tag[]) tags.elementAt(i); 669 if (tag[0].isMatchTo(name, attr)) { 670 if (tag[1] == null) { 671 tags.remove(i--); 672 } else { 673 boolean isInStack = false ; 674 for (int j = 0; j < tagStack.size(); j++) { 675 if (tag[1].isMatchTo((String) tagStack.elementAt(j), 676 (XAttributeList) attrStack.elementAt(j))) { 677 678 isInStack = true ; 679 break ; 680 } 681 } 682 if (isInStack) { 683 tags.remove(i--) ; 684 } 685 } 686 } 687 } 688 } 689 690 tagStack.add(0, name) ; 691 attrStack.add(0, new AttributeList(attr)); 692 } catch (Exception e) { 693 e.printStackTrace(log); 694 } 695 } 696 697 public void characters(String ch) { 698 super.characters(ch) ; 699 for (int i = 0; i < chars.size(); i++) { 700 Object[] chr = (Object[]) chars.elementAt(i); 701 if (((String) chr[0]).equals(ch)) { 702 if (chr[1] == null) { 703 chars.remove(i--); 704 } else { 705 boolean isInStack = false ; 706 for (int j = 0; j < tagStack.size(); j++) { 707 if (((Tag) chr[1]).isMatchTo((String) tagStack.elementAt(j), 708 (XAttributeList) attrStack.elementAt(j))) { 709 710 isInStack = true ; 711 break ; 712 } 713 } 714 if (isInStack) { 715 chars.remove(i--) ; 716 } 717 } 718 } 719 } 720 } 721 722 public void endElement(String name) { 723 try { 724 super.endElement(name); 725 726 if (tagStack.size() > 0) { 727 tagStack.remove(0) ; 728 attrStack.remove(0) ; 729 } 730 } catch(Exception e) { 731 e.printStackTrace(log) ; 732 } 733 } 734 735 public boolean check() { 736 if (tags.size()> 0) { 737 log.println("!!! Error: Some tags were not found :") ; 738 for (int i = 0; i < tags.size(); i++) { 739 Tag[] tag = (Tag[]) tags.elementAt(i) ; 740 log.println(" Tag " + tag[0] + " was not found"); 741 if (tag[1] != null) 742 log.println(" inside tag " + tag[1]) ; 743 } 744 } 745 if (chars.size() > 0) { 746 log.println("!!! Error: Some character data blocks were not found :") ; 747 for (int i = 0; i < chars.size(); i++) { 748 Object[] ch = (Object[]) chars.elementAt(i) ; 749 log.println(" Character data \"" + ch[0] + "\" was not found ") ; 750 if (ch[1] != null) 751 log.println(" inside tag " + ch[1]) ; 752 } 753 } 754 755 if (!isWellFormed()) 756 log.println("!!! Some errors were found in XML structure") ; 757 758 boolean result = tags.size() == 0 && chars.size() == 0 && isWellFormed(); 759 reset(); 760 return result; 761 } 762 } 763 764 /** 765 * Creates <code>XDocumentHandler</code> implementation in form 766 * of <code>com.sun.star.xml.sax.Writer</code> service, which 767 * writes XML data into a <code>com.sun.star.io.Pipe</code> 768 * created. 769 * @return Single element array which contains the handler 770 * contained in <code>Any</code> structure. 771 */ 772 public static Object[] getDocumentHandler(XMultiServiceFactory xMSF) { 773 Object[] ret = new Object[1]; 774 try { 775 XInterface Writer = (XInterface) xMSF.createInstance( 776 "com.sun.star.xml.sax.Writer"); 777 XInterface oPipe = (XInterface) xMSF.createInstance 778 ( "com.sun.star.io.Pipe" ); 779 XOutputStream xPipeOutput = (XOutputStream) UnoRuntime. 780 queryInterface(XOutputStream.class, oPipe) ; 781 782 XActiveDataSource xADS = (XActiveDataSource) 783 UnoRuntime.queryInterface(XActiveDataSource.class,Writer); 784 xADS.setOutputStream(xPipeOutput); 785 XDocumentHandler handler = (XDocumentHandler) 786 UnoRuntime.queryInterface(XDocumentHandler.class,Writer); 787 788 Any arg = new Any(new Type(XDocumentHandler.class),handler); 789 790 ret[0] = arg; 791 } catch (com.sun.star.uno.Exception e) { 792 e.printStackTrace(); 793 } 794 return ret; 795 } 796 797 public static PropertyValue[] createMediaDescriptor(String[] propNames, Object[] values) { 798 PropertyValue[] props = new PropertyValue[propNames.length] ; 799 800 for (int i = 0; i < props.length; i++) { 801 props[i] = new PropertyValue() ; 802 props[i].Name = propNames[i] ; 803 if (values != null && i < values.length) { 804 props[i].Value = values[i] ; 805 } 806 } 807 808 return props ; 809 } 810 811 /** 812 * Gets the hanlder, which writes all the XML data passed to the 813 * file specified. 814 * @param xMSF Soffice <code>ServiceManager</code> factory. 815 * @param fileURL The file URL (in form file:///<path>) to which 816 * XML data is written. 817 * @return SAX handler to which XML data has to be written. 818 */ 819 public static XDocumentHandler getFileXMLWriter(XMultiServiceFactory xMSF, String fileURL) 820 throws com.sun.star.uno.Exception 821 { 822 XInterface oFacc = (XInterface)xMSF.createInstance( 823 "com.sun.star.comp.ucb.SimpleFileAccess"); 824 XSimpleFileAccess xFacc = (XSimpleFileAccess)UnoRuntime.queryInterface 825 (XSimpleFileAccess.class, oFacc) ; 826 827 XInterface oWriter = (XInterface)xMSF.createInstance( 828 "com.sun.star.xml.sax.Writer"); 829 XActiveDataSource xWriterDS = (XActiveDataSource) 830 UnoRuntime.queryInterface(XActiveDataSource.class, oWriter); 831 XDocumentHandler xDocHandWriter = (XDocumentHandler) UnoRuntime.queryInterface 832 (XDocumentHandler.class, oWriter) ; 833 834 if (xFacc.exists(fileURL)) 835 xFacc.kill(fileURL); 836 XOutputStream fOut = xFacc.openFileWrite(fileURL) ; 837 xWriterDS.setOutputStream(fOut); 838 839 return xDocHandWriter ; 840 } 841 842 /** 843 * Parses XML file and passes its data to the SAX handler specified. 844 * @param xMSF Soffice <code>ServiceManager</code> factory. 845 * @param fileURL XML file name (in form file:///<path>) to be parsed. 846 * @param handler SAX handler to which XML data from file will 847 * be transferred. 848 */ 849 public static void parseXMLFile(XMultiServiceFactory xMSF, 850 String fileURL, XDocumentHandler handler) throws com.sun.star.uno.Exception 851 { 852 XInterface oFacc = (XInterface)xMSF.createInstance( 853 "com.sun.star.comp.ucb.SimpleFileAccess"); 854 XSimpleFileAccess xFacc = (XSimpleFileAccess)UnoRuntime.queryInterface 855 (XSimpleFileAccess.class, oFacc) ; 856 XInputStream oIn = xFacc.openFileRead(fileURL) ; 857 858 XInterface oParser = (XInterface)xMSF.createInstance( 859 "com.sun.star.xml.sax.Parser"); 860 XParser xParser = (XParser) UnoRuntime.queryInterface(XParser.class, oParser); 861 862 xParser.setDocumentHandler(handler) ; 863 InputSource inSrc = new InputSource() ; 864 inSrc.aInputStream = oIn ; 865 xParser.parseStream(inSrc) ; 866 867 oIn.closeInput(); 868 } 869 870 /** 871 * Exports document (the whole or a part) into the file specified 872 * in XML format. 873 * @param xMSF Soffice <code>ServiceManager</code> factory. 874 * @param xDoc Document to be exported. 875 * @param docType Type of document (for example 'Calc', 'Writer', 'Draw') 876 * The type must start with <b>capital</b> letter. 877 * @param exportType The type of export specifies if the whole 878 * document will be exported or one of its parts (Meta info, Styles, etc.). 879 * The following types supported (it also depends of document type) : 880 * "" (empty string) - for the whole document ; 881 * "Content" - only content exported ; 882 * "Meta" - meta document info exported ; 883 * "Settings" - view settings of document exported ; 884 * "Styles" - document styles exported ; 885 * @param fileURL XML file name (in form file:///<path>) to be exported to. 886 */ 887 public static void exportDocument(XMultiServiceFactory xMSF, XComponent xDoc, 888 String docType, String exportType, String fileURL) 889 throws com.sun.star.uno.Exception { 890 891 XDocumentHandler xDocHandWriter = XMLTools.getFileXMLWriter(xMSF, fileURL) ; 892 893 Any arg = new Any(new Type(XDocumentHandler.class), xDocHandWriter); 894 XInterface oExp = (XInterface)xMSF.createInstanceWithArguments( 895 "com.sun.star.comp." + docType + ".XML" + exportType + "Exporter", 896 new Object[] {arg}); 897 898 XExporter xExp = (XExporter) UnoRuntime.queryInterface 899 (XExporter.class, oExp) ; 900 xExp.setSourceDocument(xDoc) ; 901 902 XFilter filter = (XFilter) UnoRuntime.queryInterface(XFilter.class, oExp) ; 903 filter.filter(XMLTools.createMediaDescriptor( 904 new String[] {"FilterName"}, 905 new Object[] {"Custom filter"})) ; 906 } 907 908 /** 909 * Imports document (the whole or a part) from the file specified 910 * in XML format. 911 * @param xMSF Soffice <code>ServiceManager</code> factory. 912 * @param xDoc Target document to be imported. 913 * @param docType Type of document (for example 'Calc', 'Writer', 'Draw') 914 * The type must start with <b>capital</b> letter. 915 * @param exportType The type of export specifies if the whole 916 * document will be exported or one of its parts (Meta info, Styles, etc.). 917 * The following types supported (it hardly depends of XML data in file) : 918 * "" (empty string) - for the whole document ; 919 * "Content" - only content exported ; 920 * "Meta" - meta document info exported ; 921 * "Settings" - view settings of document exported ; 922 * "Styles" - document styles exported ; 923 * @param fileURL XML file name (in form file:///<path>) to be imported from. 924 */ 925 public static void importDocument(XMultiServiceFactory xMSF, XComponent xDoc, 926 String docType, String importType, String fileURL) 927 throws com.sun.star.uno.Exception { 928 929 XInterface oImp = (XInterface)xMSF.createInstance( 930 "com.sun.star.comp." + docType + ".XML" + importType + "Importer"); 931 XImporter xImp = (XImporter) UnoRuntime.queryInterface 932 (XImporter.class, oImp) ; 933 XDocumentHandler xDocHandImp = (XDocumentHandler) UnoRuntime.queryInterface 934 (XDocumentHandler.class, oImp) ; 935 936 xImp.setTargetDocument(xDoc) ; 937 parseXMLFile(xMSF, fileURL, xDocHandImp) ; 938 } 939 }