jmri.jmrit.vsdecoder.VSDecoderPreferences.java Source code

Java tutorial

Introduction

Here is the source code for jmri.jmrit.vsdecoder.VSDecoderPreferences.java

Source

package jmri.jmrit.vsdecoder;

/*
 * <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         Mark Underwood Copyright (C) 2011
 * @version         $Revision$
 */
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import jmri.jmrit.XmlFile;
import jmri.jmrit.vsdecoder.listener.ListeningSpot;
import jmri.util.FileUtil;
import jmri.util.PhysicalLocation;
import org.jdom2.Document;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class VSDecoderPreferences {

    public final static String VSDPreferencesFileName = "VSDecoderPreferences.xml";

    static public enum AudioMode {

        ROOM_AMBIENT, HEADPHONES
    }

    static public final Map<AudioMode, String> AudioModeMap;

    static {
        Map<AudioMode, String> aMap = new HashMap<AudioMode, String>();
        aMap.put(AudioMode.ROOM_AMBIENT, "RoomAmbient");
        aMap.put(AudioMode.HEADPHONES, "Headphones");
        AudioModeMap = Collections.unmodifiableMap(aMap);
    }
    static public final AudioMode DefaultAudioMode = AudioMode.ROOM_AMBIENT;

    // Private variables to hold preference values
    private boolean _autoStartEngine = false; // play engine sound w/o waiting for "Engine Start" button pressed.
    private String _defaultVSDFilePath = null;
    private String _defaultVSDFileName = null;
    private boolean _autoLoadDefaultVSDFile = false; // Automatically load a VSD file.
    private ListeningSpot _listenerPosition;
    private AudioMode _audioMode;

    // Other internal variables
    //private Dimension _winDim = new Dimension(800,600);
    private String prefFile;
    private ArrayList<PropertyChangeListener> listeners;

    public VSDecoderPreferences(String sfile) {
        prefFile = sfile;
        VSDecoderPrefsXml prefs = new VSDecoderPrefsXml();
        File file = new File(prefFile);
        Element root;

        // Set default values
        _defaultVSDFilePath = FileUtil.getExternalFilename("program:resources/vsdecoder");
        _defaultVSDFileName = "example.vsd";
        _listenerPosition = new ListeningSpot(); // default to (0, 0, 0) Orientation (0,1,0)
        _audioMode = DefaultAudioMode;

        // Try to load preferences from the file
        try {
            root = prefs.rootFromFile(file);
        } catch (java.io.FileNotFoundException e2) {
            log.info(
                    "Did not find VSDecoder preferences file.  This is normal if you haven't save the preferences before");
            root = null;
        } catch (Exception e) {
            log.error("Exception while loading VSDecoder preferences: " + e);
            root = null;
        }
        if (root != null) {
            load(root.getChild("VSDecoderPreferences"));
        }
    }

    public VSDecoderPreferences() {
    }

    public void load(org.jdom2.Element e) {
        if (e == null) {
            return;
        }
        org.jdom2.Attribute a;
        org.jdom2.Element c;
        if ((a = e.getAttribute("isAutoStartingEngine")) != null) {
            setAutoStartEngine(a.getValue().compareTo("true") == 0);
        }
        if ((a = e.getAttribute("isAutoLoadingDefaultVSDFile")) != null) {
            setAutoLoadDefaultVSDFile(a.getValue().compareTo("true") == 0);
        }
        if ((c = e.getChild("DefaultVSDFilePath")) != null) {
            setDefaultVSDFilePath(c.getValue());
        }
        if ((c = e.getChild("DefaultVSDFileName")) != null) {
            setDefaultVSDFileName(c.getValue());
        }
        if ((c = e.getChild("ListenerPosition")) != null) {
            _listenerPosition = new ListeningSpot(c);
        } else {
            _listenerPosition = new ListeningSpot();
        }
        if ((c = e.getChild("AudioMode")) != null) {
            setAudioMode(c.getValue());
        }
    }

    /**
     * An extension of the abstract XmlFile. No changes made to that class.
     *
     */
    static class VSDecoderPrefsXml extends XmlFile {
    }

    private org.jdom2.Element store() {
        org.jdom2.Element ec;
        org.jdom2.Element e = new org.jdom2.Element("VSDecoderPreferences");
        e.setAttribute("isAutoStartingEngine", "" + isAutoStartingEngine());
        e.setAttribute("isAutoLoadingDefaultVSDFile", "" + isAutoLoadingDefaultVSDFile());
        ec = new Element("DefaultVSDFilePath");
        ec.setText("" + getDefaultVSDFilePath());
        e.addContent(ec);
        ec = new Element("DefaultVSDFileName");
        ec.setText("" + getDefaultVSDFileName());
        e.addContent(ec);
        // ListenerPosition generates its own XML
        e.addContent(_listenerPosition.getXml("ListenerPosition"));
        ec = new Element("AudioMode");
        ec.setText("" + AudioModeMap.get(_audioMode));
        e.addContent(ec);
        return e;
    }

    public void set(VSDecoderPreferences tp) {
        setAutoStartEngine(tp.isAutoStartingEngine());
        setAutoLoadDefaultVSDFile(tp.isAutoLoadingDefaultVSDFile());
        setDefaultVSDFilePath(tp.getDefaultVSDFilePath());
        setDefaultVSDFileName(tp.getDefaultVSDFileName());
        setListenerPosition(tp.getListenerPosition());
        setAudioMode(tp.getAudioMode());

        if (listeners != null) {
            for (int i = 0; i < listeners.size(); i++) {
                PropertyChangeListener l = listeners.get(i);
                PropertyChangeEvent e = new PropertyChangeEvent(this, "VSDecoderPreferences", null, this);
                l.propertyChange(e);
            }
        }
    }

    public boolean compareTo(VSDecoderPreferences tp) {
        return (isAutoStartingEngine() != tp.isAutoStartingEngine()
                || isAutoLoadingDefaultVSDFile() != tp.isAutoLoadingDefaultVSDFile()
                || !(getDefaultVSDFilePath().equals(tp.getDefaultVSDFilePath()))
                || !(getDefaultVSDFileName().equals(tp.getDefaultVSDFileName()))
                || !(getListenerPosition().equals(tp.getListenerPosition()))
                || !(getAudioMode().equals(tp.getAudioMode())));
    }

    public void save() {
        if (prefFile == null) {
            return;
        }
        XmlFile xf = new XmlFile() {
        }; // odd syntax is due to XmlFile being abstract
        xf.makeBackupFile(prefFile);
        File file = new File(prefFile);
        try {
            //The file does not exist, create it before writing
            File parentDir = file.getParentFile();
            if (!parentDir.exists()) {
                if (!parentDir.mkdir()) // make directory, check result
                {
                    log.error("failed to make parent directory");
                }
            }
            if (!file.createNewFile()) // create file, check result
            {
                log.error("createNewFile failed");
            }
        } catch (Exception exp) {
            log.error("Exception while writing the new VSDecoder preferences file, may not be complete: " + exp);
        }

        try {
            Element root = new Element("vsdecoder-preferences");
            //Document doc = XmlFile.newDocument(root, XmlFile.dtdLocation+"vsdecoder-preferences.dtd");
            Document doc = XmlFile.newDocument(root);
            // add XSLT processing instruction
            // <?xml-stylesheet type="text/xsl" href="XSLT/throttle.xsl"?>
            /*TODO          java.util.Map<String,String> m = new java.util.HashMap<String,String>();
                         m.put("type", "text/xsl");
                         m.put("href", jmri.jmrit.XmlFile.xsltLocation+"throttles-preferences.xsl");
                         ProcessingInstruction p = new ProcessingInstruction("xml-stylesheet", m);
                         doc.addContent(0,p);*/
            root.setContent(store());
            xf.writeXML(file, doc);
        } catch (Exception ex) {
            log.warn("Exception in storing vsdecoder preferences xml: " + ex);
        }
    }

    public String getDefaultVSDFilePath() {
        return (_defaultVSDFilePath);
    }

    public void setDefaultVSDFilePath(String s) {
        _defaultVSDFilePath = s;
    }

    public String getDefaultVSDFileName() {
        return (_defaultVSDFileName);
    }

    public void setDefaultVSDFileName(String s) {
        _defaultVSDFileName = s;
    }

    public boolean isAutoStartingEngine() {
        return (_autoStartEngine);
    }

    public void setAutoStartEngine(boolean b) {
        _autoStartEngine = b;
    }

    public boolean isAutoLoadingDefaultVSDFile() {
        return (_autoLoadDefaultVSDFile);
    }

    public void setAutoLoadDefaultVSDFile(boolean b) {
        _autoLoadDefaultVSDFile = b;
    }

    public ListeningSpot getListenerPosition() {
        log.debug("getListenerPosition() : " + _listenerPosition.toString());
        return (_listenerPosition);
    }

    public void setListenerPosition(ListeningSpot p) {
        VSDecoderManager vm = VSDecoderManager.instance();
        vm.setListenerLocation(vm.getDefaultListenerName(), p);
        _listenerPosition = p;
    }
    // Note:  No setListenerPosition(String) for ListeningSpot implementation

    public PhysicalLocation getListenerPhysicalLocation() {
        return (_listenerPosition.getPhysicalLocation());
    }

    public void setListenerPosition(PhysicalLocation p) {
        VSDecoderManager vm = VSDecoderManager.instance();
        vm.setListenerLocation(vm.getDefaultListenerName(), new ListeningSpot(p));
        //_listenerPosition = new ListeningSpot();
        //_listenerPosition.setLocation(p);
    }

    public AudioMode getAudioMode() {
        return (_audioMode);
    }

    public void setAudioMode(AudioMode am) {
        _audioMode = am;
    }

    public void setAudioMode(String am) {
        // There's got to be a more efficient way to do this
        Set<Map.Entry<AudioMode, String>> ids = AudioModeMap.entrySet();
        Iterator<Map.Entry<AudioMode, String>> idi = ids.iterator();
        while (idi.hasNext()) {
            Map.Entry<AudioMode, String> e = idi.next();
            log.debug("    ID = " + e.getKey() + " Val = " + e.getValue());
            if (e.getValue().equals(am)) {
                _audioMode = e.getKey();
                return;
            }
        }
        // We fell out of the loop.  Must be an invalid string. Set default
        _audioMode = DefaultAudioMode;
    }

    /**
     * Add an AddressListener. AddressListeners are notified when the user
     * selects a new address and when a Throttle is acquired for that address
     *
     * @param l
     */
    public void addPropertyChangeListener(PropertyChangeListener l) {
        if (listeners == null) {
            listeners = new ArrayList<PropertyChangeListener>(2);
        }
        if (!listeners.contains(l)) {
            listeners.add(l);
        }
    }

    /**
     * Remove an AddressListener.
     *
     * @param l
     */
    public void removePropertyChangeListener(PropertyChangeListener l) {
        if (listeners == null) {
            return;
        }
        if (listeners.contains(l)) {
            listeners.remove(l);
        }
    }

    static Logger log = LoggerFactory.getLogger(VSDecoderPreferences.class.getName());
}