1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package com.jme3.export.xml; 34 35 import com.jme3.export.InputCapsule; 36 import com.jme3.export.Savable; 37 import com.jme3.export.SavableClassUtil; 38 import com.jme3.util.BufferUtils; 39 import com.jme3.util.IntMap; 40 import java.io.IOException; 41 import java.nio.ByteBuffer; 42 import java.nio.FloatBuffer; 43 import java.nio.IntBuffer; 44 import java.nio.ShortBuffer; 45 import java.util.*; 46 import java.util.logging.Logger; 47 import org.w3c.dom.*; 48 49 /** 50 * Part of the jME XML IO system as introduced in the google code jmexml project. 51 * 52 * @author Kai Rabien (hevee) - original author of the code.google.com jmexml project 53 * @author Doug Daniels (dougnukem) - adjustments for jME 2.0 and Java 1.5 54 * @author blaine 55 */ 56 public class DOMInputCapsule implements InputCapsule { 57 private static final Logger logger = 58 Logger.getLogger(DOMInputCapsule.class .getName()); 59 60 private Document doc; 61 private Element currentElem; 62 private XMLImporter importer; 63 private boolean isAtRoot = true; 64 private Map<String, Savable> referencedSavables = new HashMap<String, Savable>(); 65 66 private int[] classHierarchyVersions; 67 private Savable savable; 68 69 public DOMInputCapsule(Document doc, XMLImporter importer) { 70 this.doc = doc; 71 this.importer = importer; 72 currentElem = doc.getDocumentElement(); 73 74 String version = currentElem.getAttribute("format_version"); 75 importer.formatVersion = version.equals("") ? 0 : Integer.parseInt(version); 76 } 77 78 public int getSavableVersion(Class<? extends Savable> desiredClass) { 79 if (classHierarchyVersions != null){ 80 return SavableClassUtil.getSavedSavableVersion(savable, desiredClass, 81 classHierarchyVersions, importer.getFormatVersion()); 82 }else{ 83 return 0; 84 } 85 } 86 87 private static String decodeString(String s) { 88 if (s == null) { 89 return null; 90 } 91 s = s.replaceAll("\\"", "\"").replaceAll("\\<", "<").replaceAll("\\&", "&"); 92 return s; 93 } 94 95 private Element findFirstChildElement(Element parent) { 96 Node ret = parent.getFirstChild(); 97 while (ret != null && (!(ret instanceof Element))) { 98 ret = ret.getNextSibling(); 99 } 100 return (Element) ret; 101 } 102 103 private Element findChildElement(Element parent, String name) { 104 if (parent == null) { 105 return null; 106 } 107 Node ret = parent.getFirstChild(); 108 while (ret != null && (!(ret instanceof Element) || !ret.getNodeName().equals(name))) { 109 ret = ret.getNextSibling(); 110 } 111 return (Element) ret; 112 } 113 114 private Element findNextSiblingElement(Element current) { 115 Node ret = current.getNextSibling(); 116 while (ret != null) { 117 if (ret instanceof Element) { 118 return (Element) ret; 119 } 120 ret = ret.getNextSibling(); 121 } 122 return null; 123 } 124 125 public byte readByte(String name, byte defVal) throws IOException { 126 String tmpString = currentElem.getAttribute(name); 127 if (tmpString == null || tmpString.length() < 1) return defVal; 128 try { 129 return Byte.parseByte(tmpString); 130 } catch (NumberFormatException nfe) { 131 IOException io = new IOException(nfe.toString()); 132 io.initCause(nfe); 133 throw io; 134 } catch (DOMException de) { 135 IOException io = new IOException(de.toString()); 136 io.initCause(de); 137 throw io; 138 } 139 } 140 141 public byte[] readByteArray(String name, byte[] defVal) throws IOException { 142 try { 143 Element tmpEl; 144 if (name != null) { 145 tmpEl = findChildElement(currentElem, name); 146 } else { 147 tmpEl = currentElem; 148 } 149 if (tmpEl == null) { 150 return defVal; 151 } 152 String sizeString = tmpEl.getAttribute("size"); 153 String[] strings = parseTokens(tmpEl.getAttribute("data")); 154 if (sizeString.length() > 0) { 155 int requiredSize = Integer.parseInt(sizeString); 156 if (strings.length != requiredSize) 157 throw new IOException("Wrong number of bytes for '" + name 158 + "'. size says " + requiredSize 159 + ", data contains " 160 + strings.length); 161 } 162 byte[] tmp = new byte[strings.length]; 163 for (int i = 0; i < strings.length; i++) { 164 tmp[i] = Byte.parseByte(strings[i]); 165 } 166 return tmp; 167 } catch (IOException ioe) { 168 throw ioe; 169 } catch (NumberFormatException nfe) { 170 IOException io = new IOException(nfe.toString()); 171 io.initCause(nfe); 172 throw io; 173 } catch (DOMException de) { 174 IOException io = new IOException(de.toString()); 175 io.initCause(de); 176 throw io; 177 } 178 } 179 180 public byte[][] readByteArray2D(String name, byte[][] defVal) throws IOException { 181 try { 182 Element tmpEl; 183 if (name != null) { 184 tmpEl = findChildElement(currentElem, name); 185 } else { 186 tmpEl = currentElem; 187 } 188 if (tmpEl == null) { 189 return defVal; 190 } 191 192 String sizeString = tmpEl.getAttribute("size"); 193 NodeList nodes = currentElem.getChildNodes(); 194 List<byte[]> byteArrays = new ArrayList<byte[]>(); 195 196 for (int i = 0; i < nodes.getLength(); i++) { 197 Node n = nodes.item(i); 198 if (n instanceof Element && n.getNodeName().contains("array")) { 199 // Very unsafe assumption 200 byteArrays.add(readByteArray(n.getNodeName(), null)); 201 } 202 } 203 if (sizeString.length() > 0) { 204 int requiredSize = Integer.parseInt(sizeString); 205 if (byteArrays.size() != requiredSize) 206 throw new IOException( 207 "String array contains wrong element count. " 208 + "Specified size " + requiredSize 209 + ", data contains " + byteArrays.size()); 210 } 211 currentElem = (Element) currentElem.getParentNode(); 212 return byteArrays.toArray(new byte[0][]); 213 } catch (IOException ioe) { 214 throw ioe; 215 } catch (NumberFormatException nfe) { 216 IOException io = new IOException(nfe.toString()); 217 io.initCause(nfe); 218 throw io; 219 } catch (DOMException de) { 220 IOException io = new IOException(de.toString()); 221 io.initCause(de); 222 throw io; 223 } 224 } 225 226 public int readInt(String name, int defVal) throws IOException { 227 String tmpString = currentElem.getAttribute(name); 228 if (tmpString == null || tmpString.length() < 1) return defVal; 229 try { 230 return Integer.parseInt(tmpString); 231 } catch (NumberFormatException nfe) { 232 IOException io = new IOException(nfe.toString()); 233 io.initCause(nfe); 234 throw io; 235 } catch (DOMException de) { 236 IOException io = new IOException(de.toString()); 237 io.initCause(de); 238 throw io; 239 } 240 } 241 242 public int[] readIntArray(String name, int[] defVal) throws IOException { 243 try { 244 Element tmpEl; 245 if (name != null) { 246 tmpEl = findChildElement(currentElem, name); 247 } else { 248 tmpEl = currentElem; 249 } 250 if (tmpEl == null) { 251 return defVal; 252 } 253 String sizeString = tmpEl.getAttribute("size"); 254 String[] strings = parseTokens(tmpEl.getAttribute("data")); 255 if (sizeString.length() > 0) { 256 int requiredSize = Integer.parseInt(sizeString); 257 if (strings.length != requiredSize) 258 throw new IOException("Wrong number of ints for '" + name 259 + "'. size says " + requiredSize 260 + ", data contains " + strings.length); 261 } 262 int[] tmp = new int[strings.length]; 263 for (int i = 0; i < tmp.length; i++) { 264 tmp[i] = Integer.parseInt(strings[i]); 265 } 266 return tmp; 267 } catch (IOException ioe) { 268 throw ioe; 269 } catch (NumberFormatException nfe) { 270 IOException io = new IOException(nfe.toString()); 271 io.initCause(nfe); 272 throw io; 273 } catch (DOMException de) { 274 IOException io = new IOException(de.toString()); 275 io.initCause(de); 276 throw io; 277 } 278 } 279 280 public int[][] readIntArray2D(String name, int[][] defVal) throws IOException { 281 try { 282 Element tmpEl; 283 if (name != null) { 284 tmpEl = findChildElement(currentElem, name); 285 } else { 286 tmpEl = currentElem; 287 } 288 if (tmpEl == null) { 289 return defVal; 290 } 291 String sizeString = tmpEl.getAttribute("size"); 292 293 294 295 296 NodeList nodes = currentElem.getChildNodes(); 297 List<int[]> intArrays = new ArrayList<int[]>(); 298 299 for (int i = 0; i < nodes.getLength(); i++) { 300 Node n = nodes.item(i); 301 if (n instanceof Element && n.getNodeName().contains("array")) { 302 // Very unsafe assumption 303 intArrays.add(readIntArray(n.getNodeName(), null)); 304 } 305 } 306 if (sizeString.length() > 0) { 307 int requiredSize = Integer.parseInt(sizeString); 308 if (intArrays.size() != requiredSize) 309 throw new IOException( 310 "String array contains wrong element count. " 311 + "Specified size " + requiredSize 312 + ", data contains " + intArrays.size()); 313 } 314 currentElem = (Element) currentElem.getParentNode(); 315 return intArrays.toArray(new int[0][]); 316 } catch (IOException ioe) { 317 throw ioe; 318 } catch (NumberFormatException nfe) { 319 IOException io = new IOException(nfe.toString()); 320 io.initCause(nfe); 321 throw io; 322 } catch (DOMException de) { 323 IOException io = new IOException(de.toString()); 324 io.initCause(de); 325 throw io; 326 } 327 } 328 329 public float readFloat(String name, float defVal) throws IOException { 330 String tmpString = currentElem.getAttribute(name); 331 if (tmpString == null || tmpString.length() < 1) return defVal; 332 try { 333 return Float.parseFloat(tmpString); 334 } catch (NumberFormatException nfe) { 335 IOException io = new IOException(nfe.toString()); 336 io.initCause(nfe); 337 throw io; 338 } catch (DOMException de) { 339 IOException io = new IOException(de.toString()); 340 io.initCause(de); 341 throw io; 342 } 343 } 344 345 public float[] readFloatArray(String name, float[] defVal) throws IOException { 346 try { 347 Element tmpEl; 348 if (name != null) { 349 tmpEl = findChildElement(currentElem, name); 350 } else { 351 tmpEl = currentElem; 352 } 353 if (tmpEl == null) { 354 return defVal; 355 } 356 String sizeString = tmpEl.getAttribute("size"); 357 String[] strings = parseTokens(tmpEl.getAttribute("data")); 358 if (sizeString.length() > 0) { 359 int requiredSize = Integer.parseInt(sizeString); 360 if (strings.length != requiredSize) 361 throw new IOException("Wrong number of floats for '" + name 362 + "'. size says " + requiredSize 363 + ", data contains " + strings.length); 364 } 365 float[] tmp = new float[strings.length]; 366 for (int i = 0; i < tmp.length; i++) { 367 tmp[i] = Float.parseFloat(strings[i]); 368 } 369 return tmp; 370 } catch (IOException ioe) { 371 throw ioe; 372 } catch (DOMException de) { 373 IOException io = new IOException(de.toString()); 374 io.initCause(de); 375 throw io; 376 } 377 } 378 379 public float[][] readFloatArray2D(String name, float[][] defVal) throws IOException { 380 /* Why does this one method ignore the 'size attr.? */ 381 try { 382 Element tmpEl; 383 if (name != null) { 384 tmpEl = findChildElement(currentElem, name); 385 } else { 386 tmpEl = currentElem; 387 } 388 if (tmpEl == null) { 389 return defVal; 390 } 391 int size_outer = Integer.parseInt(tmpEl.getAttribute("size_outer")); 392 int size_inner = Integer.parseInt(tmpEl.getAttribute("size_outer")); 393 394 float[][] tmp = new float[size_outer][size_inner]; 395 396 String[] strings = parseTokens(tmpEl.getAttribute("data")); 397 for (int i = 0; i < size_outer; i++) { 398 tmp[i] = new float[size_inner]; 399 for (int k = 0; k < size_inner; k++) { 400 tmp[i][k] = Float.parseFloat(strings[i]); 401 } 402 } 403 return tmp; 404 } catch (NumberFormatException nfe) { 405 IOException io = new IOException(nfe.toString()); 406 io.initCause(nfe); 407 throw io; 408 } catch (DOMException de) { 409 IOException io = new IOException(de.toString()); 410 io.initCause(de); 411 throw io; 412 } 413 } 414 415 public double readDouble(String name, double defVal) throws IOException { 416 String tmpString = currentElem.getAttribute(name); 417 if (tmpString == null || tmpString.length() < 1) return defVal; 418 try { 419 return Double.parseDouble(tmpString); 420 } catch (NumberFormatException nfe) { 421 IOException io = new IOException(nfe.toString()); 422 io.initCause(nfe); 423 throw io; 424 } catch (DOMException de) { 425 IOException io = new IOException(de.toString()); 426 io.initCause(de); 427 throw io; 428 } 429 } 430 431 public double[] readDoubleArray(String name, double[] defVal) throws IOException { 432 try { 433 Element tmpEl; 434 if (name != null) { 435 tmpEl = findChildElement(currentElem, name); 436 } else { 437 tmpEl = currentElem; 438 } 439 if (tmpEl == null) { 440 return defVal; 441 } 442 String sizeString = tmpEl.getAttribute("size"); 443 String[] strings = parseTokens(tmpEl.getAttribute("data")); 444 if (sizeString.length() > 0) { 445 int requiredSize = Integer.parseInt(sizeString); 446 if (strings.length != requiredSize) 447 throw new IOException("Wrong number of doubles for '" 448 + name + "'. size says " + requiredSize 449 + ", data contains " + strings.length); 450 } 451 double[] tmp = new double[strings.length]; 452 for (int i = 0; i < tmp.length; i++) { 453 tmp[i] = Double.parseDouble(strings[i]); 454 } 455 return tmp; 456 } catch (IOException ioe) { 457 throw ioe; 458 } catch (NumberFormatException nfe) { 459 IOException io = new IOException(nfe.toString()); 460 io.initCause(nfe); 461 throw io; 462 } catch (DOMException de) { 463 IOException io = new IOException(de.toString()); 464 io.initCause(de); 465 throw io; 466 } 467 } 468 469 public double[][] readDoubleArray2D(String name, double[][] defVal) throws IOException { 470 try { 471 Element tmpEl; 472 if (name != null) { 473 tmpEl = findChildElement(currentElem, name); 474 } else { 475 tmpEl = currentElem; 476 } 477 if (tmpEl == null) { 478 return defVal; 479 } 480 String sizeString = tmpEl.getAttribute("size"); 481 NodeList nodes = currentElem.getChildNodes(); 482 List<double[]> doubleArrays = new ArrayList<double[]>(); 483 484 for (int i = 0; i < nodes.getLength(); i++) { 485 Node n = nodes.item(i); 486 if (n instanceof Element && n.getNodeName().contains("array")) { 487 // Very unsafe assumption 488 doubleArrays.add(readDoubleArray(n.getNodeName(), null)); 489 } 490 } 491 if (sizeString.length() > 0) { 492 int requiredSize = Integer.parseInt(sizeString); 493 if (doubleArrays.size() != requiredSize) 494 throw new IOException( 495 "String array contains wrong element count. " 496 + "Specified size " + requiredSize 497 + ", data contains " + doubleArrays.size()); 498 } 499 currentElem = (Element) currentElem.getParentNode(); 500 return doubleArrays.toArray(new double[0][]); 501 } catch (IOException ioe) { 502 throw ioe; 503 } catch (NumberFormatException nfe) { 504 IOException io = new IOException(nfe.toString()); 505 io.initCause(nfe); 506 throw io; 507 } catch (DOMException de) { 508 IOException io = new IOException(de.toString()); 509 io.initCause(de); 510 throw io; 511 } 512 } 513 514 public long readLong(String name, long defVal) throws IOException { 515 String tmpString = currentElem.getAttribute(name); 516 if (tmpString == null || tmpString.length() < 1) return defVal; 517 try { 518 return Long.parseLong(tmpString); 519 } catch (NumberFormatException nfe) { 520 IOException io = new IOException(nfe.toString()); 521 io.initCause(nfe); 522 throw io; 523 } catch (DOMException de) { 524 IOException io = new IOException(de.toString()); 525 io.initCause(de); 526 throw io; 527 } 528 } 529 530 public long[] readLongArray(String name, long[] defVal) throws IOException { 531 try { 532 Element tmpEl; 533 if (name != null) { 534 tmpEl = findChildElement(currentElem, name); 535 } else { 536 tmpEl = currentElem; 537 } 538 if (tmpEl == null) { 539 return defVal; 540 } 541 String sizeString = tmpEl.getAttribute("size"); 542 String[] strings = parseTokens(tmpEl.getAttribute("data")); 543 if (sizeString.length() > 0) { 544 int requiredSize = Integer.parseInt(sizeString); 545 if (strings.length != requiredSize) 546 throw new IOException("Wrong number of longs for '" + name 547 + "'. size says " + requiredSize 548 + ", data contains " + strings.length); 549 } 550 long[] tmp = new long[strings.length]; 551 for (int i = 0; i < tmp.length; i++) { 552 tmp[i] = Long.parseLong(strings[i]); 553 } 554 return tmp; 555 } catch (IOException ioe) { 556 throw ioe; 557 } catch (NumberFormatException nfe) { 558 IOException io = new IOException(nfe.toString()); 559 io.initCause(nfe); 560 throw io; 561 } catch (DOMException de) { 562 IOException io = new IOException(de.toString()); 563 io.initCause(de); 564 throw io; 565 } 566 } 567 568 public long[][] readLongArray2D(String name, long[][] defVal) throws IOException { 569 try { 570 Element tmpEl; 571 if (name != null) { 572 tmpEl = findChildElement(currentElem, name); 573 } else { 574 tmpEl = currentElem; 575 } 576 if (tmpEl == null) { 577 return defVal; 578 } 579 String sizeString = tmpEl.getAttribute("size"); 580 NodeList nodes = currentElem.getChildNodes(); 581 List<long[]> longArrays = new ArrayList<long[]>(); 582 583 for (int i = 0; i < nodes.getLength(); i++) { 584 Node n = nodes.item(i); 585 if (n instanceof Element && n.getNodeName().contains("array")) { 586 // Very unsafe assumption 587 longArrays.add(readLongArray(n.getNodeName(), null)); 588 } 589 } 590 if (sizeString.length() > 0) { 591 int requiredSize = Integer.parseInt(sizeString); 592 if (longArrays.size() != requiredSize) 593 throw new IOException( 594 "String array contains wrong element count. " 595 + "Specified size " + requiredSize 596 + ", data contains " + longArrays.size()); 597 } 598 currentElem = (Element) currentElem.getParentNode(); 599 return longArrays.toArray(new long[0][]); 600 } catch (IOException ioe) { 601 throw ioe; 602 } catch (NumberFormatException nfe) { 603 IOException io = new IOException(nfe.toString()); 604 io.initCause(nfe); 605 throw io; 606 } catch (DOMException de) { 607 IOException io = new IOException(de.toString()); 608 io.initCause(de); 609 throw io; 610 } 611 } 612 613 public short readShort(String name, short defVal) throws IOException { 614 String tmpString = currentElem.getAttribute(name); 615 if (tmpString == null || tmpString.length() < 1) return defVal; 616 try { 617 return Short.parseShort(tmpString); 618 } catch (NumberFormatException nfe) { 619 IOException io = new IOException(nfe.toString()); 620 io.initCause(nfe); 621 throw io; 622 } catch (DOMException de) { 623 IOException io = new IOException(de.toString()); 624 io.initCause(de); 625 throw io; 626 } 627 } 628 629 public short[] readShortArray(String name, short[] defVal) throws IOException { 630 try { 631 Element tmpEl; 632 if (name != null) { 633 tmpEl = findChildElement(currentElem, name); 634 } else { 635 tmpEl = currentElem; 636 } 637 if (tmpEl == null) { 638 return defVal; 639 } 640 String sizeString = tmpEl.getAttribute("size"); 641 String[] strings = parseTokens(tmpEl.getAttribute("data")); 642 if (sizeString.length() > 0) { 643 int requiredSize = Integer.parseInt(sizeString); 644 if (strings.length != requiredSize) 645 throw new IOException("Wrong number of shorts for '" 646 + name + "'. size says " + requiredSize 647 + ", data contains " + strings.length); 648 } 649 short[] tmp = new short[strings.length]; 650 for (int i = 0; i < tmp.length; i++) { 651 tmp[i] = Short.parseShort(strings[i]); 652 } 653 return tmp; 654 } catch (IOException ioe) { 655 throw ioe; 656 } catch (NumberFormatException nfe) { 657 IOException io = new IOException(nfe.toString()); 658 io.initCause(nfe); 659 throw io; 660 } catch (DOMException de) { 661 IOException io = new IOException(de.toString()); 662 io.initCause(de); 663 throw io; 664 } 665 } 666 667 public short[][] readShortArray2D(String name, short[][] defVal) throws IOException { 668 try { 669 Element tmpEl; 670 if (name != null) { 671 tmpEl = findChildElement(currentElem, name); 672 } else { 673 tmpEl = currentElem; 674 } 675 if (tmpEl == null) { 676 return defVal; 677 } 678 679 String sizeString = tmpEl.getAttribute("size"); 680 NodeList nodes = currentElem.getChildNodes(); 681 List<short[]> shortArrays = new ArrayList<short[]>(); 682 683 for (int i = 0; i < nodes.getLength(); i++) { 684 Node n = nodes.item(i); 685 if (n instanceof Element && n.getNodeName().contains("array")) { 686 // Very unsafe assumption 687 shortArrays.add(readShortArray(n.getNodeName(), null)); 688 } 689 } 690 if (sizeString.length() > 0) { 691 int requiredSize = Integer.parseInt(sizeString); 692 if (shortArrays.size() != requiredSize) 693 throw new IOException( 694 "String array contains wrong element count. " 695 + "Specified size " + requiredSize 696 + ", data contains " + shortArrays.size()); 697 } 698 currentElem = (Element) currentElem.getParentNode(); 699 return shortArrays.toArray(new short[0][]); 700 } catch (IOException ioe) { 701 throw ioe; 702 } catch (NumberFormatException nfe) { 703 IOException io = new IOException(nfe.toString()); 704 io.initCause(nfe); 705 throw io; 706 } catch (DOMException de) { 707 IOException io = new IOException(de.toString()); 708 io.initCause(de); 709 throw io; 710 } 711 } 712 713 public boolean readBoolean(String name, boolean defVal) throws IOException { 714 String tmpString = currentElem.getAttribute(name); 715 if (tmpString == null || tmpString.length() < 1) return defVal; 716 try { 717 return Boolean.parseBoolean(tmpString); 718 } catch (DOMException de) { 719 IOException io = new IOException(de.toString()); 720 io.initCause(de); 721 throw io; 722 } 723 } 724 725 public boolean[] readBooleanArray(String name, boolean[] defVal) throws IOException { 726 try { 727 Element tmpEl; 728 if (name != null) { 729 tmpEl = findChildElement(currentElem, name); 730 } else { 731 tmpEl = currentElem; 732 } 733 if (tmpEl == null) { 734 return defVal; 735 } 736 String sizeString = tmpEl.getAttribute("size"); 737 String[] strings = parseTokens(tmpEl.getAttribute("data")); 738 if (sizeString.length() > 0) { 739 int requiredSize = Integer.parseInt(sizeString); 740 if (strings.length != requiredSize) 741 throw new IOException("Wrong number of bools for '" + name 742 + "'. size says " + requiredSize 743 + ", data contains " + strings.length); 744 } 745 boolean[] tmp = new boolean[strings.length]; 746 for (int i = 0; i < tmp.length; i++) { 747 tmp[i] = Boolean.parseBoolean(strings[i]); 748 } 749 return tmp; 750 } catch (IOException ioe) { 751 throw ioe; 752 } catch (DOMException de) { 753 IOException io = new IOException(de.toString()); 754 io.initCause(de); 755 throw io; 756 } 757 } 758 759 public boolean[][] readBooleanArray2D(String name, boolean[][] defVal) throws IOException { 760 try { 761 Element tmpEl; 762 if (name != null) { 763 tmpEl = findChildElement(currentElem, name); 764 } else { 765 tmpEl = currentElem; 766 } 767 if (tmpEl == null) { 768 return defVal; 769 } 770 String sizeString = tmpEl.getAttribute("size"); 771 NodeList nodes = currentElem.getChildNodes(); 772 List<boolean[]> booleanArrays = new ArrayList<boolean[]>(); 773 774 for (int i = 0; i < nodes.getLength(); i++) { 775 Node n = nodes.item(i); 776 if (n instanceof Element && n.getNodeName().contains("array")) { 777 // Very unsafe assumption 778 booleanArrays.add(readBooleanArray(n.getNodeName(), null)); 779 } 780 } 781 if (sizeString.length() > 0) { 782 int requiredSize = Integer.parseInt(sizeString); 783 if (booleanArrays.size() != requiredSize) 784 throw new IOException( 785 "String array contains wrong element count. " 786 + "Specified size " + requiredSize 787 + ", data contains " + booleanArrays.size()); 788 } 789 currentElem = (Element) currentElem.getParentNode(); 790 return booleanArrays.toArray(new boolean[0][]); 791 } catch (IOException ioe) { 792 throw ioe; 793 } catch (NumberFormatException nfe) { 794 IOException io = new IOException(nfe.toString()); 795 io.initCause(nfe); 796 throw io; 797 } catch (DOMException de) { 798 IOException io = new IOException(de.toString()); 799 io.initCause(de); 800 throw io; 801 } 802 } 803 804 public String readString(String name, String defVal) throws IOException { 805 String tmpString = currentElem.getAttribute(name); 806 if (tmpString == null || tmpString.length() < 1) return defVal; 807 try { 808 return decodeString(tmpString); 809 } catch (DOMException de) { 810 IOException io = new IOException(de.toString()); 811 io.initCause(de); 812 throw io; 813 } 814 } 815 816 public String[] readStringArray(String name, String[] defVal) throws IOException { 817 try { 818 Element tmpEl; 819 if (name != null) { 820 tmpEl = findChildElement(currentElem, name); 821 } else { 822 tmpEl = currentElem; 823 } 824 if (tmpEl == null) { 825 return defVal; 826 } 827 String sizeString = tmpEl.getAttribute("size"); 828 NodeList nodes = tmpEl.getChildNodes(); 829 List<String> strings = new ArrayList<String>(); 830 831 for (int i = 0; i < nodes.getLength(); i++) { 832 Node n = nodes.item(i); 833 if (n instanceof Element && n.getNodeName().contains("String")) { 834 // Very unsafe assumption 835 strings.add(((Element) n).getAttributeNode("value").getValue()); 836 } 837 } 838 if (sizeString.length() > 0) { 839 int requiredSize = Integer.parseInt(sizeString); 840 if (strings.size() != requiredSize) 841 throw new IOException( 842 "String array contains wrong element count. " 843 + "Specified size " + requiredSize 844 + ", data contains " + strings.size()); 845 } 846 return strings.toArray(new String[0]); 847 } catch (IOException ioe) { 848 throw ioe; 849 } catch (NumberFormatException nfe) { 850 IOException io = new IOException(nfe.toString()); 851 io.initCause(nfe); 852 throw io; 853 } catch (DOMException de) { 854 IOException io = new IOException(de.toString()); 855 io.initCause(de); 856 throw io; 857 } 858 } 859 860 public String[][] readStringArray2D(String name, String[][] defVal) throws IOException { 861 try { 862 Element tmpEl; 863 if (name != null) { 864 tmpEl = findChildElement(currentElem, name); 865 } else { 866 tmpEl = currentElem; 867 } 868 if (tmpEl == null) { 869 return defVal; 870 } 871 String sizeString = tmpEl.getAttribute("size"); 872 NodeList nodes = currentElem.getChildNodes(); 873 List<String[]> stringArrays = new ArrayList<String[]>(); 874 875 for (int i = 0; i < nodes.getLength(); i++) { 876 Node n = nodes.item(i); 877 if (n instanceof Element && n.getNodeName().contains("array")) { 878 // Very unsafe assumption 879 stringArrays.add(readStringArray(n.getNodeName(), null)); 880 } 881 } 882 if (sizeString.length() > 0) { 883 int requiredSize = Integer.parseInt(sizeString); 884 if (stringArrays.size() != requiredSize) 885 throw new IOException( 886 "String array contains wrong element count. " 887 + "Specified size " + requiredSize 888 + ", data contains " + stringArrays.size()); 889 } 890 currentElem = (Element) currentElem.getParentNode(); 891 return stringArrays.toArray(new String[0][]); 892 } catch (IOException ioe) { 893 throw ioe; 894 } catch (NumberFormatException nfe) { 895 IOException io = new IOException(nfe.toString()); 896 io.initCause(nfe); 897 throw io; 898 } catch (DOMException de) { 899 IOException io = new IOException(de.toString()); 900 io.initCause(de); 901 throw io; 902 } 903 } 904 905 public BitSet readBitSet(String name, BitSet defVal) throws IOException { 906 String tmpString = currentElem.getAttribute(name); 907 if (tmpString == null || tmpString.length() < 1) return defVal; 908 try { 909 BitSet set = new BitSet(); 910 String[] strings = parseTokens(tmpString); 911 for (int i = 0; i < strings.length; i++) { 912 int isSet = Integer.parseInt(strings[i]); 913 if (isSet == 1) { 914 set.set(i); 915 } 916 } 917 return set; 918 } catch (NumberFormatException nfe) { 919 IOException io = new IOException(nfe.toString()); 920 io.initCause(nfe); 921 throw io; 922 } catch (DOMException de) { 923 IOException io = new IOException(de.toString()); 924 io.initCause(de); 925 throw io; 926 } 927 } 928 929 public Savable readSavable(String name, Savable defVal) throws IOException { 930 Savable ret = defVal; 931 if (name != null && name.equals("")) 932 logger.warning("Reading Savable String with name \"\"?"); 933 try { 934 Element tmpEl = null; 935 if (name != null) { 936 tmpEl = findChildElement(currentElem, name); 937 if (tmpEl == null) { 938 return defVal; 939 } 940 } else if (isAtRoot) { 941 tmpEl = doc.getDocumentElement(); 942 isAtRoot = false; 943 } else { 944 tmpEl = findFirstChildElement(currentElem); 945 } 946 currentElem = tmpEl; 947 ret = readSavableFromCurrentElem(defVal); 948 if (currentElem.getParentNode() instanceof Element) { 949 currentElem = (Element) currentElem.getParentNode(); 950 } else { 951 currentElem = null; 952 } 953 } catch (IOException ioe) { 954 throw ioe; 955 } catch (Exception e) { 956 IOException io = new IOException(e.toString()); 957 io.initCause(e); 958 throw io; 959 } 960 return ret; 961 } 962 963 private Savable readSavableFromCurrentElem(Savable defVal) throws 964 InstantiationException, ClassNotFoundException, 965 IOException, IllegalAccessException { 966 Savable ret = defVal; 967 Savable tmp = null; 968 969 if (currentElem == null || currentElem.getNodeName().equals("null")) { 970 return null; 971 } 972 String reference = currentElem.getAttribute("ref"); 973 if (reference.length() > 0) { 974 ret = referencedSavables.get(reference); 975 } else { 976 String className = currentElem.getNodeName(); 977 if (defVal != null) { 978 className = defVal.getClass().getName(); 979 } else if (currentElem.hasAttribute("class")) { 980 className = currentElem.getAttribute("class"); 981 } 982 tmp = SavableClassUtil.fromName(className, null); 983 984 985 String versionsStr = currentElem.getAttribute("savable_versions"); 986 if (versionsStr != null && !versionsStr.equals("")){ 987 String[] versionStr = versionsStr.split(","); 988 classHierarchyVersions = new int[versionStr.length]; 989 for (int i = 0; i < classHierarchyVersions.length; i++){ 990 classHierarchyVersions[i] = Integer.parseInt(versionStr[i].trim()); 991 } 992 }else{ 993 classHierarchyVersions = null; 994 } 995 996 String refID = currentElem.getAttribute("reference_ID"); 997 if (refID.length() < 1) refID = currentElem.getAttribute("id"); 998 if (refID.length() > 0) referencedSavables.put(refID, tmp); 999 if (tmp != null) { 1000 // Allows reading versions from this savable 1001 savable = tmp; 1002 tmp.read(importer); 1003 ret = tmp; 1004 } 1005 } 1006 return ret; 1007 } 1008 1009 public Savable[] readSavableArray(String name, Savable[] defVal) throws IOException { 1010 Savable[] ret = defVal; 1011 try { 1012 Element tmpEl = findChildElement(currentElem, name); 1013 if (tmpEl == null) { 1014 return defVal; 1015 } 1016 1017 String sizeString = tmpEl.getAttribute("size"); 1018 List<Savable> savables = new ArrayList<Savable>(); 1019 for (currentElem = findFirstChildElement(tmpEl); 1020 currentElem != null; 1021 currentElem = findNextSiblingElement(currentElem)) { 1022 savables.add(readSavableFromCurrentElem(null)); 1023 } 1024 if (sizeString.length() > 0) { 1025 int requiredSize = Integer.parseInt(sizeString); 1026 if (savables.size() != requiredSize) 1027 throw new IOException("Wrong number of Savables for '" 1028 + name + "'. size says " + requiredSize 1029 + ", data contains " + savables.size()); 1030 } 1031 ret = savables.toArray(new Savable[0]); 1032 currentElem = (Element) tmpEl.getParentNode(); 1033 return ret; 1034 } catch (IOException ioe) { 1035 throw ioe; 1036 } catch (Exception e) { 1037 IOException io = new IOException(e.toString()); 1038 io.initCause(e); 1039 throw io; 1040 } 1041 } 1042 1043 public Savable[][] readSavableArray2D(String name, Savable[][] defVal) throws IOException { 1044 Savable[][] ret = defVal; 1045 try { 1046 Element tmpEl = findChildElement(currentElem, name); 1047 if (tmpEl == null) { 1048 return defVal; 1049 } 1050 1051 int size_outer = Integer.parseInt(tmpEl.getAttribute("size_outer")); 1052 int size_inner = Integer.parseInt(tmpEl.getAttribute("size_outer")); 1053 1054 Savable[][] tmp = new Savable[size_outer][size_inner]; 1055 currentElem = findFirstChildElement(tmpEl); 1056 for (int i = 0; i < size_outer; i++) { 1057 for (int j = 0; j < size_inner; j++) { 1058 tmp[i][j] = (readSavableFromCurrentElem(null)); 1059 if (i == size_outer - 1 && j == size_inner - 1) { 1060 break; 1061 } 1062 currentElem = findNextSiblingElement(currentElem); 1063 } 1064 } 1065 ret = tmp; 1066 currentElem = (Element) tmpEl.getParentNode(); 1067 return ret; 1068 } catch (IOException ioe) { 1069 throw ioe; 1070 } catch (Exception e) { 1071 IOException io = new IOException(e.toString()); 1072 io.initCause(e); 1073 throw io; 1074 } 1075 } 1076 1077 public ArrayList<Savable> readSavableArrayList(String name, ArrayList defVal) throws IOException { 1078 try { 1079 Element tmpEl = findChildElement(currentElem, name); 1080 if (tmpEl == null) { 1081 return defVal; 1082 } 1083 1084 String sizeString = tmpEl.getAttribute("size"); 1085 ArrayList<Savable> savables = new ArrayList<Savable>(); 1086 for (currentElem = findFirstChildElement(tmpEl); 1087 currentElem != null; 1088 currentElem = findNextSiblingElement(currentElem)) { 1089 savables.add(readSavableFromCurrentElem(null)); 1090 } 1091 if (sizeString.length() > 0) { 1092 int requiredSize = Integer.parseInt(sizeString); 1093 if (savables.size() != requiredSize) 1094 throw new IOException( 1095 "Wrong number of Savable arrays for '" + name 1096 + "'. size says " + requiredSize 1097 + ", data contains " + savables.size()); 1098 } 1099 currentElem = (Element) tmpEl.getParentNode(); 1100 return savables; 1101 } catch (IOException ioe) { 1102 throw ioe; 1103 } catch (Exception e) { 1104 IOException io = new IOException(e.toString()); 1105 io.initCause(e); 1106 throw io; 1107 } 1108 } 1109 1110 public ArrayList<Savable>[] readSavableArrayListArray( 1111 String name, ArrayList[] defVal) throws IOException { 1112 try { 1113 Element tmpEl = findChildElement(currentElem, name); 1114 if (tmpEl == null) { 1115 return defVal; 1116 } 1117 currentElem = tmpEl; 1118 1119 String sizeString = tmpEl.getAttribute("size"); 1120 int requiredSize = (sizeString.length() > 0) 1121 ? Integer.parseInt(sizeString) 1122 : -1; 1123 1124 ArrayList<Savable> sal; 1125 List<ArrayList<Savable>> savableArrayLists = 1126 new ArrayList<ArrayList<Savable>>(); 1127 int i = -1; 1128 while (true) { 1129 sal = readSavableArrayList("SavableArrayList_" + ++i, null); 1130 if (sal == null && savableArrayLists.size() >= requiredSize) 1131 break; 1132 savableArrayLists.add(sal); 1133 } 1134 1135 if (requiredSize > -1 && savableArrayLists.size() != requiredSize) 1136 throw new IOException( 1137 "String array contains wrong element count. " 1138 + "Specified size " + requiredSize 1139 + ", data contains " + savableArrayLists.size()); 1140 currentElem = (Element) tmpEl.getParentNode(); 1141 return savableArrayLists.toArray(new ArrayList[0]); 1142 } catch (IOException ioe) { 1143 throw ioe; 1144 } catch (NumberFormatException nfe) { 1145 IOException io = new IOException(nfe.toString()); 1146 io.initCause(nfe); 1147 throw io; 1148 } catch (DOMException de) { 1149 IOException io = new IOException(de.toString()); 1150 io.initCause(de); 1151 throw io; 1152 } 1153 } 1154 1155 public ArrayList<Savable>[][] readSavableArrayListArray2D(String name, ArrayList[][] defVal) throws IOException { 1156 try { 1157 Element tmpEl = findChildElement(currentElem, name); 1158 if (tmpEl == null) { 1159 return defVal; 1160 } 1161 currentElem = tmpEl; 1162 String sizeString = tmpEl.getAttribute("size"); 1163 1164 ArrayList<Savable>[] arr; 1165 List<ArrayList<Savable>[]> sall = new ArrayList<ArrayList<Savable>[]>(); 1166 int i = -1; 1167 while ((arr = readSavableArrayListArray( 1168 "SavableArrayListArray_" + ++i, null)) != null) sall.add(arr); 1169 if (sizeString.length() > 0) { 1170 int requiredSize = Integer.parseInt(sizeString); 1171 if (sall.size() != requiredSize) 1172 throw new IOException( 1173 "String array contains wrong element count. " 1174 + "Specified size " + requiredSize 1175 + ", data contains " + sall.size()); 1176 } 1177 currentElem = (Element) tmpEl.getParentNode(); 1178 return sall.toArray(new ArrayList[0][]); 1179 } catch (IOException ioe) { 1180 throw ioe; 1181 } catch (Exception e) { 1182 IOException io = new IOException(e.toString()); 1183 io.initCause(e); 1184 throw io; 1185 } 1186 } 1187 1188 public ArrayList<FloatBuffer> readFloatBufferArrayList( 1189 String name, ArrayList<FloatBuffer> defVal) throws IOException { 1190 try { 1191 Element tmpEl = findChildElement(currentElem, name); 1192 if (tmpEl == null) { 1193 return defVal; 1194 } 1195 1196 String sizeString = tmpEl.getAttribute("size"); 1197 ArrayList<FloatBuffer> tmp = new ArrayList<FloatBuffer>(); 1198 for (currentElem = findFirstChildElement(tmpEl); 1199 currentElem != null; 1200 currentElem = findNextSiblingElement(currentElem)) { 1201 tmp.add(readFloatBuffer(null, null)); 1202 } 1203 if (sizeString.length() > 0) { 1204 int requiredSize = Integer.parseInt(sizeString); 1205 if (tmp.size() != requiredSize) 1206 throw new IOException( 1207 "String array contains wrong element count. " 1208 + "Specified size " + requiredSize 1209 + ", data contains " + tmp.size()); 1210 } 1211 currentElem = (Element) tmpEl.getParentNode(); 1212 return tmp; 1213 } catch (IOException ioe) { 1214 throw ioe; 1215 } catch (NumberFormatException nfe) { 1216 IOException io = new IOException(nfe.toString()); 1217 io.initCause(nfe); 1218 throw io; 1219 } catch (DOMException de) { 1220 IOException io = new IOException(de.toString()); 1221 io.initCause(de); 1222 throw io; 1223 } 1224 } 1225 1226 public Map<? extends Savable, ? extends Savable> readSavableMap(String name, Map<? extends Savable, ? extends Savable> defVal) throws IOException { 1227 Map<Savable, Savable> ret; 1228 Element tempEl; 1229 1230 if (name != null) { 1231 tempEl = findChildElement(currentElem, name); 1232 } else { 1233 tempEl = currentElem; 1234 } 1235 ret = new HashMap<Savable, Savable>(); 1236 1237 NodeList nodes = tempEl.getChildNodes(); 1238 for (int i = 0; i < nodes.getLength(); i++) { 1239 Node n = nodes.item(i); 1240 if (n instanceof Element && n.getNodeName().equals("MapEntry")) { 1241 Element elem = (Element) n; 1242 currentElem = elem; 1243 Savable key = readSavable(XMLExporter.ELEMENT_KEY, null); 1244 Savable val = readSavable(XMLExporter.ELEMENT_VALUE, null); 1245 ret.put(key, val); 1246 } 1247 } 1248 currentElem = (Element) tempEl.getParentNode(); 1249 return ret; 1250 } 1251 1252 public Map<String, ? extends Savable> readStringSavableMap(String name, Map<String, ? extends Savable> defVal) throws IOException { 1253 Map<String, Savable> ret = null; 1254 Element tempEl; 1255 1256 if (name != null) { 1257 tempEl = findChildElement(currentElem, name); 1258 } else { 1259 tempEl = currentElem; 1260 } 1261 if (tempEl != null) { 1262 ret = new HashMap<String, Savable>(); 1263 1264 NodeList nodes = tempEl.getChildNodes(); 1265 for (int i = 0; i < nodes.getLength(); i++) { 1266 Node n = nodes.item(i); 1267 if (n instanceof Element && n.getNodeName().equals("MapEntry")) { 1268 Element elem = (Element) n; 1269 currentElem = elem; 1270 String key = currentElem.getAttribute("key"); 1271 Savable val = readSavable("Savable", null); 1272 ret.put(key, val); 1273 } 1274 } 1275 } else { 1276 return defVal; 1277 } 1278 currentElem = (Element) tempEl.getParentNode(); 1279 return ret; 1280 } 1281 1282 public IntMap<? extends Savable> readIntSavableMap(String name, IntMap<? extends Savable> defVal) throws IOException { 1283 IntMap<Savable> ret = null; 1284 Element tempEl; 1285 1286 if (name != null) { 1287 tempEl = findChildElement(currentElem, name); 1288 } else { 1289 tempEl = currentElem; 1290 } 1291 if (tempEl != null) { 1292 ret = new IntMap<Savable>(); 1293 1294 NodeList nodes = tempEl.getChildNodes(); 1295 for (int i = 0; i < nodes.getLength(); i++) { 1296 Node n = nodes.item(i); 1297 if (n instanceof Element && n.getNodeName().equals("MapEntry")) { 1298 Element elem = (Element) n; 1299 currentElem = elem; 1300 int key = Integer.parseInt(currentElem.getAttribute("key")); 1301 Savable val = readSavable("Savable", null); 1302 ret.put(key, val); 1303 } 1304 } 1305 } else { 1306 return defVal; 1307 } 1308 currentElem = (Element) tempEl.getParentNode(); 1309 return ret; 1310 } 1311 1312 /** 1313 * reads from currentElem if name is null 1314 */ 1315 public FloatBuffer readFloatBuffer(String name, FloatBuffer defVal) throws IOException { 1316 try { 1317 Element tmpEl; 1318 if (name != null) { 1319 tmpEl = findChildElement(currentElem, name); 1320 } else { 1321 tmpEl = currentElem; 1322 } 1323 if (tmpEl == null) { 1324 return defVal; 1325 } 1326 String sizeString = tmpEl.getAttribute("size"); 1327 String[] strings = parseTokens(tmpEl.getAttribute("data")); 1328 if (sizeString.length() > 0) { 1329 int requiredSize = Integer.parseInt(sizeString); 1330 if (strings.length != requiredSize) 1331 throw new IOException("Wrong number of float buffers for '" 1332 + name + "'. size says " + requiredSize 1333 + ", data contains " + strings.length); 1334 } 1335 FloatBuffer tmp = BufferUtils.createFloatBuffer(strings.length); 1336 for (String s : strings) tmp.put(Float.parseFloat(s)); 1337 tmp.flip(); 1338 return tmp; 1339 } catch (IOException ioe) { 1340 throw ioe; 1341 } catch (NumberFormatException nfe) { 1342 IOException io = new IOException(nfe.toString()); 1343 io.initCause(nfe); 1344 throw io; 1345 } catch (DOMException de) { 1346 IOException io = new IOException(de.toString()); 1347 io.initCause(de); 1348 throw io; 1349 } 1350 } 1351 1352 public IntBuffer readIntBuffer(String name, IntBuffer defVal) throws IOException { 1353 try { 1354 Element tmpEl = findChildElement(currentElem, name); 1355 if (tmpEl == null) { 1356 return defVal; 1357 } 1358 1359 String sizeString = tmpEl.getAttribute("size"); 1360 String[] strings = parseTokens(tmpEl.getAttribute("data")); 1361 if (sizeString.length() > 0) { 1362 int requiredSize = Integer.parseInt(sizeString); 1363 if (strings.length != requiredSize) 1364 throw new IOException("Wrong number of int buffers for '" 1365 + name + "'. size says " + requiredSize 1366 + ", data contains " + strings.length); 1367 } 1368 IntBuffer tmp = BufferUtils.createIntBuffer(strings.length); 1369 for (String s : strings) tmp.put(Integer.parseInt(s)); 1370 tmp.flip(); 1371 return tmp; 1372 } catch (IOException ioe) { 1373 throw ioe; 1374 } catch (NumberFormatException nfe) { 1375 IOException io = new IOException(nfe.toString()); 1376 io.initCause(nfe); 1377 throw io; 1378 } catch (DOMException de) { 1379 IOException io = new IOException(de.toString()); 1380 io.initCause(de); 1381 throw io; 1382 } 1383 } 1384 1385 public ByteBuffer readByteBuffer(String name, ByteBuffer defVal) throws IOException { 1386 try { 1387 Element tmpEl = findChildElement(currentElem, name); 1388 if (tmpEl == null) { 1389 return defVal; 1390 } 1391 1392 String sizeString = tmpEl.getAttribute("size"); 1393 String[] strings = parseTokens(tmpEl.getAttribute("data")); 1394 if (sizeString.length() > 0) { 1395 int requiredSize = Integer.parseInt(sizeString); 1396 if (strings.length != requiredSize) 1397 throw new IOException("Wrong number of byte buffers for '" 1398 + name + "'. size says " + requiredSize 1399 + ", data contains " + strings.length); 1400 } 1401 ByteBuffer tmp = BufferUtils.createByteBuffer(strings.length); 1402 for (String s : strings) tmp.put(Byte.valueOf(s)); 1403 tmp.flip(); 1404 return tmp; 1405 } catch (IOException ioe) { 1406 throw ioe; 1407 } catch (NumberFormatException nfe) { 1408 IOException io = new IOException(nfe.toString()); 1409 io.initCause(nfe); 1410 throw io; 1411 } catch (DOMException de) { 1412 IOException io = new IOException(de.toString()); 1413 io.initCause(de); 1414 throw io; 1415 } 1416 } 1417 1418 public ShortBuffer readShortBuffer(String name, ShortBuffer defVal) throws IOException { 1419 try { 1420 Element tmpEl = findChildElement(currentElem, name); 1421 if (tmpEl == null) { 1422 return defVal; 1423 } 1424 1425 String sizeString = tmpEl.getAttribute("size"); 1426 String[] strings = parseTokens(tmpEl.getAttribute("data")); 1427 if (sizeString.length() > 0) { 1428 int requiredSize = Integer.parseInt(sizeString); 1429 if (strings.length != requiredSize) 1430 throw new IOException("Wrong number of short buffers for '" 1431 + name + "'. size says " + requiredSize 1432 + ", data contains " + strings.length); 1433 } 1434 ShortBuffer tmp = BufferUtils.createShortBuffer(strings.length); 1435 for (String s : strings) tmp.put(Short.valueOf(s)); 1436 tmp.flip(); 1437 return tmp; 1438 } catch (IOException ioe) { 1439 throw ioe; 1440 } catch (NumberFormatException nfe) { 1441 IOException io = new IOException(nfe.toString()); 1442 io.initCause(nfe); 1443 throw io; 1444 } catch (DOMException de) { 1445 IOException io = new IOException(de.toString()); 1446 io.initCause(de); 1447 throw io; 1448 } 1449 } 1450 1451 public ArrayList<ByteBuffer> readByteBufferArrayList(String name, ArrayList<ByteBuffer> defVal) throws IOException { 1452 try { 1453 Element tmpEl = findChildElement(currentElem, name); 1454 if (tmpEl == null) { 1455 return defVal; 1456 } 1457 1458 String sizeString = tmpEl.getAttribute("size"); 1459 ArrayList<ByteBuffer> tmp = new ArrayList<ByteBuffer>(); 1460 for (currentElem = findFirstChildElement(tmpEl); 1461 currentElem != null; 1462 currentElem = findNextSiblingElement(currentElem)) { 1463 tmp.add(readByteBuffer(null, null)); 1464 } 1465 if (sizeString.length() > 0) { 1466 int requiredSize = Integer.parseInt(sizeString); 1467 if (tmp.size() != requiredSize) 1468 throw new IOException("Wrong number of short buffers for '" 1469 + name + "'. size says " + requiredSize 1470 + ", data contains " + tmp.size()); 1471 } 1472 currentElem = (Element) tmpEl.getParentNode(); 1473 return tmp; 1474 } catch (IOException ioe) { 1475 throw ioe; 1476 } catch (NumberFormatException nfe) { 1477 IOException io = new IOException(nfe.toString()); 1478 io.initCause(nfe); 1479 throw io; 1480 } catch (DOMException de) { 1481 IOException io = new IOException(de.toString()); 1482 io.initCause(de); 1483 throw io; 1484 } 1485 } 1486 1487 public <T extends Enum<T>> T readEnum(String name, Class<T> enumType, 1488 T defVal) throws IOException { 1489 T ret = defVal; 1490 try { 1491 String eVal = currentElem.getAttribute(name); 1492 if (eVal != null && eVal.length() > 0) { 1493 ret = Enum.valueOf(enumType, eVal); 1494 } 1495 } catch (Exception e) { 1496 IOException io = new IOException(e.toString()); 1497 io.initCause(e); 1498 throw io; 1499 } 1500 return ret; 1501 } 1502 1503 private static final String[] zeroStrings = new String[0]; 1504 1505 protected String[] parseTokens(String inString) { 1506 String[] outStrings = inString.split("\\s+"); 1507 return (outStrings.length == 1 && outStrings[0].length() == 0) 1508 ? zeroStrings 1509 : outStrings; 1510 } 1511 }