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 com.sun.star.filter.config.tools.utils; 25 26 //_______________________________________________ 27 28 import java.lang.*; 29 import java.util.*; 30 import java.io.*; 31 32 //_______________________________________________ 33 34 /** 35 * It provides some constant values and some static helper routines 36 * which are necessary to work with a xml file - especially 37 * the filter configuration. 38 * 39 * 40 */ 41 public class XMLHelper 42 { 43 //___________________________________________ 44 // public const 45 46 /** it's a possible value of the xml attribute "oor:type" and identify an integer type. */ 47 public static final java.lang.String XMLTYPE_INTEGER = "xs:int"; 48 49 /** it's a possible value of the xml attribute "oor:type" and identify an boolean type. */ 50 public static final java.lang.String XMLTYPE_BOOLEAN = "xs:boolean"; 51 52 /** it's a possible value of the xml attribute "oor:type" and identify an string type. */ 53 public static final java.lang.String XMLTYPE_STRING = "xs:string"; 54 55 /** it's a possible value of the xml attribute "oor:type" and identify an string list type. */ 56 public static final java.lang.String XMLTYPE_STRINGLIST = "oor:string-list"; 57 58 /** it's a xml attribute, which specify a property name. */ 59 public static final java.lang.String XMLATTRIB_OOR_NAME = "oor:name"; 60 61 /** it's a xml attribute, which specify a property type. */ 62 public static final java.lang.String XMLATTRIB_OOR_TYPE = "oor:type"; 63 64 /** it's a xml attribute, which specify a list separator. */ 65 public static final java.lang.String XMLATTRIB_OOR_SEPARATOR = "oor:separator"; 66 67 /** it's a xml attribute, which specify a localized value. */ 68 public static final java.lang.String XMLATTRIB_OOR_LOCALIZED = "oor:localized"; 69 70 /** it's a xml attribute, which specify a merge operation for cfg layering. */ 71 public static final java.lang.String XMLATTRIB_OOR_OP = "oor:op"; 72 73 /** can be used as value for XMLATTRIB_OOR_OP. */ 74 public static final java.lang.String XMLATTRIB_OP_REPLACE = "replace"; 75 76 /** it's a xml attribute, which specify a locale value. */ 77 public static final java.lang.String XMLATTRIB_XML_LANG = "xml:lang"; 78 79 /** it's the tag name of a <value ...> entry. */ 80 public static final java.lang.String XMLTAG_VALUE = "value"; 81 82 /** it's the tag name of a <prop ...> entry. */ 83 public static final java.lang.String XMLTAG_PROP = "prop"; 84 85 /** it's the tag name of a <node ...> entry. */ 86 public static final java.lang.String XMLTAG_NODE = "node"; 87 88 //___________________________________________ 89 // private const 90 91 /** a static list of all possible separators, which can be used for configuration type string-list. */ 92 private static final java.lang.String[] DELIMS = {" ", ",", ";", ".", ":", "-", "_", "#", "'", "+", "*", "~", "=", "?"}; 93 94 /** index of the default separator inside list DELIMS. 95 * It's necessary to know such default separator; because it can 96 * be suppressed as xml attribute of the corresponding value tag. */ 97 private static final int DEFAULT_SEPARATOR = 0; 98 99 //___________________________________________ 100 101 /** analyze the structures of the given XML node and 102 * return a property set of all found sub nodes. 103 * 104 * Such properties are organized as [name, value] pairs. 105 * The type of a xml node will be detected automatically. 106 * Following types are supported: 107 * xs:int => java.lang.Integer 108 * xs:bool => java.lang.Boolean 109 * xs:string => java.lang.String 110 * oor:string-list => java.util.LinkedList[java.lang.String] 111 * oor:set => java.util.Vector[java.lang.Object] 112 * oor:localized => java.util.HashMap[java.lang.Object] 113 * 114 * @param aNode 115 * points directly to the xml node, where we should analyze 116 * the children nodes. 117 * 118 * @return [java.util.HashMap] 119 * contains every node name as key and its string(!) as value. 120 */ convertNodeToPropSet(org.w3c.dom.Node aNode)121 public static java.util.HashMap convertNodeToPropSet(org.w3c.dom.Node aNode) 122 throws java.lang.Exception 123 { 124 java.util.HashMap aPropSet = new java.util.HashMap(); 125 126 // get all child nodes, which seems to be properties 127 java.util.Vector lChildNodes = XMLHelper.extractChildNodesByTagName(aNode, XMLTAG_PROP); 128 java.util.Enumeration en1 = lChildNodes.elements(); 129 while(en1.hasMoreElements()) 130 { 131 org.w3c.dom.Node aChildNode = (org.w3c.dom.Node)en1.nextElement(); 132 133 // read its name 134 java.lang.String sChildName = XMLHelper.extractNodeAttribByName(aChildNode, XMLATTRIB_OOR_NAME); 135 if (sChildName == null) 136 throw new java.io.IOException("unsupported format: could not extract child node name"); 137 138 // read its type info 139 java.lang.String sChildType = XMLHelper.extractNodeAttribByName(aChildNode, XMLATTRIB_OOR_TYPE); 140 if (sChildType == null) 141 { 142 /** Special patch: 143 * If an xml tag has no type information set ... we can restore it 144 * by analyzing the already read tag name :-) 145 * Not very nice - but it can help to read stripped xml files too. */ 146 sChildType = XMLHelper.getTypeForTag(sChildName); 147 if (sChildType == null) 148 throw new java.io.IOException("unsupported format: could not extract child node type"); 149 } 150 151 // read its value(s?) 152 java.util.Vector lChildValues = XMLHelper.extractChildNodesByTagName(aChildNode, XMLTAG_VALUE); 153 java.util.Enumeration en2 = lChildValues.elements(); 154 int nValue = 0; 155 java.lang.Object aValue = null; 156 while(en2.hasMoreElements()) 157 { 158 org.w3c.dom.Node aValueNode = (org.w3c.dom.Node)en2.nextElement(); 159 java.lang.String sChildLocale = XMLHelper.extractNodeAttribByName(aValueNode, XMLATTRIB_XML_LANG); 160 boolean bLocalized = (sChildLocale != null); 161 162 ++nValue; 163 164 if (sChildType.equals(XMLTYPE_INTEGER)) 165 { 166 if (!bLocalized && nValue > 1) 167 throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); 168 java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); 169 aValue = new java.lang.Integer(sData); 170 } 171 else 172 if (sChildType.equals(XMLTYPE_BOOLEAN)) 173 { 174 if (!bLocalized && nValue > 1) 175 throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); 176 java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); 177 aValue = new java.lang.Boolean(sData); 178 } 179 else 180 if (sChildType.equals(XMLTYPE_STRING)) 181 { 182 if (!bLocalized && nValue > 1) 183 throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); 184 185 java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); 186 187 java.util.HashMap lLocalized = null; 188 if (bLocalized) 189 { 190 if (aValue == null) 191 aValue = new java.util.HashMap(); 192 lLocalized = (java.util.HashMap)aValue; 193 lLocalized.put(sChildLocale, sData); 194 } 195 else 196 aValue = sData; 197 } 198 else 199 if (sChildType.equals(XMLTYPE_STRINGLIST)) 200 { 201 if (!bLocalized && nValue > 1) 202 throw new java.io.IOException("unsupported format: more then one value for non localized but atomic type detected"); 203 204 java.lang.String sSeparator = XMLHelper.extractNodeAttribByName(aChildNode, XMLATTRIB_OOR_SEPARATOR); 205 if (sSeparator == null) 206 sSeparator = " "; 207 208 java.lang.String sData = ((org.w3c.dom.CharacterData)aValueNode.getFirstChild()).getData(); 209 sData = sData.replace('\t', ' '); 210 sData = sData.replace('\n', ' '); 211 java.util.StringTokenizer aTokenizer = new java.util.StringTokenizer(sData, sSeparator); 212 java.util.Vector lList = new java.util.Vector(); 213 while(aTokenizer.hasMoreTokens()) 214 { 215 java.lang.String sToken = (java.lang.String)aTokenizer.nextToken(); 216 sToken.trim(); 217 if (sToken.length() < 1) 218 continue; 219 lList.add(sToken); 220 } 221 aValue = lList; 222 } 223 224 aPropSet.put(sChildName, aValue); 225 } 226 } 227 228 return aPropSet; 229 } 230 231 //___________________________________________ 232 getTypeForTag(java.lang.String sTag)233 private static java.lang.String getTypeForTag(java.lang.String sTag) 234 { 235 java.lang.String sType = null; 236 237 if ( 238 (sTag.equals(Cache.PROPNAME_DATA )) || 239 (sTag.equals(Cache.PROPNAME_NAME )) || 240 (sTag.equals(Cache.PROPNAME_UINAME )) || 241 (sTag.equals(Cache.PROPNAME_MEDIATYPE )) || 242 (sTag.equals(Cache.PROPNAME_CLIPBOARDFORMAT )) || 243 (sTag.equals(Cache.PROPNAME_PREFERREDFILTER )) || 244 (sTag.equals(Cache.PROPNAME_DETECTSERVICE )) || 245 (sTag.equals(Cache.PROPNAME_FRAMELOADER )) || 246 (sTag.equals(Cache.PROPNAME_CONTENTHANDLER )) || 247 (sTag.equals(Cache.PROPNAME_DOCUMENTSERVICE )) || 248 (sTag.equals(Cache.PROPNAME_FILTERSERVICE )) || 249 (sTag.equals(Cache.PROPNAME_TEMPLATENAME )) || 250 (sTag.equals(Cache.PROPNAME_TYPE )) || 251 (sTag.equals(Cache.PROPNAME_UICOMPONENT )) 252 ) 253 sType = XMLTYPE_STRING; 254 else 255 if ( 256 (sTag.equals(Cache.PROPNAME_PREFERRED )) || 257 (sTag.equals("Installed" )) 258 ) 259 sType = XMLTYPE_BOOLEAN; 260 else 261 if ( 262 (sTag.equals(Cache.PROPNAME_UIORDER )) || 263 (sTag.equals(Cache.PROPNAME_DOCUMENTICONID )) || 264 (sTag.equals(Cache.PROPNAME_FILEFORMATVERSION)) 265 ) 266 sType = XMLTYPE_INTEGER; 267 else 268 if ( 269 (sTag.equals(Cache.PROPNAME_URLPATTERN )) || 270 (sTag.equals(Cache.PROPNAME_EXTENSIONS )) || 271 (sTag.equals(Cache.PROPNAME_USERDATA )) || 272 (sTag.equals(Cache.PROPNAME_FLAGS )) || 273 (sTag.equals(Cache.PROPNAME_TYPES )) 274 ) 275 sType = XMLTYPE_STRINGLIST; 276 277 if (sType == null) 278 System.err.println("getTypeForTag("+sTag+") = "+sType); 279 280 return sType; 281 } 282 283 //___________________________________________ 284 285 /** return a xml representation of the given property set. 286 * 287 * @param aPropSet 288 * a set of <name,value> pairs, which should be translated to xml 289 * 290 * @return [java.lang.String] 291 * the xml string representation. 292 * 293 * @throws [java.lang.Exception] 294 * if anything during conversion fill fail. 295 */ convertPropSetToXML(java.util.HashMap aPropSet , int nPrettyTabs)296 public static java.lang.String convertPropSetToXML(java.util.HashMap aPropSet , 297 int nPrettyTabs) 298 throws java.lang.Exception 299 { 300 java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); 301 302 java.util.Iterator it1 = aPropSet.keySet().iterator(); 303 while(it1.hasNext()) 304 { 305 java.lang.String sProp = (java.lang.String)it1.next(); 306 java.lang.Object aVal = aPropSet.get(sProp); 307 308 sProp = encodeHTMLSigns(sProp); 309 310 // is it a simple type? 311 if ( 312 (aVal instanceof java.lang.Integer) || 313 (aVal instanceof java.lang.Boolean) || 314 (aVal instanceof java.lang.String ) 315 ) 316 { 317 sXML.append(XMLHelper.convertSimpleObjectToXML(sProp, aVal, nPrettyTabs)); 318 continue; 319 } 320 321 // no! 322 // is it a list value? 323 if (aVal instanceof java.util.Vector) 324 { 325 java.util.Vector lVal = (java.util.Vector)aVal; 326 sXML.append(XMLHelper.convertListToXML(sProp, lVal, nPrettyTabs)); 327 continue; 328 } 329 330 // it's a localized value? 331 if (aVal instanceof java.util.HashMap) 332 { 333 java.util.HashMap lVal = (java.util.HashMap)aVal; 334 sXML.append(XMLHelper.convertLocalizedValueToXML(sProp, lVal, nPrettyTabs)); 335 continue; 336 } 337 338 // unknown type! 339 java.lang.StringBuffer sMsg = new java.lang.StringBuffer(256); 340 sMsg.append("unsupported object type detected."); 341 sMsg.append("\ttype ? : \""+sProp+"\" = "+aVal); 342 sMsg.append("\tprop set: \""+aPropSet ); 343 throw new java.lang.Exception(sMsg.toString()); 344 } 345 346 return sXML.toString(); 347 } 348 encodeHTMLSigns(java.lang.String sValue)349 public static java.lang.String encodeHTMLSigns(java.lang.String sValue) 350 { 351 java.lang.StringBuffer sSource = new java.lang.StringBuffer(sValue); 352 java.lang.StringBuffer sDestination = new java.lang.StringBuffer(1000 ); 353 354 for (int i=0; i<sSource.length(); ++i) 355 { 356 char c = sSource.charAt(i); 357 if (c == '&') 358 sDestination.append("&"); 359 else 360 sDestination.append(c); 361 } 362 363 java.lang.String sReturn = sDestination.toString(); 364 if (!sReturn.equals(sValue)) 365 System.out.println("encode \""+sValue+"\" => \""+sReturn+"\""); 366 367 return sReturn; 368 } 369 370 //___________________________________________ 371 372 /** return a xml representation of an atomic property. 373 * 374 * Atomic property types are e.g. Integer, Boolean, String. 375 * 376 * @param sName 377 * the name of the property. 378 379 * @param aValue 380 * the value of the property. 381 * 382 * @param nPrettyTabs 383 * count of tab signs for pretty format the xml code :-) 384 * 385 * @return [java.lang.String] 386 * the xml string representation. 387 * 388 * @throws [java.lang.Exception] 389 * if anything during conversion fill fail. 390 */ convertSimpleObjectToXML(java.lang.String sName , java.lang.Object aValue , int nPrettyTabs)391 private static java.lang.String convertSimpleObjectToXML(java.lang.String sName , 392 java.lang.Object aValue , 393 int nPrettyTabs) 394 throws java.lang.Exception 395 { 396 java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); 397 for (int t=0; t<nPrettyTabs; ++t) 398 sXML.append("\t"); 399 400 if (aValue instanceof java.lang.Integer) 401 { 402 sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">"); 403 sXML.append("<value>"+aValue.toString()+"</value>"); 404 sXML.append("</prop>\n"); 405 } 406 else 407 if (aValue instanceof java.lang.Boolean) 408 { 409 sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">"); 410 sXML.append("<value>"+aValue.toString()+"</value>"); 411 sXML.append("</prop>\n"); 412 } 413 else 414 if (aValue instanceof java.lang.String) 415 { 416 sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\""); 417 java.lang.String sValue = (java.lang.String)aValue; 418 419 sValue = encodeHTMLSigns(sValue); 420 421 if (sValue.length() < 1) 422 sXML.append("/>\n"); 423 else 424 { 425 sXML.append("><value>"+sValue+"</value>"); 426 sXML.append("</prop>\n"); 427 } 428 } 429 else 430 { 431 System.err.println("name = "+sName); 432 System.err.println("value = "+aValue); 433 // ! can be used outside to detect - that it was not a simple type :-) 434 throw new java.lang.Exception("not an atomic type."); 435 } 436 437 return sXML.toString(); 438 } 439 440 //___________________________________________ 441 442 /** return a xml representation of a string-list property. 443 * 444 * @param sName 445 * the name of the property. 446 447 * @param aValue 448 * the value of the property. 449 * 450 * @param nPrettyTabs 451 * count of tab signs for pretty format the xml code :-) 452 * 453 * @return [java.lang.String] 454 * the xml string representation. 455 * 456 * @throws [java.lang.Exception] 457 * if anything during conversion fill fail. 458 */ convertListToXML(java.lang.String sName , java.util.Vector aValue , int nPrettyTabs)459 private static java.lang.String convertListToXML(java.lang.String sName , 460 java.util.Vector aValue , 461 int nPrettyTabs) 462 throws java.lang.Exception 463 { 464 java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); 465 466 for (int t=0; t<nPrettyTabs; ++t) 467 sXML.append("\t"); 468 469 int c = aValue.size(); 470 if (c < 1) 471 { 472 sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\"/>\n"); 473 return sXML.toString(); 474 } 475 476 // step over all list items and add it to a string buffer 477 // Every item will be separated by a default separator "\n" first. 478 // Because "\n" is not a valid separator at all and can`t occur inside 479 // our list items. During we step over all items, we check if our current separator 480 // (we use a list of possible ones!) clash with an item. 481 // If it clash - we step to the next possible separator. 482 // If our list of possible separator values runs out of range we throw 483 // an exception :-) It's better then generating of wrong values 484 // If we found a valid separator - we use it to replace our "\n" place holder 485 // at the end of the following loop ... 486 487 int d = 0; 488 java.lang.StringBuffer sValBuff = new java.lang.StringBuffer(256); 489 for (int i=0; i<c; ++i) 490 { 491 // get the next list item 492 java.lang.Object aItem = aValue.get(i); 493 if (!(aItem instanceof java.lang.String)) 494 throw new java.lang.Exception("Current implementation supports string-list only!"); 495 496 java.lang.String sValue = (java.lang.String)aItem; 497 498 sValue = encodeHTMLSigns(sValue); 499 500 // append item with default separator, which isn't a valid separator at all 501 // But suppress adding of the separator if last element is reached. 502 sValBuff.append(sValue); 503 if (i<(c-1)) 504 sValBuff.append("\n"); 505 506 // check for delim clash 507 // Attention: An empty (means default) element forbid using 508 // of a whitespace character as separator! 509 while(true) 510 { 511 if (d >= DELIMS.length) 512 throw new java.lang.Exception("No valid separator found for a string list item."); 513 if (sValue.length() < 1 && DELIMS[d].equals(" ")) 514 { 515 ++d; 516 continue; 517 } 518 if (sValue.indexOf(DELIMS[d]) != -1) 519 { 520 ++d; 521 continue; 522 } 523 break; 524 } 525 } 526 527 // replace default separator with right one 528 System.out.println("TODO: must be adapted to java 1.3 :-("); 529 System.exit(-1); 530 //TODO_JAVA java.lang.String sListVal = sValBuff.toString().replaceAll("\n", DELIMS[d]); 531 java.lang.String sListVal = null; 532 533 sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">"); 534 if (d == DEFAULT_SEPARATOR) 535 sXML.append("<value>"); 536 else 537 sXML.append("<value "+XMLATTRIB_OOR_SEPARATOR+"=\""+DELIMS[d]+"\">"); 538 sXML.append(sListVal); 539 sXML.append("</value>"); 540 sXML.append("</prop>\n"); 541 542 return sXML.toString(); 543 } 544 545 //___________________________________________ 546 547 /** return a xml representation of a localized property. 548 * 549 * @param sName 550 * the name of the property. 551 552 * @param aValue 553 * the value of the property. 554 * 555 * @param nPrettyTabs 556 * count of tab signs for pretty format the xml code :-) 557 * 558 * @return [java.lang.String] 559 * the xml string representation. 560 * 561 * @throws [java.lang.Exception] 562 * if anything during conversion fill fail. 563 */ convertLocalizedValueToXML(java.lang.String sName , java.util.HashMap aValue , int nPrettyTabs)564 private static java.lang.String convertLocalizedValueToXML(java.lang.String sName , 565 java.util.HashMap aValue , 566 int nPrettyTabs) 567 throws java.lang.Exception 568 { 569 java.lang.StringBuffer sXML = new java.lang.StringBuffer(256); 570 571 int c = aValue.size(); 572 if (c < 1) 573 throw new java.lang.Exception("Can't detect type of localized values. Because the given list is empty."); 574 575 for (int t=0; t<nPrettyTabs; ++t) 576 sXML.append("\t"); 577 // !Our localized values must be formatted at a deeper column 578 // then its property name! 579 ++nPrettyTabs; 580 581 sXML.append("<prop "+XMLATTRIB_OOR_NAME+"=\""+sName+"\">\n"); 582 java.util.Iterator it = aValue.keySet().iterator(); 583 // boolean bTypeKnown = false; 584 while(it.hasNext()) 585 { 586 java.lang.String sLocale = (java.lang.String)it.next(); 587 java.lang.Object aLocalizedValue = aValue.get(sLocale); 588 /* 589 if (!bTypeKnown) 590 { 591 bTypeKnown = true; 592 if (aLocalizedValue instanceof java.lang.Integer) 593 sXML.append(" "+XMLATTRIB_OOR_TYPE+"=\""+XMLTYPE_INTEGER+"\">\n"); 594 else 595 if (aLocalizedValue instanceof java.lang.Boolean) 596 sXML.append(" "+XMLATTRIB_OOR_TYPE+"=\""+XMLTYPE_BOOLEAN+"\">\n"); 597 else 598 if (aLocalizedValue instanceof java.lang.String) 599 sXML.append(" "+XMLATTRIB_OOR_TYPE+"=\""+XMLTYPE_STRING+"\">\n"); 600 else 601 throw new java.lang.Exception("Unsupported type for localized value detected."); 602 } 603 */ 604 java.lang.String sLocValue = aLocalizedValue.toString(); 605 java.lang.String sValue = encodeHTMLSigns(sLocValue); 606 607 for (int t=0; t<nPrettyTabs; ++t) 608 sXML.append("\t"); 609 sXML.append("<value "+XMLATTRIB_XML_LANG+"=\""+sLocale+"\">"+sValue+"</value>\n"); 610 } 611 --nPrettyTabs; 612 for (int t=0; t<nPrettyTabs; ++t) 613 sXML.append("\t"); 614 sXML.append("</prop>\n"); 615 616 return sXML.toString(); 617 } 618 619 //___________________________________________ 620 621 /** returns the value of an attribute of the given node. 622 * 623 * If the given node represent an element node, may it supports some attributes. 624 * Then this method search for an attribute with the specified name and return its value. 625 * If nothing could be found ... or the given node isn't a suitable node ... it returns null. 626 * 627 * @param aNode 628 * the node, which should be analyzed. 629 * 630 * @param sAttrib 631 * name of the attribute, which should be searched. 632 * 633 * @return The value of the specified attribute if it could be found at the given node. 634 * Can be null if node doesn't support attributes or the searched one does not exist there. 635 */ extractNodeAttribByName(org.w3c.dom.Node aNode , java.lang.String sAttrib)636 public static java.lang.String extractNodeAttribByName(org.w3c.dom.Node aNode , 637 java.lang.String sAttrib) 638 throws java.lang.Exception 639 { 640 // We can get valid attributes for element nodes only! 641 if (aNode.getNodeType() != org.w3c.dom.Node.ELEMENT_NODE) 642 { 643 // System.err.println("not an element node"); 644 return null; 645 } 646 647 // may it supports attributes in general ... but doesn't have anyone really. 648 org.w3c.dom.NamedNodeMap lAttribs = aNode.getAttributes(); 649 if (lAttribs==null) 650 { 651 // System.err.println("no attributes at all"); 652 return null; 653 } 654 655 // step over the attribute list and search for the requested one 656 for (int i=0; i<lAttribs.getLength(); ++i) 657 { 658 org.w3c.dom.Attr aAttrib = (org.w3c.dom.Attr)lAttribs.item(i); 659 if (aAttrib.getName().equals(sAttrib)) 660 { 661 java.lang.String sValue = aAttrib.getValue(); 662 return sValue; 663 } 664 } 665 666 // the searched attribute was not found! 667 // System.err.println("required attribute \""+sAttrib+"\" does not exist for node ["+aNode.toString()+"]"); 668 return null; 669 } 670 671 //___________________________________________ 672 673 /** returns a list of childs, which are ELEMENT_NODES and have the right tag name. 674 * 675 * It analyze the list of all possible child nodes. Only ELEMENT_NODES are candidates. 676 * All other ones will be ignored. Further these element nodes are compared by it's tag 677 * names. If it match with the specified value it's added to the return list. 678 * So the return list includes references to the DOM tree nodes only, which are child 679 * element nodes with the right tag name. 680 * 681 * @param aNode 682 * provides access to the child nodes, which should be analyzed 683 * 684 * @param sTag 685 * the searched tag name. 686 * 687 * @return A list of child nodes, which are element nodes and have the right tag name. 688 */ extractChildNodesByTagName(org.w3c.dom.Node aNode, java.lang.String sTag )689 public static java.util.Vector extractChildNodesByTagName(org.w3c.dom.Node aNode, 690 java.lang.String sTag ) 691 { 692 // extract first all ELEMENT_NODES of he given parent 693 // Such nodes only provide tag names. 694 java.util.Vector lChilds = XMLHelper.extractChildNodesByType(aNode,org.w3c.dom.Node.ELEMENT_NODE); 695 java.util.Vector lExtractedChilds = new java.util.Vector(lChilds.size()); 696 697 // step over the list and search for the right tags using the specified name 698 java.util.Enumeration en = lChilds.elements(); 699 while (en.hasMoreElements()) 700 { 701 org.w3c.dom.Node aChild = (org.w3c.dom.Node)en.nextElement(); 702 if (aChild.getNodeName().equals(sTag)) 703 lExtractedChilds.add(aChild); 704 } 705 706 // pack(!) and return the list 707 lExtractedChilds.trimToSize(); 708 return lExtractedChilds; 709 } 710 711 //___________________________________________ 712 713 /** returns a list of childs, which supports the right node type. 714 * 715 * It analyzes the list of all possible child nodes. If a node represents the right node type 716 * it is added to the return list. Otherwise it will be ignored. 717 * 718 * @param aNode 719 * provides access to the list of possible children nodes. 720 * 721 * @param nType 722 * represent the searched node type. 723 * Possible values are constant fields of a org.w3c.dom.Node - e.g. org.w3c.dom.Node.ELEMENT_NODE. 724 * 725 * @return A list of child nodes, which provides the right node type. 726 */ extractChildNodesByType(org.w3c.dom.Node aNode, short nType)727 public static java.util.Vector extractChildNodesByType(org.w3c.dom.Node aNode, 728 short nType) 729 { 730 // get list of all possibe childs and reserve enough space for our return list 731 // Attention: A null pointer is not allowed for return! (means lExtractedChilds) 732 org.w3c.dom.NodeList lChilds = aNode.getChildNodes(); 733 int c = lChilds.getLength(); 734 java.util.Vector lExtractedChilds = new java.util.Vector(c); 735 736 // step of these childs and select only needed ones 737 for (int i=0; i<c; ++i) 738 { 739 org.w3c.dom.Node aChild = lChilds.item(i); 740 if (aChild.getNodeType() == nType) 741 lExtractedChilds.add(aChild); 742 } 743 744 // pack(!) and return the list 745 lExtractedChilds.trimToSize(); 746 return lExtractedChilds; 747 } 748 749 //___________________________________________ 750 751 /** generates an xml header, using parameters. 752 * 753 * @param sVersion 754 * number of the xml version. 755 * 756 * @param sEncoding 757 * used file encoding. 758 * 759 * @param sPath 760 * name of the configuration root. 761 * 762 * @param sPackage 763 * name of the configuration package. 764 * 765 * @param bLanguagepack 766 * force creation of a special header, 767 * which is needed for language packs only. 768 * 769 * @return [java.lang.String] 770 * the generated xml header. 771 772 */ generateHeader(java.lang.String sVersion , java.lang.String sEncoding , java.lang.String sPath , java.lang.String sPackage , boolean bLanguagePack)773 public static java.lang.String generateHeader(java.lang.String sVersion , 774 java.lang.String sEncoding , 775 java.lang.String sPath , 776 java.lang.String sPackage , 777 boolean bLanguagePack) 778 { 779 java.lang.StringBuffer sHeader = new java.lang.StringBuffer(256); 780 781 if (bLanguagePack) 782 { 783 sHeader.append("<?xml version=\""); 784 sHeader.append(sVersion); 785 sHeader.append("\" encoding=\""); 786 sHeader.append(sEncoding); 787 sHeader.append("\"?>\n"); 788 sHeader.append("<oor:component-data oor:package=\""); 789 sHeader.append(sPath); 790 sHeader.append("\" oor:name=\""); 791 sHeader.append(sPackage); 792 sHeader.append("\" xmlns:install=\"http://openoffice.org/2004/installation\""); 793 sHeader.append(" xmlns:oor=\"http://openoffice.org/2001/registry\""); 794 sHeader.append(" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""); 795 sHeader.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"); 796 } 797 else 798 { 799 sHeader.append("<?xml version=\""); 800 sHeader.append(sVersion); 801 sHeader.append("\" encoding=\""); 802 sHeader.append(sEncoding); 803 sHeader.append("\"?>\n"); 804 sHeader.append("<oor:component-data xmlns:oor=\"http://openoffice.org/2001/registry\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" oor:package=\""); 805 sHeader.append(sPath); 806 sHeader.append("\" oor:name=\""); 807 sHeader.append(sPackage); 808 sHeader.append("\">\n"); 809 } 810 811 return sHeader.toString(); 812 } 813 generateFooter()814 public static java.lang.String generateFooter() 815 { 816 return "</oor:component-data>\n"; 817 } 818 } 819