Package com.ardor3d.util.export.xml

Source Code of com.ardor3d.util.export.xml.DOMInputCapsule

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.util.export.xml;

import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.ardor3d.annotation.SavableFactory;
import com.ardor3d.image.Texture;
import com.ardor3d.renderer.state.RenderState;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.util.Ardor3dException;
import com.ardor3d.util.TextureKey;
import com.ardor3d.util.TextureManager;
import com.ardor3d.util.export.InputCapsule;
import com.ardor3d.util.export.Savable;
import com.ardor3d.util.geom.BufferUtils;
import com.google.common.collect.Lists;

/**
* Part of the ardor3d XML IO system
*/
public class DOMInputCapsule implements InputCapsule {

    private final Document _doc;
    private Element _currentElem;
    private boolean _isAtRoot = true;
    private final Map<String, Savable> _referencedSavables = new HashMap<String, Savable>();

    public DOMInputCapsule(final Document doc) {
        _doc = doc;
        _currentElem = doc.getDocumentElement();
    }

    private static String decodeString(String s) {
        if (s == null) {
            return null;
        }
        s = s.replaceAll("\\&quot;", "\"").replaceAll("\\&lt;", "<").replaceAll("\\&amp;", "&");
        return s;
    }

    private Element findFirstChildElement(final Element parent) {
        Node ret = parent.getFirstChild();
        while (ret != null && (!(ret instanceof Element))) {
            ret = ret.getNextSibling();
        }
        return (Element) ret;
    }

