jmri.managers.configurexml.AbstractAudioManagerConfigXML.java Source code

Java tutorial

Introduction

Here is the source code for jmri.managers.configurexml.AbstractAudioManagerConfigXML.java

Source

// AbstractAudioManagerConfigXML.java
package jmri.managers.configurexml;

import java.util.List;
import javax.vecmath.Vector3f;
import jmri.Audio;
import jmri.AudioException;
import jmri.AudioManager;
import jmri.InstanceManager;
import jmri.jmrit.audio.AudioBuffer;
import jmri.jmrit.audio.AudioListener;
import jmri.jmrit.audio.AudioSource;
import jmri.util.FileUtil;
import org.jdom2.Attribute;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides the abstract base and store functionality for configuring
 * AudioManagers, working with AbstractAudioManagers.
 * <P>
 * Typically, a subclass will just implement the load(Element audio) class,
 * relying on implementation here to load the individual Audio objects. Note
 * that these are stored explicitly, so the resolution mechanism doesn't need to
 * see *Xml classes for each specific Audio or AbstractAudio subclass at store
 * time.
 *
 * <hr>
 * This file is part of JMRI.
 * <P>
 * JMRI is free software; you can redistribute it and/or modify it under the
 * terms of version 2 of the GNU General Public License as published by the Free
 * Software Foundation. See the "COPYING" file for a copy of this license.
 * <P>
 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * <P>
 *
 * @author Bob Jacobsen Copyright: Copyright (c) 2002, 2008
 * @author Matthew Harris copyright (c) 2009, 2011
 * @version $Revision$
 */
public abstract class AbstractAudioManagerConfigXML extends AbstractNamedBeanManagerConfigXML {

    /**
     * Default constructor
     */
    public AbstractAudioManagerConfigXML() {
    }

