aboutsummaryrefslogtreecommitdiff
path: root/engine/src/xml
diff options
context:
space:
mode:
authorScott Barta <sbarta@google.com>2012-03-01 12:35:35 -0800
committerScott Barta <sbarta@google.com>2012-03-01 12:40:08 -0800
commit59b2e6871c65f58fdad78cd7229c292f6a177578 (patch)
tree2d4e7bfc05b93f40b34675d77e403dd1c25efafd /engine/src/xml
parentf9b30489e75ac1eabc365064959804e99534f7ab (diff)
downloadjmonkeyengine-59b2e6871c65f58fdad78cd7229c292f6a177578.tar.gz
Adds the jMonkeyEngine library to the build.
Adds the jMonkeyEngine open source 3D game engine to the build. This is built as a static library and is only used by the Finsky client. Change-Id: I06a3f054df7b8a67757267d884854f70c5a16ca0
Diffstat (limited to 'engine/src/xml')
-rw-r--r--engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java1511
-rw-r--r--engine/src/xml/com/jme3/export/xml/DOMOutputCapsule.java825
-rw-r--r--engine/src/xml/com/jme3/export/xml/DOMSerializer.java237
-rw-r--r--engine/src/xml/com/jme3/export/xml/XMLExporter.java92
-rw-r--r--engine/src/xml/com/jme3/export/xml/XMLImporter.java116
5 files changed, 2781 insertions, 0 deletions
diff --git a/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java b/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java
new file mode 100644
index 0000000..c3be20a
--- /dev/null
+++ b/engine/src/xml/com/jme3/export/xml/DOMInputCapsule.java
@@ -0,0 +1,1511 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.export.xml;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.Savable;
+import com.jme3.export.SavableClassUtil;
+import com.jme3.util.BufferUtils;
+import com.jme3.util.IntMap;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.*;
+import java.util.logging.Logger;
+import org.w3c.dom.*;
+
+/**
+ * Part of the jME XML IO system as introduced in the google code jmexml project.
+ *
+ * @author Kai Rabien (hevee) - original author of the code.google.com jmexml project
+ * @author Doug Daniels (dougnukem) - adjustments for jME 2.0 and Java 1.5
+ * @author blaine
+ */
+public class DOMInputCapsule implements InputCapsule {
+ private static final Logger logger =
+ Logger.getLogger(DOMInputCapsule.class .getName());
+
+ private Document doc;
+ private Element currentElem;
+ private XMLImporter importer;
+ private boolean isAtRoot = true;
+ private Map<String, Savable> referencedSavables = new HashMap<String, Savable>();
+
+ private int[] classHierarchyVersions;
+ private Savable savable;
+
+ public DOMInputCapsule(Document doc, XMLImporter importer) {
+ this.doc = doc;
+ this.importer = importer;
+ currentElem = doc.getDocumentElement();
+
+ String version = currentElem.getAttribute("format_version");
+ importer.formatVersion = version.equals("") ? 0 : Integer.parseInt(version);
+ }
+
+ public int getSavableVersion(Class<? extends Savable> desiredClass) {
+ if (classHierarchyVersions != null){
+ return SavableClassUtil.getSavedSavableVersion(savable, desiredClass,
+ classHierarchyVersions, importer.getFormatVersion());
+ }else{
+ return 0;
+ }
+ }
+
+ private static String decodeString(String s) {
+ if (s == null) {
+ return null;
+ }
+ s = s.replaceAll("\\&quot;", "\"").replaceAll("\\&lt;", "<").replaceAll("\\&amp;", "&");
+ return s;
+ }
+
+ private Element findFirstChildElement(Element parent) {
+ Node ret = parent.getFirstChild();
+ while (ret != null && (!(ret instanceof Element))) {
+ ret = ret.getNextSibling();
+ }
+ return (Element) ret;
+ }
+
+ private Element findChildElement(Element parent, String name) {
+ if (parent == null) {
+ return null;
+ }
+ Node ret = parent.getFirstChild();
+ while (ret != null && (!(ret instanceof Element) || !ret.getNodeName().equals(name))) {
+ ret = ret.getNextSibling();
+ }
+ return (Element) ret;
+ }
+
+ private Element findNextSiblingElement(Element current) {
+ Node ret = current.getNextSibling();
+ while (ret != null) {
+ if (ret instanceof Element) {
+ return (Element) ret;
+ }
+ ret = ret.getNextSibling();
+ }
+ return null;
+ }
+
+ public byte readByte(String name, byte defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Byte.parseByte(tmpString);
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public byte[] readByteArray(String name, byte[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of bytes for '" + name
+ + "'. size says " + requiredSize
+ + ", data contains "
+ + strings.length);
+ }
+ byte[] tmp = new byte[strings.length];
+ for (int i = 0; i < strings.length; i++) {
+ tmp[i] = Byte.parseByte(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public byte[][] readByteArray2D(String name, byte[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = currentElem.getChildNodes();
+ List<byte[]> byteArrays = new ArrayList<byte[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ byteArrays.add(readByteArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (byteArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + byteArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return byteArrays.toArray(new byte[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public int readInt(String name, int defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Integer.parseInt(tmpString);
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public int[] readIntArray(String name, int[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of ints for '" + name
+ + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ int[] tmp = new int[strings.length];
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = Integer.parseInt(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public int[][] readIntArray2D(String name, int[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+
+
+
+
+ NodeList nodes = currentElem.getChildNodes();
+ List<int[]> intArrays = new ArrayList<int[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ intArrays.add(readIntArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (intArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + intArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return intArrays.toArray(new int[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public float readFloat(String name, float defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Float.parseFloat(tmpString);
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public float[] readFloatArray(String name, float[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of floats for '" + name
+ + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ float[] tmp = new float[strings.length];
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = Float.parseFloat(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public float[][] readFloatArray2D(String name, float[][] defVal) throws IOException {
+ /* Why does this one method ignore the 'size attr.? */
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ int size_outer = Integer.parseInt(tmpEl.getAttribute("size_outer"));
+ int size_inner = Integer.parseInt(tmpEl.getAttribute("size_outer"));
+
+ float[][] tmp = new float[size_outer][size_inner];
+
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ for (int i = 0; i < size_outer; i++) {
+ tmp[i] = new float[size_inner];
+ for (int k = 0; k < size_inner; k++) {
+ tmp[i][k] = Float.parseFloat(strings[i]);
+ }
+ }
+ return tmp;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public double readDouble(String name, double defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Double.parseDouble(tmpString);
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public double[] readDoubleArray(String name, double[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of doubles for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ double[] tmp = new double[strings.length];
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = Double.parseDouble(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public double[][] readDoubleArray2D(String name, double[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = currentElem.getChildNodes();
+ List<double[]> doubleArrays = new ArrayList<double[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ doubleArrays.add(readDoubleArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (doubleArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + doubleArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return doubleArrays.toArray(new double[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public long readLong(String name, long defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Long.parseLong(tmpString);
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public long[] readLongArray(String name, long[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of longs for '" + name
+ + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ long[] tmp = new long[strings.length];
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = Long.parseLong(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public long[][] readLongArray2D(String name, long[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = currentElem.getChildNodes();
+ List<long[]> longArrays = new ArrayList<long[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ longArrays.add(readLongArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (longArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + longArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return longArrays.toArray(new long[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public short readShort(String name, short defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Short.parseShort(tmpString);
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public short[] readShortArray(String name, short[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of shorts for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ short[] tmp = new short[strings.length];
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = Short.parseShort(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public short[][] readShortArray2D(String name, short[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = currentElem.getChildNodes();
+ List<short[]> shortArrays = new ArrayList<short[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ shortArrays.add(readShortArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (shortArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + shortArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return shortArrays.toArray(new short[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public boolean readBoolean(String name, boolean defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return Boolean.parseBoolean(tmpString);
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public boolean[] readBooleanArray(String name, boolean[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of bools for '" + name
+ + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ boolean[] tmp = new boolean[strings.length];
+ for (int i = 0; i < tmp.length; i++) {
+ tmp[i] = Boolean.parseBoolean(strings[i]);
+ }
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public boolean[][] readBooleanArray2D(String name, boolean[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = currentElem.getChildNodes();
+ List<boolean[]> booleanArrays = new ArrayList<boolean[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ booleanArrays.add(readBooleanArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (booleanArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + booleanArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return booleanArrays.toArray(new boolean[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public String readString(String name, String defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ return decodeString(tmpString);
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public String[] readStringArray(String name, String[] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = tmpEl.getChildNodes();
+ List<String> strings = new ArrayList<String>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("String")) {
+ // Very unsafe assumption
+ strings.add(((Element) n).getAttributeNode("value").getValue());
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + strings.size());
+ }
+ return strings.toArray(new String[0]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public String[][] readStringArray2D(String name, String[][] defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ NodeList nodes = currentElem.getChildNodes();
+ List<String[]> stringArrays = new ArrayList<String[]>();
+
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().contains("array")) {
+ // Very unsafe assumption
+ stringArrays.add(readStringArray(n.getNodeName(), null));
+ }
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (stringArrays.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + stringArrays.size());
+ }
+ currentElem = (Element) currentElem.getParentNode();
+ return stringArrays.toArray(new String[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public BitSet readBitSet(String name, BitSet defVal) throws IOException {
+ String tmpString = currentElem.getAttribute(name);
+ if (tmpString == null || tmpString.length() < 1) return defVal;
+ try {
+ BitSet set = new BitSet();
+ String[] strings = parseTokens(tmpString);
+ for (int i = 0; i < strings.length; i++) {
+ int isSet = Integer.parseInt(strings[i]);
+ if (isSet == 1) {
+ set.set(i);
+ }
+ }
+ return set;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public Savable readSavable(String name, Savable defVal) throws IOException {
+ Savable ret = defVal;
+ if (name != null && name.equals(""))
+ logger.warning("Reading Savable String with name \"\"?");
+ try {
+ Element tmpEl = null;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+ } else if (isAtRoot) {
+ tmpEl = doc.getDocumentElement();
+ isAtRoot = false;
+ } else {
+ tmpEl = findFirstChildElement(currentElem);
+ }
+ currentElem = tmpEl;
+ ret = readSavableFromCurrentElem(defVal);
+ if (currentElem.getParentNode() instanceof Element) {
+ currentElem = (Element) currentElem.getParentNode();
+ } else {
+ currentElem = null;
+ }
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (Exception e) {
+ IOException io = new IOException(e.toString());
+ io.initCause(e);
+ throw io;
+ }
+ return ret;
+ }
+
+ private Savable readSavableFromCurrentElem(Savable defVal) throws
+ InstantiationException, ClassNotFoundException,
+ IOException, IllegalAccessException {
+ Savable ret = defVal;
+ Savable tmp = null;
+
+ if (currentElem == null || currentElem.getNodeName().equals("null")) {
+ return null;
+ }
+ String reference = currentElem.getAttribute("ref");
+ if (reference.length() > 0) {
+ ret = referencedSavables.get(reference);
+ } else {
+ String className = currentElem.getNodeName();
+ if (defVal != null) {
+ className = defVal.getClass().getName();
+ } else if (currentElem.hasAttribute("class")) {
+ className = currentElem.getAttribute("class");
+ }
+ tmp = SavableClassUtil.fromName(className, null);
+
+
+ String versionsStr = currentElem.getAttribute("savable_versions");
+ if (versionsStr != null && !versionsStr.equals("")){
+ String[] versionStr = versionsStr.split(",");
+ classHierarchyVersions = new int[versionStr.length];
+ for (int i = 0; i < classHierarchyVersions.length; i++){
+ classHierarchyVersions[i] = Integer.parseInt(versionStr[i].trim());
+ }
+ }else{
+ classHierarchyVersions = null;
+ }
+
+ String refID = currentElem.getAttribute("reference_ID");
+ if (refID.length() < 1) refID = currentElem.getAttribute("id");
+ if (refID.length() > 0) referencedSavables.put(refID, tmp);
+ if (tmp != null) {
+ // Allows reading versions from this savable
+ savable = tmp;
+ tmp.read(importer);
+ ret = tmp;
+ }
+ }
+ return ret;
+ }
+
+ public Savable[] readSavableArray(String name, Savable[] defVal) throws IOException {
+ Savable[] ret = defVal;
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ List<Savable> savables = new ArrayList<Savable>();
+ for (currentElem = findFirstChildElement(tmpEl);
+ currentElem != null;
+ currentElem = findNextSiblingElement(currentElem)) {
+ savables.add(readSavableFromCurrentElem(null));
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (savables.size() != requiredSize)
+ throw new IOException("Wrong number of Savables for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + savables.size());
+ }
+ ret = savables.toArray(new Savable[0]);
+ currentElem = (Element) tmpEl.getParentNode();
+ return ret;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (Exception e) {
+ IOException io = new IOException(e.toString());
+ io.initCause(e);
+ throw io;
+ }
+ }
+
+ public Savable[][] readSavableArray2D(String name, Savable[][] defVal) throws IOException {
+ Savable[][] ret = defVal;
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ int size_outer = Integer.parseInt(tmpEl.getAttribute("size_outer"));
+ int size_inner = Integer.parseInt(tmpEl.getAttribute("size_outer"));
+
+ Savable[][] tmp = new Savable[size_outer][size_inner];
+ currentElem = findFirstChildElement(tmpEl);
+ for (int i = 0; i < size_outer; i++) {
+ for (int j = 0; j < size_inner; j++) {
+ tmp[i][j] = (readSavableFromCurrentElem(null));
+ if (i == size_outer - 1 && j == size_inner - 1) {
+ break;
+ }
+ currentElem = findNextSiblingElement(currentElem);
+ }
+ }
+ ret = tmp;
+ currentElem = (Element) tmpEl.getParentNode();
+ return ret;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (Exception e) {
+ IOException io = new IOException(e.toString());
+ io.initCause(e);
+ throw io;
+ }
+ }
+
+ public ArrayList<Savable> readSavableArrayList(String name, ArrayList defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ ArrayList<Savable> savables = new ArrayList<Savable>();
+ for (currentElem = findFirstChildElement(tmpEl);
+ currentElem != null;
+ currentElem = findNextSiblingElement(currentElem)) {
+ savables.add(readSavableFromCurrentElem(null));
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (savables.size() != requiredSize)
+ throw new IOException(
+ "Wrong number of Savable arrays for '" + name
+ + "'. size says " + requiredSize
+ + ", data contains " + savables.size());
+ }
+ currentElem = (Element) tmpEl.getParentNode();
+ return savables;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (Exception e) {
+ IOException io = new IOException(e.toString());
+ io.initCause(e);
+ throw io;
+ }
+ }
+
+ public ArrayList<Savable>[] readSavableArrayListArray(
+ String name, ArrayList[] defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+ currentElem = tmpEl;
+
+ String sizeString = tmpEl.getAttribute("size");
+ int requiredSize = (sizeString.length() > 0)
+ ? Integer.parseInt(sizeString)
+ : -1;
+
+ ArrayList<Savable> sal;
+ List<ArrayList<Savable>> savableArrayLists =
+ new ArrayList<ArrayList<Savable>>();
+ int i = -1;
+ while (true) {
+ sal = readSavableArrayList("SavableArrayList_" + ++i, null);
+ if (sal == null && savableArrayLists.size() >= requiredSize)
+ break;
+ savableArrayLists.add(sal);
+ }
+
+ if (requiredSize > -1 && savableArrayLists.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + savableArrayLists.size());
+ currentElem = (Element) tmpEl.getParentNode();
+ return savableArrayLists.toArray(new ArrayList[0]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public ArrayList<Savable>[][] readSavableArrayListArray2D(String name, ArrayList[][] defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+ currentElem = tmpEl;
+ String sizeString = tmpEl.getAttribute("size");
+
+ ArrayList<Savable>[] arr;
+ List<ArrayList<Savable>[]> sall = new ArrayList<ArrayList<Savable>[]>();
+ int i = -1;
+ while ((arr = readSavableArrayListArray(
+ "SavableArrayListArray_" + ++i, null)) != null) sall.add(arr);
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (sall.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + sall.size());
+ }
+ currentElem = (Element) tmpEl.getParentNode();
+ return sall.toArray(new ArrayList[0][]);
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (Exception e) {
+ IOException io = new IOException(e.toString());
+ io.initCause(e);
+ throw io;
+ }
+ }
+
+ public ArrayList<FloatBuffer> readFloatBufferArrayList(
+ String name, ArrayList<FloatBuffer> defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ ArrayList<FloatBuffer> tmp = new ArrayList<FloatBuffer>();
+ for (currentElem = findFirstChildElement(tmpEl);
+ currentElem != null;
+ currentElem = findNextSiblingElement(currentElem)) {
+ tmp.add(readFloatBuffer(null, null));
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (tmp.size() != requiredSize)
+ throw new IOException(
+ "String array contains wrong element count. "
+ + "Specified size " + requiredSize
+ + ", data contains " + tmp.size());
+ }
+ currentElem = (Element) tmpEl.getParentNode();
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public Map<? extends Savable, ? extends Savable> readSavableMap(String name, Map<? extends Savable, ? extends Savable> defVal) throws IOException {
+ Map<Savable, Savable> ret;
+ Element tempEl;
+
+ if (name != null) {
+ tempEl = findChildElement(currentElem, name);
+ } else {
+ tempEl = currentElem;
+ }
+ ret = new HashMap<Savable, Savable>();
+
+ NodeList nodes = tempEl.getChildNodes();
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().equals("MapEntry")) {
+ Element elem = (Element) n;
+ currentElem = elem;
+ Savable key = readSavable(XMLExporter.ELEMENT_KEY, null);
+ Savable val = readSavable(XMLExporter.ELEMENT_VALUE, null);
+ ret.put(key, val);
+ }
+ }
+ currentElem = (Element) tempEl.getParentNode();
+ return ret;
+ }
+
+ public Map<String, ? extends Savable> readStringSavableMap(String name, Map<String, ? extends Savable> defVal) throws IOException {
+ Map<String, Savable> ret = null;
+ Element tempEl;
+
+ if (name != null) {
+ tempEl = findChildElement(currentElem, name);
+ } else {
+ tempEl = currentElem;
+ }
+ if (tempEl != null) {
+ ret = new HashMap<String, Savable>();
+
+ NodeList nodes = tempEl.getChildNodes();
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().equals("MapEntry")) {
+ Element elem = (Element) n;
+ currentElem = elem;
+ String key = currentElem.getAttribute("key");
+ Savable val = readSavable("Savable", null);
+ ret.put(key, val);
+ }
+ }
+ } else {
+ return defVal;
+ }
+ currentElem = (Element) tempEl.getParentNode();
+ return ret;
+ }
+
+ public IntMap<? extends Savable> readIntSavableMap(String name, IntMap<? extends Savable> defVal) throws IOException {
+ IntMap<Savable> ret = null;
+ Element tempEl;
+
+ if (name != null) {
+ tempEl = findChildElement(currentElem, name);
+ } else {
+ tempEl = currentElem;
+ }
+ if (tempEl != null) {
+ ret = new IntMap<Savable>();
+
+ NodeList nodes = tempEl.getChildNodes();
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n instanceof Element && n.getNodeName().equals("MapEntry")) {
+ Element elem = (Element) n;
+ currentElem = elem;
+ int key = Integer.parseInt(currentElem.getAttribute("key"));
+ Savable val = readSavable("Savable", null);
+ ret.put(key, val);
+ }
+ }
+ } else {
+ return defVal;
+ }
+ currentElem = (Element) tempEl.getParentNode();
+ return ret;
+ }
+
+ /**
+ * reads from currentElem if name is null
+ */
+ public FloatBuffer readFloatBuffer(String name, FloatBuffer defVal) throws IOException {
+ try {
+ Element tmpEl;
+ if (name != null) {
+ tmpEl = findChildElement(currentElem, name);
+ } else {
+ tmpEl = currentElem;
+ }
+ if (tmpEl == null) {
+ return defVal;
+ }
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of float buffers for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ FloatBuffer tmp = BufferUtils.createFloatBuffer(strings.length);
+ for (String s : strings) tmp.put(Float.parseFloat(s));
+ tmp.flip();
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public IntBuffer readIntBuffer(String name, IntBuffer defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of int buffers for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ IntBuffer tmp = BufferUtils.createIntBuffer(strings.length);
+ for (String s : strings) tmp.put(Integer.parseInt(s));
+ tmp.flip();
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public ByteBuffer readByteBuffer(String name, ByteBuffer defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of byte buffers for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ ByteBuffer tmp = BufferUtils.createByteBuffer(strings.length);
+ for (String s : strings) tmp.put(Byte.valueOf(s));
+ tmp.flip();
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public ShortBuffer readShortBuffer(String name, ShortBuffer defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ String[] strings = parseTokens(tmpEl.getAttribute("data"));
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (strings.length != requiredSize)
+ throw new IOException("Wrong number of short buffers for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + strings.length);
+ }
+ ShortBuffer tmp = BufferUtils.createShortBuffer(strings.length);
+ for (String s : strings) tmp.put(Short.valueOf(s));
+ tmp.flip();
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public ArrayList<ByteBuffer> readByteBufferArrayList(String name, ArrayList<ByteBuffer> defVal) throws IOException {
+ try {
+ Element tmpEl = findChildElement(currentElem, name);
+ if (tmpEl == null) {
+ return defVal;
+ }
+
+ String sizeString = tmpEl.getAttribute("size");
+ ArrayList<ByteBuffer> tmp = new ArrayList<ByteBuffer>();
+ for (currentElem = findFirstChildElement(tmpEl);
+ currentElem != null;
+ currentElem = findNextSiblingElement(currentElem)) {
+ tmp.add(readByteBuffer(null, null));
+ }
+ if (sizeString.length() > 0) {
+ int requiredSize = Integer.parseInt(sizeString);
+ if (tmp.size() != requiredSize)
+ throw new IOException("Wrong number of short buffers for '"
+ + name + "'. size says " + requiredSize
+ + ", data contains " + tmp.size());
+ }
+ currentElem = (Element) tmpEl.getParentNode();
+ return tmp;
+ } catch (IOException ioe) {
+ throw ioe;
+ } catch (NumberFormatException nfe) {
+ IOException io = new IOException(nfe.toString());
+ io.initCause(nfe);
+ throw io;
+ } catch (DOMException de) {
+ IOException io = new IOException(de.toString());
+ io.initCause(de);
+ throw io;
+ }
+ }
+
+ public <T extends Enum<T>> T readEnum(String name, Class<T> enumType,
+ T defVal) throws IOException {
+ T ret = defVal;
+ try {
+ String eVal = currentElem.getAttribute(name);
+ if (eVal != null && eVal.length() > 0) {
+ ret = Enum.valueOf(enumType, eVal);
+ }
+ } catch (Exception e) {
+ IOException io = new IOException(e.toString());
+ io.initCause(e);
+ throw io;
+ }
+ return ret;
+ }
+
+ private static final String[] zeroStrings = new String[0];
+
+ protected String[] parseTokens(String inString) {
+ String[] outStrings = inString.split("\\s+");
+ return (outStrings.length == 1 && outStrings[0].length() == 0)
+ ? zeroStrings
+ : outStrings;
+ }
+} \ No newline at end of file
diff --git a/engine/src/xml/com/jme3/export/xml/DOMOutputCapsule.java b/engine/src/xml/com/jme3/export/xml/DOMOutputCapsule.java
new file mode 100644
index 0000000..2baef1f
--- /dev/null
+++ b/engine/src/xml/com/jme3/export/xml/DOMOutputCapsule.java
@@ -0,0 +1,825 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.export.xml;
+
+import com.jme3.export.FormatVersion;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import com.jme3.export.SavableClassUtil;
+import com.jme3.util.IntMap;
+import com.jme3.util.IntMap.Entry;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.*;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Part of the jME XML IO system as introduced in the google code jmexml project.
+ *
+ * @author Kai Rabien (hevee) - original author of the code.google.com jmexml project
+ * @author Doug Daniels (dougnukem) - adjustments for jME 2.0 and Java 1.5
+ */
+public class DOMOutputCapsule implements OutputCapsule {
+
+ private static final String dataAttributeName = "data";
+ private Document doc;
+ private Element currentElement;
+ private JmeExporter exporter;
+ private Map<Savable, Element> writtenSavables = new IdentityHashMap<Savable, Element>();
+
+ public DOMOutputCapsule(Document doc, JmeExporter exporter) {
+ this.doc = doc;
+ this.exporter = exporter;
+ currentElement = null;
+ }
+
+ public Document getDoc() {
+ return doc;
+ }
+
+ /**
+ * appends a new Element with the given name to currentElement, sets
+ * currentElement to be new Element, and returns the new Element as well
+ */
+ private Element appendElement(String name) {
+ Element ret = doc.createElement(name);
+ if (currentElement == null) {
+ ret.setAttribute("format_version", Integer.toString(FormatVersion.VERSION));
+ doc.appendChild(ret);
+ } else {
+ currentElement.appendChild(ret);
+ }
+ currentElement = ret;
+ return ret;
+ }
+
+ private static String encodeString(String s) {
+ if (s == null) {
+ return null;
+ }
+ s = s.replaceAll("\\&", "&amp;")
+ .replaceAll("\\\"", "&quot;")
+ .replaceAll("\\<", "&lt;");
+ return s;
+ }
+
+ public void write(byte value, String name, byte defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(byte[] value, String name, byte[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ for (byte b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(buf.length() - 1);
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(byte[][] value, String name, byte[][] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ for (byte[] bs : value) {
+ for (byte b : bs) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ buf.append(" ");
+ }
+ //remove last spaces
+ buf.setLength(buf.length() - 2);
+
+ Element el = appendElement(name);
+ el.setAttribute("size_outer", String.valueOf(value.length));
+ el.setAttribute("size_inner", String.valueOf(value[0].length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(int value, String name, int defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(int[] value, String name, int[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) { return; }
+ if (Arrays.equals(value, defVal)) { return; }
+
+ for (int b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(Math.max(0, buf.length() - 1));
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(int[][] value, String name, int[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ int[] array = value[i];
+ write(array, "array_"+i, defVal==null?null:defVal[i]);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(float value, String name, float defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(float[] value, String name, float[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ if (value != null) {
+ for (float b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(buf.length() - 1);
+ }
+
+ Element el = appendElement(name);
+ el.setAttribute("size", value == null ? "0" : String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(float[][] value, String name, float[][] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ for (float[] bs : value) {
+ for(float b : bs){
+ buf.append(b);
+ buf.append(" ");
+ }
+ }
+ //remove last space
+ buf.setLength(buf.length() - 1);
+
+ Element el = appendElement(name);
+ el.setAttribute("size_outer", String.valueOf(value.length));
+ el.setAttribute("size_inner", String.valueOf(value[0].length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(double value, String name, double defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(double[] value, String name, double[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ for (double b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(buf.length() - 1);
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(double[][] value, String name, double[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ double[] array = value[i];
+ write(array, "array_"+i, defVal==null?null:defVal[i]);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(long value, String name, long defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(long[] value, String name, long[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ for (long b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(buf.length() - 1);
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(long[][] value, String name, long[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ long[] array = value[i];
+ write(array, "array_"+i, defVal==null?null:defVal[i]);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(short value, String name, short defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(short[] value, String name, short[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ for (short b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(buf.length() - 1);
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(short[][] value, String name, short[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ short[] array = value[i];
+ write(array, "array_"+i, defVal==null?null:defVal[i]);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(boolean value, String name, boolean defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+ }
+
+ public void write(boolean[] value, String name, boolean[] defVal) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ if (value == null) {
+ value = defVal;
+ }
+ for (boolean b : value) {
+ buf.append(b);
+ buf.append(" ");
+ }
+ //remove last space
+ buf.setLength(Math.max(0, buf.length() - 1));
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(boolean[][] value, String name, boolean[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ boolean[] array = value[i];
+ write(array, "array_"+i, defVal==null?null:defVal[i]);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(String value, String name, String defVal) throws IOException {
+ if (value == null || value.equals(defVal)) {
+ return;
+ }
+ currentElement.setAttribute(name, encodeString(value));
+ }
+
+ public void write(String[] value, String name, String[] defVal) throws IOException {
+ Element el = appendElement(name);
+
+ if (value == null) {
+ value = defVal;
+ }
+
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ String b = value[i];
+ appendElement("String_"+i);
+ String val = encodeString(b);
+ currentElement.setAttribute("value", val);
+ currentElement = el;
+ }
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void write(String[][] value, String name, String[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.length));
+
+ for (int i=0; i<value.length; i++) {
+ String[] array = value[i];
+ write(array, "array_"+i, defVal==null?null:defVal[i]);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(BitSet value, String name, BitSet defVal) throws IOException {
+ if (value == null || value.equals(defVal)) {
+ return;
+ }
+ StringBuilder buf = new StringBuilder();
+ for (int i = value.nextSetBit(0); i >= 0; i = value.nextSetBit(i + 1)) {
+ buf.append(i);
+ buf.append(" ");
+ }
+ buf.setLength(Math.max(0, buf.length() - 1));
+ currentElement.setAttribute(name, buf.toString());
+
+ }
+
+ public void write(Savable object, String name, Savable defVal) throws IOException {
+ if (object == null) {
+ return;
+ }
+ if (object.equals(defVal)) {
+ return;
+ }
+
+ Element old = currentElement;
+ Element el = writtenSavables.get(object);
+
+ String className = null;
+ if(!object.getClass().getName().equals(name)){
+ className = object.getClass().getName();
+ }
+ try {
+ doc.createElement(name);
+ } catch (DOMException e) {
+ // Ridiculous fallback behavior.
+ // Would be far better to throw than to totally disregard the
+ // specified "name" and write a class name instead!
+ // (Besides the fact we are clobbering the managed .getClassTag()).
+ name = "Object";
+ className = object.getClass().getName();
+ }
+
+ if (el != null) {
+ String refID = el.getAttribute("reference_ID");
+ if (refID.length() == 0) {
+ refID = object.getClass().getName() + "@" + object.hashCode();
+ el.setAttribute("reference_ID", refID);
+ }
+ el = appendElement(name);
+ el.setAttribute("ref", refID);
+ } else {
+ el = appendElement(name);
+
+ // jME3 NEW: Append version number(s)
+ int[] versions = SavableClassUtil.getSavableVersions(object.getClass());
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < versions.length; i++){
+ sb.append(versions[i]);
+ if (i != versions.length - 1){
+ sb.append(", ");
+ }
+ }
+ el.setAttribute("savable_versions", sb.toString());
+
+ writtenSavables.put(object, el);
+ object.write(exporter);
+ }
+ if(className != null){
+ el.setAttribute("class", className);
+ }
+
+ currentElement = old;
+ }
+
+ public void write(Savable[] objects, String name, Savable[] defVal) throws IOException {
+ if (objects == null) {
+ return;
+ }
+ if (Arrays.equals(objects, defVal)) {
+ return;
+ }
+
+ Element old = currentElement;
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(objects.length));
+ for (int i = 0; i < objects.length; i++) {
+ Savable o = objects[i];
+ if(o == null){
+ //renderStateList has special loading code, so we can leave out the null values
+ if(!name.equals("renderStateList")){
+ Element before = currentElement;
+ appendElement("null");
+ currentElement = before;
+ }
+ }else{
+ write(o, o.getClass().getName(), null);
+ }
+ }
+ currentElement = old;
+ }
+
+ public void write(Savable[][] value, String name, Savable[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size_outer", String.valueOf(value.length));
+ el.setAttribute("size_inner", String.valueOf(value[0].length));
+ for (Savable[] bs : value) {
+ for(Savable b : bs){
+ write(b, b.getClass().getSimpleName(), null);
+ }
+ }
+ currentElement = (Element) currentElement.getParentNode();
+ }
+
+ public void writeSavableArrayList(ArrayList array, String name, ArrayList defVal) throws IOException {
+ if (array == null) {
+ return;
+ }
+ if (array.equals(defVal)) {
+ return;
+ }
+ Element old = currentElement;
+ Element el = appendElement(name);
+ currentElement = el;
+ el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(array.size()));
+ for (Object o : array) {
+ if(o == null) {
+ continue;
+ }
+ else if (o instanceof Savable) {
+ Savable s = (Savable) o;
+ write(s, s.getClass().getName(), null);
+ } else {
+ throw new ClassCastException("Not a Savable instance: " + o);
+ }
+ }
+ currentElement = old;
+ }
+
+ public void writeSavableArrayListArray(ArrayList[] objects, String name, ArrayList[] defVal) throws IOException {
+ if (objects == null) {return;}
+ if (Arrays.equals(objects, defVal)) {return;}
+
+ Element old = currentElement;
+ Element el = appendElement(name);
+ el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(objects.length));
+ for (int i = 0; i < objects.length; i++) {
+ ArrayList o = objects[i];
+ if(o == null){
+ Element before = currentElement;
+ appendElement("null");
+ currentElement = before;
+ }else{
+ StringBuilder buf = new StringBuilder("SavableArrayList_");
+ buf.append(i);
+ writeSavableArrayList(o, buf.toString(), null);
+ }
+ }
+ currentElement = old;
+ }
+
+ public void writeSavableArrayListArray2D(ArrayList[][] value, String name, ArrayList[][] defVal) throws IOException {
+ if (value == null) return;
+ if(Arrays.deepEquals(value, defVal)) return;
+
+ Element el = appendElement(name);
+ int size = value.length;
+ el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(size));
+
+ for (int i=0; i< size; i++) {
+ ArrayList[] vi = value[i];
+ writeSavableArrayListArray(vi, "SavableArrayListArray_"+i, null);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void writeFloatBufferArrayList(ArrayList<FloatBuffer> array, String name, ArrayList<FloatBuffer> defVal) throws IOException {
+ if (array == null) {
+ return;
+ }
+ if (array.equals(defVal)) {
+ return;
+ }
+ Element el = appendElement(name);
+ el.setAttribute(XMLExporter.ATTRIBUTE_SIZE, String.valueOf(array.size()));
+ for (FloatBuffer o : array) {
+ write(o, XMLExporter.ELEMENT_FLOATBUFFER, null);
+ }
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void writeSavableMap(Map<? extends Savable, ? extends Savable> map, String name, Map<? extends Savable, ? extends Savable> defVal) throws IOException {
+ if (map == null) {
+ return;
+ }
+ if (map.equals(defVal)) {
+ return;
+ }
+ Element stringMap = appendElement(name);
+
+ Iterator<? extends Savable> keyIterator = map.keySet().iterator();
+ while(keyIterator.hasNext()) {
+ Savable key = keyIterator.next();
+ Element mapEntry = appendElement(XMLExporter.ELEMENT_MAPENTRY);
+ write(key, XMLExporter.ELEMENT_KEY, null);
+ Savable value = map.get(key);
+ write(value, XMLExporter.ELEMENT_VALUE, null);
+ currentElement = stringMap;
+ }
+
+ currentElement = (Element) stringMap.getParentNode();
+ }
+
+ public void writeStringSavableMap(Map<String, ? extends Savable> map, String name, Map<String, ? extends Savable> defVal) throws IOException {
+ if (map == null) {
+ return;
+ }
+ if (map.equals(defVal)) {
+ return;
+ }
+ Element stringMap = appendElement(name);
+
+ Iterator<String> keyIterator = map.keySet().iterator();
+ while(keyIterator.hasNext()) {
+ String key = keyIterator.next();
+ Element mapEntry = appendElement("MapEntry");
+ mapEntry.setAttribute("key", key);
+ Savable s = map.get(key);
+ write(s, "Savable", null);
+ currentElement = stringMap;
+ }
+
+ currentElement = (Element) stringMap.getParentNode();
+ }
+
+ public void writeIntSavableMap(IntMap<? extends Savable> map, String name, IntMap<? extends Savable> defVal) throws IOException {
+ if (map == null) {
+ return;
+ }
+ if (map.equals(defVal)) {
+ return;
+ }
+ Element stringMap = appendElement(name);
+
+ for(Entry<? extends Savable> entry : map) {
+ int key = entry.getKey();
+ Element mapEntry = appendElement("MapEntry");
+ mapEntry.setAttribute("key", Integer.toString(key));
+ Savable s = entry.getValue();
+ write(s, "Savable", null);
+ currentElement = stringMap;
+ }
+
+ currentElement = (Element) stringMap.getParentNode();
+ }
+
+ public void write(FloatBuffer value, String name, FloatBuffer defVal) throws IOException {
+ if (value == null) {
+ return;
+ }
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.limit()));
+ StringBuilder buf = new StringBuilder();
+ int pos = value.position();
+ value.rewind();
+ int ctr = 0;
+ while (value.hasRemaining()) {
+ ctr++;
+ buf.append(value.get());
+ buf.append(" ");
+ }
+ if (ctr != value.limit())
+ throw new IOException("'" + name
+ + "' buffer contention resulted in write data consistency. "
+ + ctr + " values written when should have written "
+ + value.limit());
+ buf.setLength(Math.max(0, buf.length() - 1));
+ value.position(pos);
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(IntBuffer value, String name, IntBuffer defVal) throws IOException {
+ if (value == null) {
+ return;
+ }
+ if (value.equals(defVal)) {
+ return;
+ }
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.limit()));
+ StringBuilder buf = new StringBuilder();
+ int pos = value.position();
+ value.rewind();
+ int ctr = 0;
+ while (value.hasRemaining()) {
+ ctr++;
+ buf.append(value.get());
+ buf.append(" ");
+ }
+ if (ctr != value.limit())
+ throw new IOException("'" + name
+ + "' buffer contention resulted in write data consistency. "
+ + ctr + " values written when should have written "
+ + value.limit());
+ buf.setLength(buf.length() - 1);
+ value.position(pos);
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(ByteBuffer value, String name, ByteBuffer defVal) throws IOException {
+ if (value == null) return;
+ if (value.equals(defVal)) return;
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.limit()));
+ StringBuilder buf = new StringBuilder();
+ int pos = value.position();
+ value.rewind();
+ int ctr = 0;
+ while (value.hasRemaining()) {
+ ctr++;
+ buf.append(value.get());
+ buf.append(" ");
+ }
+ if (ctr != value.limit())
+ throw new IOException("'" + name
+ + "' buffer contention resulted in write data consistency. "
+ + ctr + " values written when should have written "
+ + value.limit());
+ buf.setLength(buf.length() - 1);
+ value.position(pos);
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(ShortBuffer value, String name, ShortBuffer defVal) throws IOException {
+ if (value == null) {
+ return;
+ }
+ if (value.equals(defVal)) {
+ return;
+ }
+
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(value.limit()));
+ StringBuilder buf = new StringBuilder();
+ int pos = value.position();
+ value.rewind();
+ int ctr = 0;
+ while (value.hasRemaining()) {
+ ctr++;
+ buf.append(value.get());
+ buf.append(" ");
+ }
+ if (ctr != value.limit())
+ throw new IOException("'" + name
+ + "' buffer contention resulted in write data consistency. "
+ + ctr + " values written when should have written "
+ + value.limit());
+ buf.setLength(buf.length() - 1);
+ value.position(pos);
+ el.setAttribute(dataAttributeName, buf.toString());
+ currentElement = (Element) el.getParentNode();
+ }
+
+ public void write(Enum value, String name, Enum defVal) throws IOException {
+ if (value == defVal) {
+ return;
+ }
+ currentElement.setAttribute(name, String.valueOf(value));
+
+ }
+
+ public void writeByteBufferArrayList(ArrayList<ByteBuffer> array,
+ String name, ArrayList<ByteBuffer> defVal) throws IOException {
+ if (array == null) {
+ return;
+ }
+ if (array.equals(defVal)) {
+ return;
+ }
+ Element el = appendElement(name);
+ el.setAttribute("size", String.valueOf(array.size()));
+ for (ByteBuffer o : array) {
+ write(o, "ByteBuffer", null);
+ }
+ currentElement = (Element) el.getParentNode();
+
+ }
+} \ No newline at end of file
diff --git a/engine/src/xml/com/jme3/export/xml/DOMSerializer.java b/engine/src/xml/com/jme3/export/xml/DOMSerializer.java
new file mode 100644
index 0000000..b30ba19
--- /dev/null
+++ b/engine/src/xml/com/jme3/export/xml/DOMSerializer.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.export.xml;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import org.w3c.dom.*;
+
+/**
+ * The DOMSerializer was based primarily off the DOMSerializer.java class from the
+ * "Java and XML" 3rd Edition book by Brett McLaughlin, and Justin Edelson. Some
+ * modifications were made to support formatting of elements and attributes.
+ *
+ * @author Brett McLaughlin, Justin Edelson - Original creation for "Java and XML" book.
+ * @author Doug Daniels (dougnukem) - adjustments for XML formatting
+ * @version $Revision: 4207 $, $Date: 2009-03-29 11:19:16 -0400 (Sun, 29 Mar 2009) $
+ */
+public class DOMSerializer {
+
+ /** The encoding to use for output (default is UTF-8) */
+ private Charset encoding = Charset.forName("utf-8");
+
+ /** The amount of indentation to use (default is 4 spaces). */
+ private int indent = 4;
+
+ /** The line separator to use (default is the based on the current system settings). */
+ private String lineSeparator = System.getProperty("line.separator", "\n");
+
+ private void escape(Writer writer, String s) throws IOException {
+ if (s == null) { return; }
+ for (int i = 0, len = s.length(); i < len; i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '<':
+ writer.write("&lt;");
+ break;
+ case '>':
+ writer.write("&gt;");
+ break;
+ case '&':
+ writer.write("&amp;");
+ break;
+ case '\r':
+ writer.write("&#xD;");
+ break;
+ default:
+ writer.write(c);
+ }
+ }
+ }
+
+ /**
+ * Serialize {@code doc} to {@code out}
+ *
+ * @param doc the document to serialize.
+ * @param file the file to serialize to.
+ * @throws IOException
+ */
+ public void serialize(Document doc, File file) throws IOException {
+ serialize(doc, new FileOutputStream(file));
+ }
+
+ /**
+ * Serialize {@code doc} to {@code out}
+ *
+ * @param doc the document to serialize.
+ * @param out the stream to serialize to.
+ * @throws IOException
+ */
+ public void serialize(Document doc, OutputStream out) throws IOException {
+ Writer writer = new OutputStreamWriter(out, encoding);
+ write(doc, writer, 0);
+ writer.flush();
+ }
+
+ /**
+ * Set the encoding used by this serializer.
+ *
+ * @param encoding the encoding to use, passing in {@code null} results in the
+ * default encoding (UTF-8) being set.
+ * @throws IllegalCharsetNameException if the given charset name is illegal.
+ * @throws UnsupportedCharsetException if the given charset is not supported by the
+ * current JVM.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = Charset.forName(encoding);
+ }
+
+ /**
+ * Set the number of spaces to use for indentation.
+ * <p>
+ * The default is to use 4 spaces.
+ *
+ * @param indent the number of spaces to use for indentation, values less than or
+ * equal to zero result in no indentation being used.
+ */
+ public void setIndent(int indent) {
+ this.indent = indent >= 0 ? indent : 0;
+ }
+
+ /**
+ * Set the line separator that will be used when serializing documents.
+ * <p>
+ * If this is not called then the serializer uses a default based on the
+ * {@code line.separator} system property.
+ *
+ * @param lineSeparator the line separator to set.
+ */
+ public void setLineSeparator(String lineSeparator) {
+ this.lineSeparator = lineSeparator;
+ }
+
+ private void write(Node node, Writer writer, int depth) throws IOException {
+ switch (node.getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ writeDocument((Document) node, writer);
+ break;
+ case Node.ELEMENT_NODE:
+ writeElement((Element) node, writer, depth);
+ break;
+ case Node.TEXT_NODE:
+ escape(writer, node.getNodeValue());
+ break;
+ case Node.CDATA_SECTION_NODE:
+ writer.write("<![CDATA[");
+ escape(writer, node.getNodeValue());
+ writer.write("]]>");
+ break;
+ case Node.COMMENT_NODE:
+ for (int i = 0; i < depth; ++i) { writer.append(' '); }
+ writer.append("<!-- ").append(node.getNodeValue()).append(" -->").append(lineSeparator);
+ break;
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ String n = node.getNodeName();
+ String v = node.getNodeValue();
+ for (int i = 0; i < depth; ++i) { writer.append(' '); }
+ writer.append("<?").append(n).append(' ').append(v).append("?>").append(lineSeparator);
+ break;
+ case Node.ENTITY_REFERENCE_NODE:
+ writer.append('&').append(node.getNodeName()).append(';');
+ break;
+ case Node.DOCUMENT_TYPE_NODE:
+ writeDocumentType((DocumentType) node, writer, depth);
+ break;
+ }
+ }
+
+ private void writeDocument(Document document, Writer writer) throws IOException {
+ String v = document.getXmlVersion();
+
+ writer.append("<?xml ");
+ writer.append(" version='").append(v == null ? "1.0" : v).append("'");
+ writer.append(" encoding='").append(encoding.name()).append("'");
+ if (document.getXmlStandalone()) {
+ writer.append(" standalone='yes'");
+ }
+ writer.append("?>").append(lineSeparator);
+
+ NodeList nodes = document.getChildNodes();
+ for (int i = 0, imax = nodes.getLength(); i < imax; ++i) {
+ write(nodes.item(i), writer, 0);
+ }
+ }
+
+ private void writeDocumentType(DocumentType docType, Writer writer, int depth) throws IOException {
+ String publicId = docType.getPublicId();
+ String internalSubset = docType.getInternalSubset();
+
+ for (int i = 0; i < depth; ++i) { writer.append(' '); }
+ writer.append("<!DOCTYPE ").append(docType.getName());
+ if (publicId != null) {
+ writer.append(" PUBLIC '").append(publicId).append("' ");
+ } else {
+ writer.write(" SYSTEM ");
+ }
+ writer.append("'").append(docType.getSystemId()).append("'");
+ if (internalSubset != null) {
+ writer.append(" [").append(internalSubset).append("]");
+ }
+ writer.append('>').append(lineSeparator);
+ }
+
+ private void writeElement(Element element, Writer writer, int depth) throws IOException {
+ for (int i = 0; i < depth; ++i) { writer.append(' '); }
+ writer.append('<').append(element.getTagName());
+ NamedNodeMap attrs = element.getAttributes();
+ for (int i = 0, imax = attrs.getLength(); i < imax; ++i) {
+ Attr attr = (Attr) attrs.item(i);
+ writer.append(' ').append(attr.getName()).append("='").append(attr.getValue()).append("'");
+ }
+ NodeList nodes = element.getChildNodes();
+ if (nodes.getLength() == 0) {
+ // no children, so just close off the element and return
+ writer.append("/>").append(lineSeparator);
+ return;
+ }
+ writer.append('>').append(lineSeparator);
+ for (int i = 0, imax = nodes.getLength(); i < imax; ++i) {
+ Node n = nodes.item(i);
+ if (n.getNodeType() == Node.ATTRIBUTE_NODE) { continue; }
+ write(n, writer, depth + indent);
+ }
+ for (int i = 0; i < depth; ++i) { writer.append(' '); }
+ writer.append("</").append(element.getTagName()).append('>').append(lineSeparator);
+ }
+
+}
diff --git a/engine/src/xml/com/jme3/export/xml/XMLExporter.java b/engine/src/xml/com/jme3/export/xml/XMLExporter.java
new file mode 100644
index 0000000..6e7c395
--- /dev/null
+++ b/engine/src/xml/com/jme3/export/xml/XMLExporter.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.export.xml;
+
+import com.jme3.export.JmeExporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.export.Savable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+/**
+ * Part of the jME XML IO system as introduced in the google code jmexml project.
+ *
+ * @author Kai Rabien (hevee) - original author of the code.google.com jmexml project
+ * @author Doug Daniels (dougnukem) - adjustments for jME 2.0 and Java 1.5
+ */
+public class XMLExporter implements JmeExporter {
+
+ public static final String ELEMENT_MAPENTRY = "MapEntry";
+ public static final String ELEMENT_KEY = "Key";
+ public static final String ELEMENT_VALUE = "Value";
+ public static final String ELEMENT_FLOATBUFFER = "FloatBuffer";
+ public static final String ATTRIBUTE_SIZE = "size";
+
+ private DOMOutputCapsule domOut;
+
+ public XMLExporter() {
+
+ }
+
+ public boolean save(Savable object, OutputStream f) throws IOException {
+ try {
+ //Initialize Document when saving so we don't retain state of previous exports
+ this.domOut = new DOMOutputCapsule(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(), this);
+ domOut.write(object, object.getClass().getName(), null);
+ DOMSerializer serializer = new DOMSerializer();
+ serializer.serialize(domOut.getDoc(), f);
+ f.flush();
+ return true;
+ } catch (Exception ex) {
+ IOException e = new IOException();
+ e.initCause(ex);
+ throw e;
+ }
+ }
+
+ public boolean save(Savable object, File f) throws IOException {
+ return save(object, new FileOutputStream(f));
+ }
+
+ public OutputCapsule getCapsule(Savable object) {
+ return domOut;
+ }
+
+ public static XMLExporter getInstance() {
+ return new XMLExporter();
+ }
+
+}
diff --git a/engine/src/xml/com/jme3/export/xml/XMLImporter.java b/engine/src/xml/com/jme3/export/xml/XMLImporter.java
new file mode 100644
index 0000000..7a46b17
--- /dev/null
+++ b/engine/src/xml/com/jme3/export/xml/XMLImporter.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.export.xml;
+
+import com.jme3.asset.AssetInfo;
+import com.jme3.asset.AssetManager;
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.Savable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.xml.sax.SAXException;
+
+/**
+ * Part of the jME XML IO system as introduced in the google code jmexml project.
+ * @author Kai Rabien (hevee) - original author of the code.google.com jmexml project
+ * @author Doug Daniels (dougnukem) - adjustments for jME 2.0 and Java 1.5
+ */
+public class XMLImporter implements JmeImporter {
+
+ private AssetManager assetManager;
+ private DOMInputCapsule domIn;
+ int formatVersion = 0;
+
+ public XMLImporter() {
+ }
+
+ public int getFormatVersion() {
+ return formatVersion;
+ }
+
+ public AssetManager getAssetManager(){
+ return assetManager;
+ }
+
+ public void setAssetManager(AssetManager assetManager){
+ this.assetManager = assetManager;
+ }
+
+ public Object load(AssetInfo info) throws IOException{
+ assetManager = info.getManager();
+ InputStream in = info.openStream();
+ Savable obj = load(in);
+ in.close();
+ return obj;
+ }
+
+ public Savable load(File f) throws IOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(f);
+ Savable sav = load(fis);
+ return sav;
+ } finally {
+ if (fis != null) fis.close();
+ }
+ }
+
+ public Savable load(InputStream f) throws IOException {
+ try {
+ domIn = new DOMInputCapsule(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f), this);
+ return domIn.readSavable(null, null);
+ } catch (SAXException e) {
+ IOException ex = new IOException();
+ ex.initCause(e);
+ throw ex;
+ } catch (ParserConfigurationException e) {
+ IOException ex = new IOException();
+ ex.initCause(e);
+ throw ex;
+ }
+ }
+
+ public InputCapsule getCapsule(Savable id) {
+ return domIn;
+ }
+
+ public static XMLImporter getInstance() {
+ return new XMLImporter();
+ }
+
+}