1 34 35 package com.micronova.util; 36 37 import java.util.*; 38 import java.io.*; 39 import java.text.*; 40 import java.util.regex.*; 41 42 import javax.xml.parsers.*; 43 import javax.xml.transform.*; 44 import javax.xml.transform.dom.*; 45 import javax.xml.transform.stream.*; 46 import javax.xml.transform.sax.*; 47 import org.w3c.dom.*; 48 import org.xml.sax.*; 49 import java.net.*; 50 51 52 53 public class XMLMap 54 { 55 56 57 public static final String TYPEATTRIBUTE = "typeAttribute"; 58 public static final String INDEXATTRIBUTE = "indexAttribute"; 59 public static final String DEFAULTTYPE = "defaultType"; 60 public static final String MAPTYPE = "mapType"; 61 public static final String LISTTYPE = "listType"; 62 public static final String ITEMNAME = "itemName"; 63 public static final String LISTNAME = "listName"; 64 public static final String NAMEPREFIX = "namePrefix"; 65 public static final String NAMESPACE = "namespace"; 66 public static final String ROOTNAME = "rootName"; 67 public static final String NAMEMAP = "nameMap"; 68 public static final String ROOTATTRIBUTE = "rootAttribute"; 69 public static final String HASATTRIBUTES = "hasAttributes"; 70 public static final String DOESENCODENAMES = "doesEncodeNames"; 71 72 public static final String ATTRIBUTE = "^"; 73 74 public static boolean isNameStartChar(char c) 75 { 76 78 return (c == '_' || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); 79 } 80 81 public static boolean isNameChar(char c) 82 { 83 return (isNameStartChar(c) || c == '-' || c == '.' || (c >= '0' && c <= '9')); 84 } 85 86 public static String encodeName(String name) 87 { 88 char[] chars = name.toCharArray(); 89 int length = chars.length; 90 91 if (length == 0) 92 { 93 return "_x_"; 94 } 95 96 StringBuffer buffer = new StringBuffer (); 97 98 int index = 0; 99 boolean afterUnderscore = false; 100 101 if (length > 0) 102 { 103 char c = chars[0]; 104 105 if (c == '_') 106 { 107 afterUnderscore = true; 108 index ++; 109 } 110 else if (isNameStartChar(c)) 111 { 112 buffer.append(c); 113 index ++; 114 } 115 else if (isNameChar(c)) 116 { 117 buffer.append("_0"); 118 } 119 } 120 121 while (index < length) 122 { 123 char c = chars[index]; 124 125 if (afterUnderscore) 126 { 127 buffer.append('_'); 128 129 if ((c == '0') || (c == 'x') || (c == '_')) 130 { 131 buffer.append('_'); 132 } 133 134 afterUnderscore = false; 135 } 136 137 if (c == '_') 138 { 139 afterUnderscore = true; 140 } 141 else if (isNameChar(c)) 142 { 143 buffer.append(c); 144 } 145 else 146 { 147 buffer.append("_x"); 148 String hex = Integer.toHexString((int)c); 149 buffer.append(hex); 150 buffer.append("_"); 151 } 152 153 index ++; 154 } 155 156 if (afterUnderscore) 157 { 158 buffer.append("_"); 159 } 160 161 return buffer.toString(); 162 } 163 164 public static String decodeName(String encoded) 165 { 166 if (encoded.equals("_x_")) 167 { 168 return ""; 169 } 170 171 StringBuffer buffer = new StringBuffer (); 172 StringBuffer hexBuffer = null; 173 174 char[] chars = encoded.toCharArray(); 175 int length = chars.length; 176 boolean afterUnderscore = false; 177 178 for (int index = 0; index < length; index ++) 179 { 180 char c = chars[index]; 181 182 if (afterUnderscore) 183 { 184 if (c == '0') 185 { 186 } 188 else if (c == '_') 189 { 190 buffer.append('_'); 191 } 192 else if (c == 'x') 193 { 194 if (hexBuffer == null) 195 { 196 hexBuffer = new StringBuffer (); 197 } 198 199 hexBuffer.setLength(0); 200 201 for (int j = index + 1; j < length; j ++) 202 { 203 char d = chars[j]; 204 205 if (d == '_') 206 { 207 index = j; 208 break; 209 } 210 else 211 { 212 hexBuffer.append(d); 213 } 214 } 215 216 buffer.append((char)Integer.parseInt(hexBuffer.toString(), 16)); 217 } 218 else 219 { 220 buffer.append('_'); 221 buffer.append(c); 222 } 223 224 afterUnderscore = false; 225 } 226 else 227 { 228 if (c == '_') 229 { 230 afterUnderscore = true; 231 } 232 else 233 { 234 buffer.append(c); 235 } 236 } 237 } 238 239 if (afterUnderscore) 240 { 241 buffer.append('_'); 242 } 243 244 return buffer.toString(); 245 } 246 247 248 249 250 public static final Map defaultControlMap; 251 252 static 253 { 254 defaultControlMap = new HashMap(); 255 256 defaultControlMap.put(TYPEATTRIBUTE, null); 257 defaultControlMap.put(INDEXATTRIBUTE, "index"); 258 defaultControlMap.put(DEFAULTTYPE, "string"); 259 defaultControlMap.put(MAPTYPE, "map"); 260 defaultControlMap.put(LISTTYPE, "list"); 261 defaultControlMap.put(LISTNAME, "_"); 262 defaultControlMap.put(ITEMNAME, "item"); 263 264 defaultControlMap.put(ROOTNAME, "root"); 265 defaultControlMap.put(NAMESPACE, "*"); 266 defaultControlMap.put(DOESENCODENAMES, "true"); 267 } 268 269 270 271 protected static final Map getControlMap(Map map, String key) 272 { 273 Map value = null; 274 275 if (map != null) 276 { 277 value = (Map)map.get(key); 278 } 279 280 if (value == null) 281 { 282 value = (Map)defaultControlMap.get(key); 283 } 284 285 return value; 286 } 287 288 289 290 protected static final String getControlString(Map map, String key) 291 { 292 String value = null; 293 294 if (map != null) 295 { 296 value = (String )map.get(key); 297 } 298 299 if (value == null) 300 { 301 value = (String )defaultControlMap.get(key); 302 } 303 304 return value; 305 } 306 307 308 309 protected static final Element addAttribute(Element element, Map map) 310 { 311 if (map != null) 312 { 313 Iterator iterator = map.entrySet().iterator(); 314 315 while (iterator.hasNext()) 316 { 317 Map.Entry entry = (Map.Entry)iterator.next(); 318 319 element.setAttribute(entry.getKey().toString(), entry.getValue().toString()); 320 } 321 } 322 323 return element; 324 } 325 326 327 328 public static final Document encode(Object object) throws Exception 329 { 330 return encode(object, null); 331 } 332 333 334 335 public static final Document encode(Object object, Map control) throws Exception 336 { 337 Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); 338 339 String name = getControlString(control, ROOTNAME); 340 boolean isEmptyName = TypeUtil.isEmptyString(name); 341 342 Element root = buildMapNode(document, (isEmptyName) ? "root" : name, object, getControlMap(control, ATTRIBUTE), control); 343 344 if (isEmptyName) 345 { 346 Node firstChild = root.getFirstChild(); 347 if (firstChild instanceof Element) 348 { 349 root = (Element)firstChild; 350 } 351 } 352 353 document.appendChild(root); 354 355 return document; 356 } 357 358 protected static final Element buildMapNode(Document document, String name, Object object, Map attributes, Map control) 359 { 360 String elementName = name; 361 362 boolean doesEncodeNames = TypeUtil.isTrue(getControlString(control, DOESENCODENAMES)); 363 364 if (doesEncodeNames) 365 { 366 elementName = encodeName(elementName); 367 } 368 369 String namePrefix = getControlString(control, NAMEPREFIX); 370 371 if (!TypeUtil.isEmpty(namePrefix)) 372 { 373 elementName = namePrefix + elementName; 374 } 375 376 Element element = document.createElement(elementName); 377 378 String typeAttribute = getControlString(control, TYPEATTRIBUTE); 379 380 if (object instanceof Map) 381 { 382 Map elementAttributes = (Map)((Map)object).get(ATTRIBUTE); 383 384 String mapType = getControlString(control, MAPTYPE); 385 386 if ((!TypeUtil.isEmpty(typeAttribute)) && (!TypeUtil.isEmpty(mapType))) 387 { 388 element.setAttribute(typeAttribute, mapType); 389 } 390 391 TreeMap treeMap = new TreeMap((Map)object); 392 393 Iterator iterator = treeMap.entrySet().iterator(); 394 395 while (iterator.hasNext()) 396 { 397 Map.Entry entry = (Map.Entry)iterator.next(); 398 399 Object key = entry.getKey(); 400 Object value = entry.getValue(); 401 402 if (key != null) 403 { 404 String keyString = key.toString(); 405 406 if (!ATTRIBUTE.equals(keyString)) 407 { 408 if (value instanceof List) 409 { 410 String itemName = getControlString(control, LISTNAME); 411 412 if ("*".equals(itemName)) 413 { 414 keyString = name; 415 } 416 else 417 { 418 keyString = itemName; 419 } 420 } 421 422 Map elementAttribute = null; 423 424 if (elementAttributes != null) 425 { 426 elementAttribute = (Map)elementAttributes.get(keyString); 427 } 428 429 Element child = buildMapNode(document, keyString, value, elementAttribute, control); 430 431 element.appendChild(child); 432 } 433 } 434 } 435 } 436 else if (object instanceof List) 437 { 438 String listType = getControlString(control, LISTTYPE); 439 String indexAttribute = getControlString(control, INDEXATTRIBUTE); 440 441 if ((!TypeUtil.isEmpty(typeAttribute)) && (!TypeUtil.isEmpty(listType))) 442 { 443 element.setAttribute(typeAttribute, listType); 444 } 445 446 int index = 0; 447 448 Iterator iterator = ((List)object).iterator(); 449 450 String itemName = getControlString(control, ITEMNAME); 451 452 while (iterator.hasNext()) 453 { 454 Object item = iterator.next(); 455 456 Element child = buildMapNode(document, itemName, item, attributes, control); 457 458 if (!TypeUtil.isEmpty(indexAttribute)) 459 { 460 child.setAttribute(indexAttribute, Integer.toString(index)); 461 } 462 463 element.appendChild(child); 464 465 index ++; 466 } 467 } 468 else 469 { 470 if (object != null) 471 { 472 String defaultType = getControlString(control, DEFAULTTYPE); 473 474 if ((!TypeUtil.isEmpty(typeAttribute)) && (!TypeUtil.isEmpty(defaultType))) 475 { 476 element.setAttribute(typeAttribute, defaultType); 477 } 478 479 Text text = document.createTextNode(object.toString()); 480 element.appendChild(text); 481 } 482 } 483 484 addAttribute(element, attributes); 485 486 return element; 487 } 488 489 490 491 public static Object decode(Node node) throws Exception 492 { 493 return decode(node, null); 494 } 495 496 497 498 public static String getNodeName(Node node, String namespace) 499 { 500 String nodeName = null; 501 502 String namespaceURI = node.getNamespaceURI(); 503 504 String localName = node.getLocalName(); 505 506 if (localName != null) 507 { 508 nodeName = localName; 509 } 510 else 511 { 512 nodeName = node.getNodeName(); 513 } 514 515 if (!"_".equals(nodeName)) 516 { 517 if (!"*".equals(namespace)) 518 { 519 if (namespaceURI != null) 520 { 521 if (!namespaceURI.equals(namespace)) 522 { 523 nodeName = namespaceURI + "|" + nodeName; 524 } 525 } 526 else 527 { 528 if ((namespace != null) && (!namespace.equals(""))) 529 { 530 nodeName = "|" + nodeName; 531 } 532 } 533 } 534 } 535 536 return nodeName; 537 } 538 539 540 541 public static NestedMap getAttributeMap(Node node, String namespace) throws Exception 542 { 543 NestedMap attributeMap = null; 544 545 NamedNodeMap attributeNodeMap = node.getAttributes(); 546 547 if (attributeNodeMap != null) 548 { 549 int attributeCount = attributeNodeMap.getLength(); 550 551 if (attributeCount > 0) 552 { 553 attributeMap = new NestedMap(); 554 555 while (--attributeCount >= 0) 556 { 557 Attr attr = (Attr)attributeNodeMap.item(attributeCount); 558 559 if (attr != null) 560 { 561 String attributeName = getNodeName(attr, namespace); 562 563 564 attributeMap.put(attributeName, attr.getValue()); 565 } 566 } 567 } 568 } 569 570 return attributeMap; 571 } 572 573 574 575 public static Object decode(Node node, Map control) throws Exception 576 { 577 return decode(node, control, "/"); 578 } 579 580 581 582 public static Object decode(Node node, Map control, String path) throws Exception 583 { 584 NestedMap map = null; 585 586 String text = null; 587 588 node.normalize(); 589 590 NodeList children = node.getChildNodes(); 591 592 int childrenLength = children.getLength(); 593 594 String namespace = getControlString(control, NAMESPACE); 595 boolean hasAttributes = TypeUtil.isTrue(getControlString(control, HASATTRIBUTES)); 596 boolean doesEncodeNames = TypeUtil.isTrue(getControlString(control, DOESENCODENAMES)); 597 598 Map nameMap = getControlMap(control, NAMEMAP); 599 600 for (int i = 0; i < childrenLength; i ++) 601 { 602 Node child = children.item(i); 603 604 int nodeType = child.getNodeType(); 605 606 if (nodeType == Node.ELEMENT_NODE) 607 { 608 if (map == null) 609 { 610 map = new NestedMap(); 611 } 612 613 String nodeName = getNodeName(child, namespace); 614 615 NestedMap attributeMap = null; 616 617 if (hasAttributes) 618 { 619 NamedNodeMap attributeNodeMap = child.getAttributes(); 620 621 if (attributeNodeMap != null) 622 { 623 attributeMap = getAttributeMap(child, namespace); 624 } 625 } 626 627 String nextPath = path + nodeName + "/"; 628 629 String target = getControlString(nameMap, nextPath); 630 631 if (target == null) 632 { 633 target = getControlString(nameMap, nodeName); 634 635 if (target == null) 636 { 637 target = nodeName; 638 } 639 } 640 641 if (doesEncodeNames) 642 { 643 target = decodeName(target); 644 } 645 646 if ("_".equals(target)) 647 { 648 NodeList listItems = child.getChildNodes(); 649 int listLength = listItems.getLength(); 650 651 for (int j = 0; j < listLength; j ++) 652 { 653 Node listItem = listItems.item(j); 654 655 NestedMap listItemAttributeMap = getAttributeMap(listItem, namespace); 656 657 String indexProperty = "*"; 658 659 if (listItemAttributeMap != null) 660 { 661 indexProperty = listItemAttributeMap.getString("index", indexProperty); 662 } 663 664 Object decoded = decode(listItem, control, nextPath); 665 666 if (decoded != null) 667 { 668 map.put("@_." + indexProperty, decoded); 669 670 if (hasAttributes && (listItemAttributeMap != null)) 671 { 672 map.put("@" + ATTRIBUTE + "._." + indexProperty, listItemAttributeMap); 673 } 674 } 675 } 676 } 677 else 678 { 679 map.put(target, decode(child, control, nextPath)); 680 681 if (attributeMap != null) 682 { 683 map.put("@" + ATTRIBUTE + "." + target, attributeMap); 684 } 685 } 686 } 687 else if (nodeType == Node.TEXT_NODE) 688 { 689 if (text == null) 690 { 691 text = child.getNodeValue(); 692 } 693 else 694 { 695 text = text + child.getNodeValue(); 696 } 697 } 698 } 699 700 if (map != null) 701 { 702 return map; 703 } 704 else 705 { 706 return text; 707 } 708 } 709 710 public static Object decode(String string, Map control) throws Exception 711 { 712 return decode(XMLUtil.parse(string, control), control, "/"); 713 } 714 715 public static Object decode(String string) throws Exception 716 { 717 return decode(string, null); 718 } 719 } 720 | Popular Tags |