    /**
     * Default implementation for storing the contents of a AudioManager
     *
     * @param o Object to store, of type AudioManager
     * @return Element containing the complete info
     */
    @Override
    public Element store(Object o) {
        Element audio = new Element("audio");
        setStoreElementClass(audio);
        AudioManager am = (AudioManager) o;
        if (am != null) {
            java.util.Iterator<String> iter = am.getSystemNameList().iterator();

            // don't return an element if there are not any audios to include
            if (!iter.hasNext()) {
                return null;
            }

            // also, don't store if we don't have any Sources or Buffers
            // (no need to store the automatically created Listener object by itself)
            if (am.getSystemNameList(Audio.SOURCE).isEmpty() && am.getSystemNameList(Audio.BUFFER).isEmpty()) {
                return null;
            }

            // finally, don't store if the only Sources and Buffers are for the
            // virtual sound decoder (VSD)
            int vsdObjectCount = 0;

            // count all VSD objects
            for (String sname : am.getSystemNameList()) {
                if (log.isDebugEnabled()) {
                    log.debug("Check if " + sname + " is a VSD object");
                }
                if (sname.length() >= 8 && sname.substring(3, 8).equalsIgnoreCase("$VSD:")) {
                    log.debug("...yes");
                    vsdObjectCount++;
                }
            }

            if (log.isDebugEnabled()) {
                log.debug("Found " + vsdObjectCount + " VSD objects of " + am.getSystemNameList(Audio.SOURCE).size()
                        + am.getSystemNameList(Audio.BUFFER).size() + " objects");
            }

            // check if the total number of Sources and Buffers is equal to
            // the number of VSD objects - if so, exit.
            if (am.getSystemNameList(Audio.SOURCE).size()
                    + am.getSystemNameList(Audio.BUFFER).size() == vsdObjectCount) {
                log.debug("Only VSD objects - nothing to store");
                return null;
            }

            // store global information
            audio.setAttribute("distanceattenuated",
                    am.getActiveAudioFactory().isDistanceAttenuated() ? "yes" : "no");

            // store the audios
            while (iter.hasNext()) {
                String sname = iter.next();
                if (sname == null) {
                    log.error("System name null during store");
                    continue;
                }
                if (log.isDebugEnabled()) {
                    log.debug("system name is " + sname);
                }

                if (sname.length() >= 8 && sname.substring(3, 8).equalsIgnoreCase("$VSD:")) {
                    if (log.isDebugEnabled()) {
                        log.debug("Skipping storage of VSD object " + sname);
                    }
                    continue;
                }

                Audio a = am.getBySystemName(sname);

                // Transient objects for current element and any children
                Element e = null;
                Element ce = null;

                int type = a.getSubType();
                if (type == Audio.BUFFER) {
                    AudioBuffer ab = (AudioBuffer) a;
                    e = new Element("audiobuffer").setAttribute("systemName", sname);
                    e.addContent(new Element("systemName").addContent(sname));

                    // store common part
                    storeCommon(ab, e);

                    // store sub-type specific data
                    ce = new Element("url").addContent("" + FileUtil.getPortableFilename(ab.getURL()));
                    e.addContent(ce);

                    ce = new Element("looppoint");
                    ce.setAttribute("start", "" + ab.getStartLoopPoint());
                    ce.setAttribute("end", "" + ab.getEndLoopPoint());
                    e.addContent(ce);

                    ce = new Element("streamed");
                    ce.addContent("" + (ab.isStreamed() ? "yes" : "no"));
                    e.addContent(ce);
                } else if (type == Audio.LISTENER) {
                    AudioListener al = (AudioListener) a;
                    e = new Element("audiolistener").setAttribute("systemName", sname);
                    e.addContent(new Element("systemName").addContent(sname));

                    // store common part
                    storeCommon(al, e);

                    // store sub-type specific data
                    ce = new Element("position");
                    ce.setAttribute("x", "" + al.getPosition().x);
                    ce.setAttribute("y", "" + al.getPosition().y);
                    ce.setAttribute("z", "" + al.getPosition().z);
                    e.addContent(ce);

                    ce = new Element("velocity");
                    ce.setAttribute("x", "" + al.getVelocity().x);
                    ce.setAttribute("y", "" + al.getVelocity().y);
                    ce.setAttribute("z", "" + al.getVelocity().z);
                    e.addContent(ce);

                    ce = new Element("orientation");
                    ce.setAttribute("atX", "" + al.getOrientation(Audio.AT).x);
                    ce.setAttribute("atY", "" + al.getOrientation(Audio.AT).y);
                    ce.setAttribute("atZ", "" + al.getOrientation(Audio.AT).z);
                    ce.setAttribute("upX", "" + al.getOrientation(Audio.UP).x);
                    ce.setAttribute("upY", "" + al.getOrientation(Audio.UP).y);
                    ce.setAttribute("upZ", "" + al.getOrientation(Audio.UP).z);
                    e.addContent(ce);

                    ce = new Element("gain");
                    ce.addContent("" + al.getGain());
                    e.addContent(ce);

                    ce = new Element("metersperunit");
                    ce.addContent("" + al.getMetersPerUnit());
                    e.addContent(ce);
                } else if (type == Audio.SOURCE) {
                    AudioSource as = (AudioSource) a;
                    e = new Element("audiosource").setAttribute("systemName", sname);
                    e.addContent(new Element("systemName").addContent(sname));

                    // store common part
                    storeCommon(as, e);

                    // store sub-type specific data
                    ce = new Element("position");
                    ce.setAttribute("x", "" + as.getPosition().x);
                    ce.setAttribute("y", "" + as.getPosition().y);
                    ce.setAttribute("z", "" + as.getPosition().z);
                    e.addContent(ce);

                    ce = new Element("velocity");
                    ce.setAttribute("x", "" + as.getVelocity().x);
                    ce.setAttribute("y", "" + as.getVelocity().y);
                    ce.setAttribute("z", "" + as.getVelocity().z);
                    e.addContent(ce);

                    ce = new Element("assignedbuffer");
                    if (as.getAssignedBuffer() != null) {
                        ce.addContent("" + as.getAssignedBufferName());
                    }
                    e.addContent(ce);

                    ce = new Element("gain");
                    ce.addContent("" + as.getGain());
                    e.addContent(ce);

                    ce = new Element("pitch");
                    ce.addContent("" + as.getPitch());
                    e.addContent(ce);

                    ce = new Element("distances");
                    ce.setAttribute("ref", "" + as.getReferenceDistance());
                    float f;
                    if ((f = as.getMaximumDistance()) != Audio.MAX_DISTANCE) {
                        ce.setAttribute("max", "" + f);
                    }
                    e.addContent(ce);

                    ce = new Element("loops");
                    ce.setAttribute("min", "" + as.getMinLoops());
                    ce.setAttribute("max", "" + as.getMaxLoops());
                    //                    ce.setAttribute("mindelay", ""+as.getMinLoopDelay());
                    //                    ce.setAttribute("maxdelay", ""+as.getMaxLoopDelay());
                    e.addContent(ce);

                    ce = new Element("fadetimes");
                    ce.setAttribute("in", "" + as.getFadeIn());
                    ce.setAttribute("out", "" + as.getFadeOut());
                    e.addContent(ce);

                    ce = new Element("dopplerfactor");
                    ce.addContent("" + as.getDopplerFactor());
                    e.addContent(ce);

                    ce = new Element("positionrelative");
                    ce.addContent("" + (as.isPositionRelative() ? "yes" : "no"));
                    e.addContent(ce);
                }

                log.debug("store Audio " + sname);
                audio.addContent(e);

            }
        }
        return audio;
    }

