• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DOMInputCapsule(Document doc, XMLImporter importer)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 
getSavableVersion(Class<? extends Savable> desiredClass)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 
decodeString(String s)87     private static String decodeString(String s) {
88         if (s == null) {
89             return null;
90         }
91         s = s.replaceAll("\\&quot;", "\"").replaceAll("\\&lt;", "<").replaceAll("\\&amp;", "&");
92         return s;
93     }
94 
findFirstChildElement(Element parent)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 
findChildElement(Element parent, String name)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 
findNextSiblingElement(Element current)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 
readByte(String name, byte defVal)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 
readByteArray(String name, byte[] defVal)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 
readByteArray2D(String name, byte[][] defVal)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 
readInt(String name, int defVal)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 
readIntArray(String name, int[] defVal)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 
readIntArray2D(String name, int[][] defVal)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 
readFloat(String name, float defVal)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 
readFloatArray(String name, float[] defVal)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 
readFloatArray2D(String name, float[][] defVal)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 
readDouble(String name, double defVal)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 
readDoubleArray(String name, double[] defVal)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 
readDoubleArray2D(String name, double[][] defVal)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 
readLong(String name, long defVal)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 
readLongArray(String name, long[] defVal)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 
readLongArray2D(String name, long[][] defVal)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 
readShort(String name, short defVal)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 
readShortArray(String name, short[] defVal)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 
readShortArray2D(String name, short[][] defVal)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 
readBoolean(String name, boolean defVal)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 
readBooleanArray(String name, boolean[] defVal)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 
readBooleanArray2D(String name, boolean[][] defVal)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 
readString(String name, String defVal)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 
readStringArray(String name, String[] defVal)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 
readStringArray2D(String name, String[][] defVal)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 
readBitSet(String name, BitSet defVal)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 
readSavable(String name, Savable defVal)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 
readSavableFromCurrentElem(Savable defVal)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 
readSavableArray(String name, Savable[] defVal)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 
readSavableArray2D(String name, Savable[][] defVal)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 
readSavableArrayList(String name, ArrayList defVal)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 
readSavableArrayListArray( String name, ArrayList[] defVal)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 
readSavableArrayListArray2D(String name, ArrayList[][] defVal)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 
readFloatBufferArrayList( String name, ArrayList<FloatBuffer> defVal)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 
readSavableMap(String name, Map<? extends Savable, ? extends Savable> defVal)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 
readStringSavableMap(String name, Map<String, ? extends Savable> defVal)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 
readIntSavableMap(String name, IntMap<? extends Savable> defVal)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      */
readFloatBuffer(String name, FloatBuffer defVal)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 
readIntBuffer(String name, IntBuffer defVal)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 
readByteBuffer(String name, ByteBuffer defVal)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 
readShortBuffer(String name, ShortBuffer defVal)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 
readByteBufferArrayList(String name, ArrayList<ByteBuffer> defVal)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 
readEnum(String name, Class<T> enumType, T defVal)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 
parseTokens(String inString)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 }