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