    /**
     * Subclass provides implementation to create the correct top element,
     * including the type information. Default implementation is to use the
     * local class here.
     *
     * @param audio The top-level element being created
     */
    abstract public void setStoreElementClass(Element audio);

    @Override
    public void load(Element element, Object o) {
        log.error("Invalid method called");
    }

    /**
     * Create a AudioManager object of the correct class, then register and fill
     * it.
     *
     * @param audio Top level Element to unpack.
     * @return true if successful
     */
    @Override
    abstract public boolean load(Element audio);

    /**
     * Utility method to load the individual Audio objects. If there's no
     * additional info needed for a specific Audio type, invoke this with the
     * parent of the set of Audio elements.
     *
     * @param audio Element containing the Audio elements to load.
     */
    @SuppressWarnings("unchecked")
    public void loadAudio(Element audio) {

        AudioManager am = InstanceManager.audioManagerInstance();

        // Count number of loaded Audio objects
        int loadedObjects = 0;

        // Load buffers first
        List<Element> audioList = audio.getChildren("audiobuffer");
        if (log.isDebugEnabled()) {
            log.debug("Found " + audioList.size() + " Audio Buffer objects");
        }

        for (int i = 0; i < audioList.size(); i++) {
            Element e = audioList.get(i);

            String sysName = getSystemName(e);
            if (sysName == null) {
                log.warn("unexpected null in systemName " + (e) + " " + (e).getAttributes());
                break;
            }

            String userName = getUserName(e);

            if (log.isDebugEnabled()) {
                log.debug("create Audio: (" + sysName + ")(" + (userName == null ? "<null>" : userName) + ")");
            }
            try {
                AudioBuffer ab = (AudioBuffer) am.newAudio(sysName, userName);

                // load common parts
                loadCommon(ab, e);

                // load sub-type specific parts
                // Transient objects for reading child elements
                Element ce;
                String value;

                if ((ce = e.getChild("url")) != null) {
                    ab.setURL(ce.getValue());
                }

                if ((ce = e.getChild("looppoint")) != null) {
                    if ((value = ce.getAttributeValue("start")) != null) {
                        ab.setStartLoopPoint(Integer.parseInt(value));
                    }
                    if ((value = ce.getAttributeValue("end")) != null) {
                        ab.setEndLoopPoint(Integer.parseInt(value));
                    }
                }

                if ((ce = e.getChild("streamed")) != null) {
                    ab.setStreamed(ce.getValue().equals("yes"));
                }

            } catch (AudioException ex) {
                log.error("Error loading AudioBuffer (" + sysName + "): " + ex);
            }
        }
        loadedObjects += audioList.size();

        // Now load sources
        audioList = audio.getChildren("audiosource");
        if (log.isDebugEnabled()) {
            log.debug("Found " + audioList.size() + " Audio Source objects");
        }

        for (int i = 0; i < audioList.size(); i++) {
            Element e = audioList.get(i);

            String sysName = getSystemName(e);
            if (sysName == null) {
                log.warn("unexpected null in systemName " + (e) + " " + (e).getAttributes());
                break;
            }

            String userName = getUserName(e);

            if (log.isDebugEnabled()) {
                log.debug("create Audio: (" + sysName + ")(" + (userName == null ? "<null>" : userName) + ")");
            }
            try {
                AudioSource as = (AudioSource) am.newAudio(sysName, userName);

                // load common parts
                loadCommon(as, e);

                // load sub-type specific parts
                // Transient objects for reading child elements
                Element ce;
                String value;

                if ((ce = e.getChild("position")) != null) {
                    as.setPosition(new Vector3f(Float.parseFloat(ce.getAttributeValue("x")),
                            Float.parseFloat(ce.getAttributeValue("y")),
                            Float.parseFloat(ce.getAttributeValue("z"))));
                }

                if ((ce = e.getChild("velocity")) != null) {
                    as.setVelocity(new Vector3f(Float.parseFloat(ce.getAttributeValue("x")),
                            Float.parseFloat(ce.getAttributeValue("y")),
                            Float.parseFloat(ce.getAttributeValue("z"))));
                }

                if ((ce = e.getChild("assignedbuffer")) != null) {
                    if (ce.getValue().length() != 0 && !ce.getValue().equals("null")) {
                        as.setAssignedBuffer(ce.getValue());
                    }
                }

                if ((ce = e.getChild("gain")) != null && ce.getValue().length() != 0) {
                    as.setGain(Float.parseFloat(ce.getValue()));
                }

                if ((ce = e.getChild("pitch")) != null && ce.getValue().length() != 0) {
                    as.setPitch(Float.parseFloat(ce.getValue()));
                }

                if ((ce = e.getChild("distances")) != null) {
                    if ((value = ce.getAttributeValue("ref")) != null) {
                        as.setReferenceDistance(Float.parseFloat(value));
                    }
                    if ((value = ce.getAttributeValue("max")) != null) {
                        as.setMaximumDistance(Float.parseFloat(value));
                    }
                }

                if ((ce = e.getChild("loops")) != null) {
                    if ((value = ce.getAttributeValue("min")) != null) {
                        as.setMinLoops(Integer.parseInt(value));
                    }
                    if ((value = ce.getAttributeValue("max")) != null) {
                        as.setMaxLoops(Integer.parseInt(value));
                    }
                    //                    if ((value = ce.getAttributeValue("mindelay"))!=null)
                    //                        as.setMinLoopDelay(Integer.parseInt(value));
                    //                    if ((value = ce.getAttributeValue("maxdelay"))!=null)
                    //                        as.setMaxLoopDelay(Integer.parseInt(value));
                }

                if ((ce = e.getChild("fadetimes")) != null) {
                    if ((value = ce.getAttributeValue("in")) != null) {
                        as.setFadeIn(Integer.parseInt(value));
                    }
                    if ((value = ce.getAttributeValue("out")) != null) {
                        as.setFadeOut(Integer.parseInt(value));
                    }
                }

                if ((ce = e.getChild("dopplerfactor")) != null && ce.getValue().length() != 0) {
                    as.setDopplerFactor(Float.parseFloat(ce.getValue()));
                }

                if ((ce = e.getChild("positionrelative")) != null) {
                    as.setPositionRelative(ce.getValue().equals("yes"));
                }

            } catch (AudioException ex) {
                log.error("Error loading AudioSource (" + sysName + "): " + ex);
            }
        }
        loadedObjects += audioList.size();

        // Finally, load Listeners if needed
        if (loadedObjects > 0) {
            audioList = audio.getChildren("audiolistener");
            if (log.isDebugEnabled()) {
                log.debug("Found " + audioList.size() + " Audio Listener objects");
            }

            for (int i = 0; i < audioList.size(); i++) {
                Element e = audioList.get(i);

                String sysName = getSystemName(e);
                if (sysName == null) {
                    log.warn("unexpected null in systemName " + (e) + " " + (e).getAttributes());
                    break;
                }

                String userName = getUserName(e);

                if (log.isDebugEnabled()) {
                    log.debug("create Audio: (" + sysName + ")(" + (userName == null ? "<null>" : userName) + ")");
                }
                try {
                    AudioListener al = (AudioListener) am.newAudio(sysName, userName);

                    // load common parts
                    loadCommon(al, e);

                    // load sub-type specific parts
                    // Transient object for reading child elements
                    Element ce;

                    if ((ce = e.getChild("position")) != null) {
                        al.setPosition(new Vector3f(Float.parseFloat(ce.getAttributeValue("x")),
                                Float.parseFloat(ce.getAttributeValue("y")),
                                Float.parseFloat(ce.getAttributeValue("z"))));
                    }

                    if ((ce = e.getChild("velocity")) != null) {
                        al.setVelocity(new Vector3f(Float.parseFloat(ce.getAttributeValue("x")),
                                Float.parseFloat(ce.getAttributeValue("y")),
                                Float.parseFloat(ce.getAttributeValue("z"))));
                    }

                    if ((ce = e.getChild("orientation")) != null) {
                        al.setOrientation(
                                new Vector3f(Float.parseFloat(ce.getAttributeValue("atX")),
                                        Float.parseFloat(ce.getAttributeValue("atY")),
                                        Float.parseFloat(ce.getAttributeValue("atZ"))),
                                new Vector3f(Float.parseFloat(ce.getAttributeValue("upX")),
                                        Float.parseFloat(ce.getAttributeValue("upY")),
                                        Float.parseFloat(ce.getAttributeValue("upZ"))));
                    }

                    if ((ce = e.getChild("gain")) != null) {
                        al.setGain(Float.parseFloat(ce.getValue()));
                    }

                    if ((ce = e.getChild("metersperunit")) != null) {
                        al.setMetersPerUnit(Float.parseFloat((ce.getValue())));
                    }

                } catch (AudioException ex) {
                    log.error("Error loading AudioListener (" + sysName + "): " + ex);
                }
            }
            Attribute a;
            if ((a = audio.getAttribute("distanceattenuated")) != null) {
                am.getActiveAudioFactory().setDistanceAttenuated(a.getValue().equals("yes"));
            }
        }
    }

    @Override
    public int loadOrder() {
        return InstanceManager.audioManagerInstance().getXMLOrder();
    }

    private static final Logger log = LoggerFactory.getLogger(AbstractAudioManagerConfigXML.class.getName());
}

/* $(#)AbstractAudioManagerConfigXML.java */