    private Element findChildElement(final Element parent, final 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(final Element current) {
        Node ret = current.getNextSibling();
        while (ret != null) {
            if (ret instanceof Element) {
                return (Element) ret;
            }
            ret = ret.getNextSibling();
        }
        return null;
    }

    public byte readByte(final String name, final byte defVal) throws IOException {
        byte ret = defVal;
        try {
            ret = Byte.parseByte(_currentElem.getAttribute(name));
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public byte[] readByteArray(final String name, final byte[] defVal) throws IOException {
        byte[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final byte[] tmp = new byte[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Byte.parseByte(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public byte[][] readByteArray2D(final String name, final byte[][] defVal) throws IOException {
        byte[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final byte[][] tmp = new byte[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readByteArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public int readInt(final String name, final int defVal) throws IOException {
        int ret = defVal;
        try {
            final String s = _currentElem.getAttribute(name);
            if (s.length() > 0) {
                ret = Integer.parseInt(s);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public int[] readIntArray(final String name, final int[] defVal) throws IOException {
        int[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final int[] tmp = new int[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Integer.parseInt(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public int[][] readIntArray2D(final String name, final int[][] defVal) throws IOException {
        int[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final int[][] tmp = new int[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readIntArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public float readFloat(final String name, final float defVal) throws IOException {
        float ret = defVal;
        try {
            final String s = _currentElem.getAttribute(name);
            if (s.length() > 0) {
                ret = Float.parseFloat(s);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public float[] readFloatArray(final String name, final float[] defVal) throws IOException {
        float[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final float[] tmp = new float[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Float.parseFloat(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public float[][] readFloatArray2D(final String name, final float[][] defVal) throws IOException {
        float[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size_outer = Integer.parseInt(tmpEl.getAttribute("size_outer"));
            final int size_inner = Integer.parseInt(tmpEl.getAttribute("size_outer"));

            final float[][] tmp = new float[size_outer][size_inner];

            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            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]);
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public double readDouble(final String name, final double defVal) throws IOException {
        double ret = defVal;
        try {
            final String s = _currentElem.getAttribute(name);
            if (s.length() > 0) {
                ret = Double.parseDouble(s);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public double[] readDoubleArray(final String name, final double[] defVal) throws IOException {
        double[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final double[] tmp = new double[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Double.parseDouble(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public double[][] readDoubleArray2D(final String name, final double[][] defVal) throws IOException {
        double[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final double[][] tmp = new double[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readDoubleArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public long readLong(final String name, final long defVal) throws IOException {
        long ret = defVal;
        try {
            final String s = _currentElem.getAttribute(name);
            if (s.length() > 0) {
                ret = Long.parseLong(s);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public long[] readLongArray(final String name, final long[] defVal) throws IOException {
        long[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final long[] tmp = new long[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Long.parseLong(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public long[][] readLongArray2D(final String name, final long[][] defVal) throws IOException {
        long[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final long[][] tmp = new long[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readLongArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public short readShort(final String name, final short defVal) throws IOException {
        short ret = defVal;
        try {
            final String s = _currentElem.getAttribute(name);
            if (s.length() > 0) {
                ret = Short.parseShort(s);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public short[] readShortArray(final String name, final short[] defVal) throws IOException {
        short[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final short[] tmp = new short[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Short.parseShort(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public short[][] readShortArray2D(final String name, final short[][] defVal) throws IOException {
        short[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final short[][] tmp = new short[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readShortArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public boolean readBoolean(final String name, final boolean defVal) throws IOException {
        boolean ret = defVal;
        try {
            final String s = _currentElem.getAttribute(name);
            if (s.length() > 0) {
                ret = Boolean.parseBoolean(s);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public boolean[] readBooleanArray(final String name, final boolean[] defVal) throws IOException {
        boolean[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final boolean[] tmp = new boolean[size];
            final String[] strings = tmpEl.getAttribute("data").split("\\s+");
            for (int i = 0; i < size; i++) {
                tmp[i] = Boolean.parseBoolean(strings[i]);
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public boolean[][] readBooleanArray2D(final String name, final boolean[][] defVal) throws IOException {
        boolean[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final boolean[][] tmp = new boolean[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readBooleanArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public String readString(final String name, final String defVal) throws IOException {
        String ret = defVal;
        try {
            ret = decodeString(_currentElem.getAttribute(name));
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public String[] readStringArray(final String name, final String[] defVal) throws IOException {
        String[] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final String[] tmp = new String[size];
            final NodeList nodes = tmpEl.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("String")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = ((Element) n).getAttributeNode("value").getValue();
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        // _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public String[][] readStringArray2D(final String name, final String[][] defVal) throws IOException {
        String[][] ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final String[][] tmp = new String[size][];
            final NodeList nodes = _currentElem.getChildNodes();
            int strIndex = 0;
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().contains("array")) {
                    if (strIndex < size) {
                        tmp[strIndex++] = readStringArray(n.getNodeName(), null);
                    } else {
                        throw new IOException("String array contains more elements than specified!");
                    }
                }
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        _currentElem = (Element) _currentElem.getParentNode();
        return ret;
    }

    public BitSet readBitSet(final String name, final BitSet defVal) throws IOException {
        BitSet ret = defVal;
        try {
            final BitSet set = new BitSet();
            final String bitString = _currentElem.getAttribute(name);
            final String[] strings = bitString.split("\\s+");
            for (int i = 0; i < strings.length; i++) {
                final int isSet = Integer.parseInt(strings[i]);
                if (isSet == 1) {
                    set.set(i);
                }
            }
            ret = set;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public Savable readSavable(final String name, final Savable defVal) throws IOException {
        Savable ret = defVal;

        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 (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }

        return ret;
    }

    private Savable readSavableFromCurrentElem(final Savable defVal) throws InstantiationException,
            ClassNotFoundException, IOException, IllegalAccessException {
        Savable ret = defVal;
        Savable tmp = null;

        if (_currentElem == null || _currentElem.getNodeName().equals("null")) {
            return null;
        }
        final 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");
            }

            try {
                @SuppressWarnings("unchecked")
                final Class<? extends Savable> clazz = (Class<? extends Savable>) Class.forName(className);
                final SavableFactory ann = clazz.getAnnotation(SavableFactory.class);
                if (ann == null) {
                    tmp = clazz.newInstance();
                } else {
                    tmp = (Savable) clazz.getMethod(ann.factoryMethod(), (Class<?>[]) null).invoke(null,
                            (Object[]) null);
                }
            } catch (final InstantiationException e) {
                Logger.getLogger(getClass().getName()).logp(
                        Level.SEVERE,
                        this.getClass().toString(),
                        "readSavableFromCurrentElem(Savable)",
                        "Could not access constructor of class '" + className + "'! \n"
                                + "Some types may require the annotation SavableFactory.  Please double check.");
                throw new Ardor3dException(e);
            } catch (final NoSuchMethodException e) {
                Logger.getLogger(getClass().getName())
                        .logp(Level.SEVERE,
                                this.getClass().toString(),
                                "readSavableFromCurrentElem(Savable)",
                                e.getMessage()
                                        + " \n"
                                        + "Method specified in annotation does not appear to exist or has an invalid method signature.");
                throw new Ardor3dException(e);
            } catch (final Exception e) {
                Logger.getLogger(getClass().getName()).logp(Level.SEVERE, this.getClass().toString(),
                        "readSavableFromCurrentElem(Savable)", "Exception", e);
                return null;
            }

            final String refID = _currentElem.getAttribute("reference_ID");
            if (refID.length() > 0) {
                _referencedSavables.put(refID, tmp);
            }
            if (tmp != null) {
                tmp.read(this);
                ret = tmp;
            }
        }
        return ret;
    }

    private TextureState readTextureStateFromCurrent() {
        final Element el = _currentElem;
        TextureState ret = null;
        try {
            ret = (TextureState) readSavableFromCurrentElem(null);
            final Savable[] savs = readSavableArray("texture", new Texture[0]);
            for (int i = 0; i < savs.length; i++) {
                Texture t = (Texture) savs[i];
                final TextureKey tKey = t.getTextureKey();
                t = TextureManager.loadFromKey(tKey, null, t);
                ret.setTexture(t, i);
            }
        } catch (final Exception e) {
            Logger.getLogger(DOMInputCapsule.class.getName()).log(Level.SEVERE, null, e);
        }
        _currentElem = el;
        return ret;
    }

    private Savable[] readRenderStateList(final Element fromElement, final Savable[] defVal) {
        Savable[] ret = defVal;
        try {
            final List<RenderState> tmp = new ArrayList<RenderState>();
            _currentElem = findFirstChildElement(fromElement);
            while (_currentElem != null) {
                final Element el = _currentElem;
                RenderState rs = null;
                if (el.getNodeName().equals("com.ardor3d.scene.state.TextureState")) {
                    rs = readTextureStateFromCurrent();
                } else {
                    rs = (RenderState) (readSavableFromCurrentElem(null));
                }
                if (rs != null) {
                    tmp.add(rs);
                }
                _currentElem = findNextSiblingElement(el);
            }
            ret = tmp.toArray(new RenderState[0]);
        } catch (final Exception e) {
            Logger.getLogger(DOMInputCapsule.class.getName()).log(Level.SEVERE, null, e);
        }

        return ret;
    }

    public Savable[] readSavableArray(final String name, final Savable[] defVal) throws IOException {
        Savable[] ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            if (name.equals("renderStateList")) {
                ret = readRenderStateList(tmpEl, defVal);
            } else {
                final int size = Integer.parseInt(tmpEl.getAttribute("size"));
                final Savable[] tmp = new Savable[size];
                _currentElem = findFirstChildElement(tmpEl);
                for (int i = 0; i < size; i++) {
                    tmp[i] = (readSavableFromCurrentElem(null));
                    if (i == size - 1) {
                        break;
                    }
                    _currentElem = findNextSiblingElement(_currentElem);
                }
                ret = tmp;
            }
            _currentElem = (Element) tmpEl.getParentNode();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public Savable[][] readSavableArray2D(final String name, final Savable[][] defVal) throws IOException {
        Savable[][] ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final int size_outer = Integer.parseInt(tmpEl.getAttribute("size_outer"));
            final int size_inner = Integer.parseInt(tmpEl.getAttribute("size_outer"));

            final 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();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    @SuppressWarnings("unchecked")
    public <E extends Savable> List<E> readSavableList(final String name, final List<E> defVal) throws IOException {
        List<E> ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final String s = tmpEl.getAttribute("size");
            final int size = Integer.parseInt(s);
            @SuppressWarnings("rawtypes")
            final List tmp = Lists.newArrayList();
            _currentElem = findFirstChildElement(tmpEl);
            for (int i = 0; i < size; i++) {
                tmp.add(readSavableFromCurrentElem(null));
                if (i == size - 1) {
                    break;
                }
                _currentElem = findNextSiblingElement(_currentElem);
            }
            ret = tmp;
            _currentElem = (Element) tmpEl.getParentNode();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    @SuppressWarnings("unchecked")
    public <E extends Savable> List<E>[] readSavableListArray(final String name, final List<E>[] defVal)
            throws IOException {
        List<E>[] ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }
            _currentElem = tmpEl;

            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final List<E>[] tmp = new ArrayList[size];
            for (int i = 0; i < size; i++) {
                final StringBuilder buf = new StringBuilder("SavableArrayList_");
                buf.append(i);
                final List<E> al = readSavableList(buf.toString(), null);
                tmp[i] = al;
                if (i == size - 1) {
                    break;
                }
            }
            ret = tmp;
            _currentElem = (Element) tmpEl.getParentNode();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public <E extends Savable> List<E>[][] readSavableListArray2D(final String name, final List<E>[][] defVal)
            throws IOException {
        List<E>[][] ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }
            _currentElem = tmpEl;
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));

            final List[][] tmp = new ArrayList[size][];
            for (int i = 0; i < size; i++) {
                final List[] arr = readSavableListArray("SavableArrayListArray_" + i, null);
                tmp[i] = arr;
            }
            ret = tmp;
            _currentElem = (Element) tmpEl.getParentNode();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public List<FloatBuffer> readFloatBufferList(final String name, final List<FloatBuffer> defVal) throws IOException {
        List<FloatBuffer> ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final List<FloatBuffer> tmp = new ArrayList<FloatBuffer>(size);
            _currentElem = findFirstChildElement(tmpEl);
            for (int i = 0; i < size; i++) {
                tmp.add(readFloatBuffer(null, null));
                if (i == size - 1) {
                    break;
                }
                _currentElem = findNextSiblingElement(_currentElem);
            }
            ret = tmp;
            _currentElem = (Element) tmpEl.getParentNode();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    @SuppressWarnings("unchecked")
    public <K extends Savable, V extends Savable> Map<K, V> readSavableMap(final String name, final Map<K, V> defVal)
            throws IOException {
        Map<K, V> ret;
        Element tempEl;

        if (name != null) {
            tempEl = findChildElement(_currentElem, name);
        } else {
            tempEl = _currentElem;
        }
        ret = new HashMap<K, V>();

        final NodeList nodes = tempEl.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            final Node n = nodes.item(i);
            if (n instanceof Element && n.getNodeName().equals("MapEntry")) {
                final Element elem = (Element) n;
                _currentElem = elem;
                final K key = (K) readSavable(XMLExporter.ELEMENT_KEY, null);
                final V val = (V) readSavable(XMLExporter.ELEMENT_VALUE, null);
                ret.put(key, val);
            }
        }
        _currentElem = (Element) tempEl.getParentNode();
        return ret;
    }

    @SuppressWarnings("unchecked")
    public <V extends Savable> Map<String, V> readStringSavableMap(final String name, final Map<String, V> defVal)
            throws IOException {
        Map<String, V> ret = null;
        Element tempEl;

        if (name != null) {
            tempEl = findChildElement(_currentElem, name);
        } else {
            tempEl = _currentElem;
        }
        if (tempEl != null) {
            ret = new HashMap<String, V>();

            final NodeList nodes = tempEl.getChildNodes();
            for (int i = 0; i < nodes.getLength(); i++) {
                final Node n = nodes.item(i);
                if (n instanceof Element && n.getNodeName().equals("MapEntry")) {
                    final Element elem = (Element) n;
                    _currentElem = elem;
                    final String key = _currentElem.getAttribute("key");
                    final V val = (V) 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(final String name, final FloatBuffer defVal) throws IOException {
        FloatBuffer ret = defVal;
        try {
            Element tmpEl;
            if (name != null) {
                tmpEl = findChildElement(_currentElem, name);
            } else {
                tmpEl = _currentElem;
            }
            if (tmpEl == null) {
                return defVal;
            }
            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final FloatBuffer tmp = BufferUtils.createFloatBuffer(size);
            if (size > 0) {
                final String[] strings = tmpEl.getAttribute("data").split("\\s+");
                for (final String s : strings) {
                    tmp.put(Float.parseFloat(s));
                }
                tmp.flip();
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public IntBuffer readIntBuffer(final String name, final IntBuffer defVal) throws IOException {
        IntBuffer ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final IntBuffer tmp = BufferUtils.createIntBuffer(size);
            if (size > 0) {
                final String[] strings = tmpEl.getAttribute("data").split("\\s+");
                for (final String s : strings) {
                    tmp.put(Integer.parseInt(s));
                }
                tmp.flip();
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public ByteBuffer readByteBuffer(final String name, final ByteBuffer defVal) throws IOException {
        ByteBuffer ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final ByteBuffer tmp = BufferUtils.createByteBuffer(size);
            if (size > 0) {
                final String[] strings = tmpEl.getAttribute("data").split("\\s+");
                for (final String s : strings) {
                    tmp.put(Byte.valueOf(s));
                }
                tmp.flip();
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public ShortBuffer readShortBuffer(final String name, final ShortBuffer defVal) throws IOException {
        ShortBuffer ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final ShortBuffer tmp = BufferUtils.createShortBuffer(size);
            if (size > 0) {
                final String[] strings = tmpEl.getAttribute("data").split("\\s+");
                for (final String s : strings) {
                    tmp.put(Short.valueOf(s));
                }
                tmp.flip();
            }
            ret = tmp;
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public List<ByteBuffer> readByteBufferList(final String name, final List<ByteBuffer> defVal) throws IOException {
        List<ByteBuffer> ret = defVal;
        try {
            final Element tmpEl = findChildElement(_currentElem, name);
            if (tmpEl == null) {
                return defVal;
            }

            final int size = Integer.parseInt(tmpEl.getAttribute("size"));
            final List<ByteBuffer> tmp = new ArrayList<ByteBuffer>(size);
            _currentElem = findFirstChildElement(tmpEl);
            for (int i = 0; i < size; i++) {
                tmp.add(readByteBuffer(null, null));
                if (i == size - 1) {
                    break;
                }
                _currentElem = findNextSiblingElement(_currentElem);
            }
            ret = tmp;
            _currentElem = (Element) tmpEl.getParentNode();
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    public <T extends Enum<T>> T readEnum(final String name, final Class<T> enumType, final T defVal)
            throws IOException {
        T ret = defVal;
        try {
            final String eVal = _currentElem.getAttribute(name);
            if (eVal != null && eVal.length() > 0) {
                ret = Enum.valueOf(enumType, eVal);
            }
        } catch (final Exception e) {
            final IOException ex = new IOException();
            ex.initCause(e);
            throw ex;
        }
        return ret;
    }

    @SuppressWarnings("unchecked")
    public <T extends Enum<T>> T[] readEnumArray(final String name, final Class<T> enumType, final T[] defVal)
            throws IOException {
        final String[] eVals = readStringArray(name, null);
        if (eVals != null) {
            final T[] rVal = (T[]) Array.newInstance(enumType, eVals.length);
            int i = 0;
            for (final String eVal : eVals) {
                rVal[i++] = Enum.valueOf(enumType, eVal);
            }
            return rVal;
        } else {
            return defVal;
        }
    }
}
TOP

Related Classes of com.ardor3d.util.export.xml.DOMInputCapsule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.