• 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.FormatVersion;
36 import com.jme3.export.JmeExporter;
37 import com.jme3.export.OutputCapsule;
38 import com.jme3.export.Savable;
39 import com.jme3.export.SavableClassUtil;
40 import com.jme3.util.IntMap;
41 import com.jme3.util.IntMap.Entry;
42 import java.io.IOException;
43 import java.nio.ByteBuffer;
44 import java.nio.FloatBuffer;
45 import java.nio.IntBuffer;
46 import java.nio.ShortBuffer;
47 import java.util.*;
48 import org.w3c.dom.DOMException;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51 
52 /**
53  * Part of the jME XML IO system as introduced in the google code jmexml project.
54  *
55  * @author Kai Rabien (hevee) - original author of the code.google.com jmexml project
56  * @author Doug Daniels (dougnukem) - adjustments for jME 2.0 and Java 1.5
57  */
58 public class DOMOutputCapsule implements OutputCapsule {
59 
60     private static final String dataAttributeName = "data";
61     private Document doc;
62     private Element currentElement;
63     private JmeExporter exporter;
64     private Map<Savable, Element> writtenSavables = new IdentityHashMap<Savable, Element>();
65 
DOMOutputCapsule(Document doc, JmeExporter exporter)66     public DOMOutputCapsule(Document doc, JmeExporter exporter) {
67         this.doc = doc;
68         this.exporter = exporter;
69         currentElement = null;
70     }
71 
getDoc()72     public Document getDoc() {
73         return doc;
74     }
75 
76     /**
77      * appends a new Element with the given name to currentElement, sets
78      * currentElement to be new Element, and returns the new Element as well
79      */
appendElement(String name)80     private Element appendElement(String name) {
81         Element ret = doc.createElement(name);
82         if (currentElement == null) {
83             ret.setAttribute("format_version", Integer.toString(FormatVersion.VERSION));
84             doc.appendChild(ret);
85         } else {
86             currentElement.appendChild(ret);
87         }
88         currentElement = ret;
89         return ret;
90     }
91 
encodeString(String s)92     private static String encodeString(String s) {
93         if (s == null) {
94             return null;
95         }
96         s =     s.replaceAll("\\&", "&amp;")
97                  .replaceAll("\\\"", "&quot;")
98                  .replaceAll("\\<", "&lt;");
99         return s;
100     }
101 
write(byte value, String name, byte defVal)102     public void write(byte value, String name, byte defVal) throws IOException {
103         if (value == defVal) {
104             return;
105         }
106         currentElement.setAttribute(name, String.valueOf(value));
107     }
108 
write(byte[] value, String name, byte[] defVal)109     public void write(byte[] value, String name, byte[] defVal) throws IOException {
110         StringBuilder buf = new StringBuilder();
111         if (value == null) {
112             value = defVal;
113         }
114         for (byte b : value) {
115             buf.append(b);
116             buf.append(" ");
117         }
118         //remove last space
119         buf.setLength(buf.length() - 1);
120 
121         Element el = appendElement(name);
122         el.setAttribute("size", String.valueOf(value.length));
123         el.setAttribute(dataAttributeName, buf.toString());
124         currentElement = (Element) currentElement.getParentNode();
125     }
126 
write(byte[][] value, String name, byte[][] defVal)127     public void write(byte[][] value, String name, byte[][] defVal) throws IOException {
128         StringBuilder buf = new StringBuilder();
129         if (value == null) {
130             value = defVal;
131         }
132         for (byte[] bs : value) {
133             for (byte b : bs) {
134                 buf.append(b);
135                 buf.append(" ");
136             }
137             buf.append(" ");
138         }
139         //remove last spaces
140         buf.setLength(buf.length() - 2);
141 
142         Element el = appendElement(name);
143         el.setAttribute("size_outer", String.valueOf(value.length));
144         el.setAttribute("size_inner", String.valueOf(value[0].length));
145         el.setAttribute(dataAttributeName, buf.toString());
146         currentElement = (Element) currentElement.getParentNode();
147     }
148 
write(int value, String name, int defVal)149     public void write(int value, String name, int defVal) throws IOException {
150         if (value == defVal) {
151             return;
152         }
153         currentElement.setAttribute(name, String.valueOf(value));
154     }
155 
write(int[] value, String name, int[] defVal)156     public void write(int[] value, String name, int[] defVal) throws IOException {
157         StringBuilder buf = new StringBuilder();
158         if (value == null) { return; }
159         if (Arrays.equals(value, defVal)) { return; }
160 
161         for (int b : value) {
162             buf.append(b);
163             buf.append(" ");
164         }
165         //remove last space
166         buf.setLength(Math.max(0, buf.length() - 1));
167 
168         Element el = appendElement(name);
169         el.setAttribute("size", String.valueOf(value.length));
170         el.setAttribute(dataAttributeName, buf.toString());
171         currentElement = (Element) currentElement.getParentNode();
172     }
173 
write(int[][] value, String name, int[][] defVal)174     public void write(int[][] value, String name, int[][] defVal) throws IOException {
175         if (value == null) return;
176         if(Arrays.deepEquals(value, defVal)) return;
177 
178         Element el = appendElement(name);
179         el.setAttribute("size", String.valueOf(value.length));
180 
181         for (int i=0; i<value.length; i++) {
182                 int[] array = value[i];
183                 write(array, "array_"+i, defVal==null?null:defVal[i]);
184         }
185         currentElement = (Element) el.getParentNode();
186     }
187 
write(float value, String name, float defVal)188     public void write(float value, String name, float defVal) throws IOException {
189         if (value == defVal) {
190             return;
191         }
192         currentElement.setAttribute(name, String.valueOf(value));
193     }
194 
write(float[] value, String name, float[] defVal)195     public void write(float[] value, String name, float[] defVal) throws IOException {
196         StringBuilder buf = new StringBuilder();
197         if (value == null) {
198             value = defVal;
199         }
200         if (value != null) {
201             for (float b : value) {
202                 buf.append(b);
203                 buf.append(" ");
204             }
205             //remove last space
206             buf.setLength(buf.length() - 1);
207         }
208 
209         Element el = appendElement(name);
210         el.setAttribute("size", value == null ? "0" : String.valueOf(value.length));
211         el.setAttribute(dataAttributeName, buf.toString());
212         currentElement = (Element) currentElement.getParentNode();
213     }
214 
write(float[][] value, String name, float[][] defVal)215     public void write(float[][] value, String name, float[][] defVal) throws IOException {
216         StringBuilder buf = new StringBuilder();
217         if (value == null) return;
218         if(Arrays.deepEquals(value, defVal)) return;
219 
220         for (float[] bs : value) {
221             for(float b : bs){
222                 buf.append(b);
223                 buf.append(" ");
224             }
225         }
226         //remove last space
227         buf.setLength(buf.length() - 1);
228 
229         Element el = appendElement(name);
230         el.setAttribute("size_outer", String.valueOf(value.length));
231         el.setAttribute("size_inner", String.valueOf(value[0].length));
232         el.setAttribute(dataAttributeName, buf.toString());
233         currentElement = (Element) currentElement.getParentNode();
234     }
235 
write(double value, String name, double defVal)236     public void write(double value, String name, double defVal) throws IOException {
237         if (value == defVal) {
238             return;
239         }
240         currentElement.setAttribute(name, String.valueOf(value));
241     }
242 
write(double[] value, String name, double[] defVal)243     public void write(double[] value, String name, double[] defVal) throws IOException {
244         StringBuilder buf = new StringBuilder();
245         if (value == null) {
246             value = defVal;
247         }
248         for (double b : value) {
249             buf.append(b);
250             buf.append(" ");
251         }
252         //remove last space
253         buf.setLength(buf.length() - 1);
254 
255         Element el = appendElement(name);
256         el.setAttribute("size", String.valueOf(value.length));
257         el.setAttribute(dataAttributeName, buf.toString());
258         currentElement = (Element) currentElement.getParentNode();
259     }
260 
write(double[][] value, String name, double[][] defVal)261     public void write(double[][] value, String name, double[][] defVal) throws IOException {
262             if (value == null) return;
263             if(Arrays.deepEquals(value, defVal)) return;
264 
265             Element el = appendElement(name);
266             el.setAttribute("size", String.valueOf(value.length));
267 
268             for (int i=0; i<value.length; i++) {
269                 double[] array = value[i];
270                 write(array, "array_"+i, defVal==null?null:defVal[i]);
271             }
272             currentElement = (Element) el.getParentNode();
273     }
274 
write(long value, String name, long defVal)275     public void write(long value, String name, long defVal) throws IOException {
276         if (value == defVal) {
277             return;
278         }
279         currentElement.setAttribute(name, String.valueOf(value));
280     }
281 
write(long[] value, String name, long[] defVal)282     public void write(long[] value, String name, long[] defVal) throws IOException {
283         StringBuilder buf = new StringBuilder();
284         if (value == null) {
285             value = defVal;
286         }
287         for (long b : value) {
288             buf.append(b);
289             buf.append(" ");
290         }
291         //remove last space
292         buf.setLength(buf.length() - 1);
293 
294         Element el = appendElement(name);
295         el.setAttribute("size", String.valueOf(value.length));
296         el.setAttribute(dataAttributeName, buf.toString());
297         currentElement = (Element) currentElement.getParentNode();
298     }
299 
write(long[][] value, String name, long[][] defVal)300     public void write(long[][] value, String name, long[][] defVal) throws IOException {
301         if (value == null) return;
302         if(Arrays.deepEquals(value, defVal)) return;
303 
304         Element el = appendElement(name);
305         el.setAttribute("size", String.valueOf(value.length));
306 
307         for (int i=0; i<value.length; i++) {
308                 long[] array = value[i];
309                 write(array, "array_"+i, defVal==null?null:defVal[i]);
310         }
311         currentElement = (Element) el.getParentNode();
312     }
313 
write(short value, String name, short defVal)314     public void write(short value, String name, short defVal) throws IOException {
315         if (value == defVal) {
316             return;
317         }
318         currentElement.setAttribute(name, String.valueOf(value));
319     }
320 
write(short[] value, String name, short[] defVal)321     public void write(short[] value, String name, short[] defVal) throws IOException {
322         StringBuilder buf = new StringBuilder();
323         if (value == null) {
324             value = defVal;
325         }
326         for (short b : value) {
327             buf.append(b);
328             buf.append(" ");
329         }
330         //remove last space
331         buf.setLength(buf.length() - 1);
332 
333         Element el = appendElement(name);
334         el.setAttribute("size", String.valueOf(value.length));
335         el.setAttribute(dataAttributeName, buf.toString());
336         currentElement = (Element) currentElement.getParentNode();
337     }
338 
write(short[][] value, String name, short[][] defVal)339     public void write(short[][] value, String name, short[][] defVal) throws IOException {
340         if (value == null) return;
341         if(Arrays.deepEquals(value, defVal)) return;
342 
343         Element el = appendElement(name);
344         el.setAttribute("size", String.valueOf(value.length));
345 
346         for (int i=0; i<value.length; i++) {
347                 short[] array = value[i];
348                 write(array, "array_"+i, defVal==null?null:defVal[i]);
349         }
350         currentElement = (Element) el.getParentNode();
351     }
352 
write(boolean value, String name, boolean defVal)353     public void write(boolean value, String name, boolean defVal) throws IOException {
354         if (value == defVal) {
355             return;
356         }
357         currentElement.setAttribute(name, String.valueOf(value));
358     }
359 
write(boolean[] value, String name, boolean[] defVal)360     public void write(boolean[] value, String name, boolean[] defVal) throws IOException {
361         StringBuilder buf = new StringBuilder();
362         if (value == null) {
363             value = defVal;
364         }
365         for (boolean b : value) {
366             buf.append(b);
367             buf.append(" ");
368         }
369         //remove last space
370         buf.setLength(Math.max(0, buf.length() - 1));
371 
372         Element el = appendElement(name);
373         el.setAttribute("size", String.valueOf(value.length));
374         el.setAttribute(dataAttributeName, buf.toString());
375         currentElement = (Element) currentElement.getParentNode();
376     }
377 
write(boolean[][] value, String name, boolean[][] defVal)378     public void write(boolean[][] value, String name, boolean[][] defVal) throws IOException {
379         if (value == null) return;
380         if(Arrays.deepEquals(value, defVal)) return;
381 
382         Element el = appendElement(name);
383         el.setAttribute("size", String.valueOf(value.length));
384 
385         for (int i=0; i<value.length; i++) {
386                 boolean[] array = value[i];
387                 write(array, "array_"+i, defVal==null?null:defVal[i]);
388         }
389         currentElement = (Element) el.getParentNode();
390     }
391 
write(String value, String name, String defVal)392     public void write(String value, String name, String defVal) throws IOException {
393         if (value == null || value.equals(defVal)) {
394             return;
395         }
396         currentElement.setAttribute(name, encodeString(value));
397     }
398 
write(String[] value, String name, String[] defVal)399     public void write(String[] value, String name, String[] defVal) throws IOException {
400         Element el = appendElement(name);
401 
402         if (value == null) {
403             value = defVal;
404         }
405 
406         el.setAttribute("size", String.valueOf(value.length));
407 
408         for (int i=0; i<value.length; i++) {
409                 String b = value[i];
410                 appendElement("String_"+i);
411             String val = encodeString(b);
412             currentElement.setAttribute("value", val);
413             currentElement = el;
414         }
415         currentElement = (Element) currentElement.getParentNode();
416     }
417 
write(String[][] value, String name, String[][] defVal)418     public void write(String[][] value, String name, String[][] defVal) throws IOException {
419         if (value == null) return;
420         if(Arrays.deepEquals(value, defVal)) return;
421 
422         Element el = appendElement(name);
423         el.setAttribute("size", String.valueOf(value.length));
424 
425         for (int i=0; i<value.length; i++) {
426                 String[] array = value[i];
427                 write(array, "array_"+i, defVal==null?null:defVal[i]);
428         }
429         currentElement = (Element) el.getParentNode();
430     }
431 
write(BitSet value, String name, BitSet defVal)432     public void write(BitSet value, String name, BitSet defVal) throws IOException {
433         if (value == null || value.equals(defVal)) {
434             return;
435         }
436         StringBuilder buf = new StringBuilder();
437         for (int i = value.nextSetBit(0); i >= 0; i = value.nextSetBit(i + 1)) {
438             buf.append(i);
439             buf.append(" ");
440         }
441         buf.setLength(Math.max(0, buf.length() - 1));
442         currentElement.setAttribute(name, buf.toString());
443 
444     }
445 
write(Savable object, String name, Savable defVal)446     public void write(Savable object, String name, Savable defVal) throws IOException {
447         if (object == null) {
448             return;
449         }
450         if (object.equals(defVal)) {
451             return;
452         }
453 
454         Element old = currentElement;
455         Element el = writtenSavables.get(object);
456 
457         String className = null;
458         if(!object.getClass().getName().equals(name)){
459             className = object.getClass().getName();
460         }
461         try {
462             doc.createElement(name);
463         } catch (DOMException e) {
464             // Ridiculous fallback behavior.
465             // Would be far better to throw than to totally disregard the
466             // specified "name" and write a class name instead!
467             // (Besides the fact we are clobbering the managed .getClassTag()).
468             name = "Object";
469             className = object.getClass().getName();
470         }
471 
472         if (el != null) {
473             String refID = el.getAttribute("reference_ID");
474             if (refID.length() == 0) {
475                 refID = object.getClass().getName() + "@" + object.hashCode();
476                 el.setAttribute("reference_ID", refID);
477             }
478             el = appendElement(name);
479             el.setAttribute("ref", refID);
480         } else {
481             el = appendElement(name);
482 
483             // jME3 NEW: Append version number(s)
484             int[] versions = SavableClassUtil.getSavableVersions(object.getClass());
485             StringBuilder sb = new StringBuilder();
486             for (int i = 0; i < versions.length; i++){
487                 sb.append(versions[i]);
488                 if (i != versions.length - 1){
489                     sb.append(", ");
490                 }
491             }
492             el.setAttribute("savable_versions", sb.toString());
493 
494             writtenSavables.put(object, el);
495             object.write(exporter);
496         }
497         if(className != null){
498             el.setAttribute("class", className);
499         }
500 
501         currentElement = old;
502     }
503 
write(Savable[] objects, String name, Savable[] defVal)504     public void write(Savable[] objects, String name, Savable[] defVal) throws IOException {
505         if (objects == null) {
506             return;
507         }
508         if (Arrays.equals(objects, defVal)) {
509             return;
510         }
511 
512         Element old = currentElement;
513         Element el = appendElement(name);
514         el.setAttribute("size", String.valueOf(objects.length));
515         for (int i = 0; i < objects.length; i++) {
516             Savable o = objects[i];
517             if(o == null){
518                 //renderStateList has special loading code, so we can leave out the null values
519                 if(!name.equals("renderStateList")){
520                 Element before = currentElement;
521                 appendElement("null");
522                 currentElement = before;
523                 }
524             }else{
525                 write(o, o.getClass().getName(), null);
526             }
527         }
528         currentElement = old;
529     }
530 
write(Savable[][] value, String name, Savable[][] defVal)531     public void write(Savable[][] value, String name, Savable[][] defVal) throws IOException {
532         if (value == null) return;
533         if(Arrays.deepEquals(value, defVal)) return;
534 
535         Element el = appendElement(name);
536         el.setAttribute("size_outer", String.valueOf(value.length));
537         el.setAttribute("size_inner", String.valueOf(value[0].length));
538         for (Savable[] bs : value) {
539             for(Savable b : bs){
540                 write(b, b.getClass().getSimpleName(), null);
541             }
542         }
543         currentElement = (Element) currentElement.getParentNode();
544     }
545 
writeSavableArrayList(ArrayList array, String name, ArrayList defVal)546     public void writeSavableArrayList(ArrayList array, String name, ArrayList defVal) throws IOException {
547         if (array == null) {
548             return;
549         }
550         if (array.equals(defVal)) {
551             return;
552         }
553         Element old = currentElement;
554         Element el = appendElement(name);
555         currentElement = el;
556         el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(array.size()));
557         for (Object o : array) {
558                 if(o == null) {
559                         continue;
560                 }
561                 else if (o instanceof Savable) {
562                 Savable s = (Savable) o;
563                 write(s, s.getClass().getName(), null);
564             } else {
565                 throw new ClassCastException("Not a Savable instance: " + o);
566             }
567         }
568         currentElement = old;
569     }
570 
writeSavableArrayListArray(ArrayList[] objects, String name, ArrayList[] defVal)571     public void writeSavableArrayListArray(ArrayList[] objects, String name, ArrayList[] defVal) throws IOException {
572         if (objects == null) {return;}
573         if (Arrays.equals(objects, defVal)) {return;}
574 
575         Element old = currentElement;
576         Element el = appendElement(name);
577         el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(objects.length));
578         for (int i = 0; i < objects.length; i++) {
579             ArrayList o = objects[i];
580             if(o == null){
581                 Element before = currentElement;
582                 appendElement("null");
583                 currentElement = before;
584             }else{
585                 StringBuilder buf = new StringBuilder("SavableArrayList_");
586                 buf.append(i);
587                 writeSavableArrayList(o, buf.toString(), null);
588             }
589         }
590         currentElement = old;
591     }
592 
writeSavableArrayListArray2D(ArrayList[][] value, String name, ArrayList[][] defVal)593     public void writeSavableArrayListArray2D(ArrayList[][] value, String name, ArrayList[][] defVal) throws IOException {
594         if (value == null) return;
595         if(Arrays.deepEquals(value, defVal)) return;
596 
597         Element el = appendElement(name);
598         int size = value.length;
599         el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(size));
600 
601         for (int i=0; i< size; i++) {
602             ArrayList[] vi = value[i];
603             writeSavableArrayListArray(vi, "SavableArrayListArray_"+i, null);
604         }
605         currentElement = (Element) el.getParentNode();
606     }
607 
writeFloatBufferArrayList(ArrayList<FloatBuffer> array, String name, ArrayList<FloatBuffer> defVal)608     public void writeFloatBufferArrayList(ArrayList<FloatBuffer> array, String name, ArrayList<FloatBuffer> defVal) throws IOException {
609         if (array == null) {
610             return;
611         }
612         if (array.equals(defVal)) {
613             return;
614         }
615         Element el = appendElement(name);
616         el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(array.size()));
617         for (FloatBuffer o : array) {
618             write(o, XMLExporter.ELEMENT_FLOATBUFFER, null);
619         }
620         currentElement = (Element) el.getParentNode();
621     }
622 
writeSavableMap(Map<? extends Savable, ? extends Savable> map, String name, Map<? extends Savable, ? extends Savable> defVal)623     public void writeSavableMap(Map<? extends Savable, ? extends Savable> map, String name, Map<? extends Savable, ? extends Savable> defVal) throws IOException {
624         if (map == null) {
625             return;
626         }
627         if (map.equals(defVal)) {
628             return;
629         }
630                 Element stringMap = appendElement(name);
631 
632                 Iterator<? extends Savable> keyIterator = map.keySet().iterator();
633                 while(keyIterator.hasNext()) {
634                         Savable key = keyIterator.next();
635                         Element mapEntry = appendElement(XMLExporter.ELEMENT_MAPENTRY);
636                         write(key, XMLExporter.ELEMENT_KEY, null);
637                         Savable value = map.get(key);
638                         write(value, XMLExporter.ELEMENT_VALUE, null);
639                         currentElement = stringMap;
640                 }
641 
642                 currentElement = (Element) stringMap.getParentNode();
643     }
644 
writeStringSavableMap(Map<String, ? extends Savable> map, String name, Map<String, ? extends Savable> defVal)645     public void writeStringSavableMap(Map<String, ? extends Savable> map, String name, Map<String, ? extends Savable> defVal) throws IOException {
646         if (map == null) {
647             return;
648         }
649         if (map.equals(defVal)) {
650             return;
651         }
652                 Element stringMap = appendElement(name);
653 
654                 Iterator<String> keyIterator = map.keySet().iterator();
655                 while(keyIterator.hasNext()) {
656                         String key = keyIterator.next();
657                         Element mapEntry = appendElement("MapEntry");
658                         mapEntry.setAttribute("key", key);
659                         Savable s = map.get(key);
660                         write(s, "Savable", null);
661                         currentElement = stringMap;
662                 }
663 
664                 currentElement = (Element) stringMap.getParentNode();
665     }
666 
writeIntSavableMap(IntMap<? extends Savable> map, String name, IntMap<? extends Savable> defVal)667     public void writeIntSavableMap(IntMap<? extends Savable> map, String name, IntMap<? extends Savable> defVal) throws IOException {
668         if (map == null) {
669             return;
670         }
671         if (map.equals(defVal)) {
672             return;
673         }
674                 Element stringMap = appendElement(name);
675 
676                 for(Entry<? extends Savable> entry : map) {
677                         int key = entry.getKey();
678                         Element mapEntry = appendElement("MapEntry");
679                         mapEntry.setAttribute("key", Integer.toString(key));
680                         Savable s = entry.getValue();
681                         write(s, "Savable", null);
682                         currentElement = stringMap;
683                 }
684 
685                 currentElement = (Element) stringMap.getParentNode();
686     }
687 
write(FloatBuffer value, String name, FloatBuffer defVal)688     public void write(FloatBuffer value, String name, FloatBuffer defVal) throws IOException {
689         if (value == null) {
690             return;
691         }
692 
693         Element el = appendElement(name);
694         el.setAttribute("size", String.valueOf(value.limit()));
695         StringBuilder buf = new StringBuilder();
696         int pos = value.position();
697         value.rewind();
698         int ctr = 0;
699         while (value.hasRemaining()) {
700             ctr++;
701             buf.append(value.get());
702             buf.append(" ");
703         }
704         if (ctr != value.limit())
705             throw new IOException("'" + name
706                 + "' buffer contention resulted in write data consistency.  "
707                 + ctr + " values written when should have written "
708                 + value.limit());
709         buf.setLength(Math.max(0, buf.length() - 1));
710         value.position(pos);
711         el.setAttribute(dataAttributeName, buf.toString());
712         currentElement = (Element) el.getParentNode();
713     }
714 
write(IntBuffer value, String name, IntBuffer defVal)715     public void write(IntBuffer value, String name, IntBuffer defVal) throws IOException {
716         if (value == null) {
717             return;
718         }
719         if (value.equals(defVal)) {
720             return;
721         }
722 
723         Element el = appendElement(name);
724         el.setAttribute("size", String.valueOf(value.limit()));
725         StringBuilder buf = new StringBuilder();
726         int pos = value.position();
727         value.rewind();
728         int ctr = 0;
729         while (value.hasRemaining()) {
730             ctr++;
731             buf.append(value.get());
732             buf.append(" ");
733         }
734         if (ctr != value.limit())
735             throw new IOException("'" + name
736                 + "' buffer contention resulted in write data consistency.  "
737                 + ctr + " values written when should have written "
738                 + value.limit());
739         buf.setLength(buf.length() - 1);
740         value.position(pos);
741         el.setAttribute(dataAttributeName, buf.toString());
742         currentElement = (Element) el.getParentNode();
743     }
744 
write(ByteBuffer value, String name, ByteBuffer defVal)745     public void write(ByteBuffer value, String name, ByteBuffer defVal) throws IOException {
746         if (value == null) return;
747         if (value.equals(defVal)) return;
748 
749         Element el = appendElement(name);
750         el.setAttribute("size", String.valueOf(value.limit()));
751         StringBuilder buf = new StringBuilder();
752         int pos = value.position();
753         value.rewind();
754         int ctr = 0;
755         while (value.hasRemaining()) {
756             ctr++;
757             buf.append(value.get());
758             buf.append(" ");
759         }
760         if (ctr != value.limit())
761             throw new IOException("'" + name
762                 + "' buffer contention resulted in write data consistency.  "
763                 + ctr + " values written when should have written "
764                 + value.limit());
765         buf.setLength(buf.length() - 1);
766         value.position(pos);
767         el.setAttribute(dataAttributeName, buf.toString());
768         currentElement = (Element) el.getParentNode();
769     }
770 
write(ShortBuffer value, String name, ShortBuffer defVal)771     public void write(ShortBuffer value, String name, ShortBuffer defVal) throws IOException {
772         if (value == null) {
773             return;
774         }
775         if (value.equals(defVal)) {
776             return;
777         }
778 
779         Element el = appendElement(name);
780         el.setAttribute("size", String.valueOf(value.limit()));
781         StringBuilder buf = new StringBuilder();
782         int pos = value.position();
783         value.rewind();
784         int ctr = 0;
785         while (value.hasRemaining()) {
786             ctr++;
787             buf.append(value.get());
788             buf.append(" ");
789         }
790         if (ctr != value.limit())
791             throw new IOException("'" + name
792                 + "' buffer contention resulted in write data consistency.  "
793                 + ctr + " values written when should have written "
794                 + value.limit());
795         buf.setLength(buf.length() - 1);
796         value.position(pos);
797         el.setAttribute(dataAttributeName, buf.toString());
798         currentElement = (Element) el.getParentNode();
799     }
800 
write(Enum value, String name, Enum defVal)801         public void write(Enum value, String name, Enum defVal) throws IOException {
802         if (value == defVal) {
803             return;
804         }
805         currentElement.setAttribute(name, String.valueOf(value));
806 
807         }
808 
writeByteBufferArrayList(ArrayList<ByteBuffer> array, String name, ArrayList<ByteBuffer> defVal)809         public void writeByteBufferArrayList(ArrayList<ByteBuffer> array,
810                         String name, ArrayList<ByteBuffer> defVal) throws IOException {
811         if (array == null) {
812             return;
813         }
814         if (array.equals(defVal)) {
815             return;
816         }
817         Element el = appendElement(name);
818         el.setAttribute("size", String.valueOf(array.size()));
819         for (ByteBuffer o : array) {
820             write(o, "ByteBuffer", null);
821         }
822         currentElement = (Element) el.getParentNode();
823 
824         }
825 }