Package edu.stanford.genetics.treeview

Source Code of edu.stanford.genetics.treeview.XmlConfig

/* BEGIN_HEADER                                              Java TreeView
*
* $Author: alokito $
* $RCSfile: XmlConfig.java,v $
* $Revision: 1.20 $
* $Date: 2010-05-02 13:57:28 $
* $Name:  $
*
* This file is part of Java TreeView
* Copyright (C) 2001-2003 Alok Saldanha, All Rights Reserved. Modified by Alex Segal 2004/08/13. Modifications Copyright (C) Lawrence Berkeley Lab.
*
* This software is provided under the GNU GPL Version 2. In particular,
*
* 1) If you modify a source file, make a comment in it containing your name and the date.
* 2) If you distribute a modified version, you must do it under the GPL 2.
* 3) Developers are encouraged but not required to notify the Java TreeView maintainers at alok@genome.stanford.edu when they make a useful addition. It would be nice if significant contributions could be merged into the main distribution.
*
* A full copy of the license can be found in gpl.txt or online at
* http://www.gnu.org/licenses/gpl.txt
*
* END_HEADER
*/
package edu.stanford.genetics.treeview;

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.JOptionPane;

import net.n3.nanoxml.IXMLElement;
import net.n3.nanoxml.IXMLParser;
import net.n3.nanoxml.IXMLReader;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
import net.n3.nanoxml.XMLException;
import net.n3.nanoxml.XMLParserFactory;
import net.n3.nanoxml.XMLWriter;

/**
* This is a generic class for maintaining a configuration registry
* for documents. The root element is managed by this class, and
* configuration should be stored in children of the root.
*
* The class is actually implemented as wrapper around XMLElement that
* is associated with a file, and knows how to store itself.
*/
public class XmlConfig {
    /**
     * Construct new configuration information source
     *
     * @param xmlFile xml file associated with configuration info
     */
   public XmlConfig(String xmlFile, String tag) {
     file = xmlFile;
     XMLElement el = null;
     boolean fileMissing = false;
     try {
       try{
         try {
           IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
           // IXMLReader reader = StdXMLReader.fileReader(file); // fails on pc
           BufferedReader breader = new BufferedReader(new FileReader(file));
           IXMLReader reader = new StdXMLReader(breader);
           parser.setReader(reader);
           el = (XMLElement) parser.parse();
           if (el == null) {
             el = promptToOverwrite(xmlFile, tag);
           } else {
             LogBuffer.println("created xml config from file " + file);
           }
         } catch (java.io.FileNotFoundException e) {
           LogBuffer.println("File not found, will try from URL");
           fileMissing = true;
           url = new URL(xmlFile);
           el = getXMLElementFromURL();
         } catch (java.security.AccessControlException e) {
           LogBuffer.println("AccessControlException, will try from URL");
           url = new URL(xmlFile);
           el = getXMLElementFromURL();
         }
       } catch (java.net.MalformedURLException e) {
         if (!file.contains(":")) {
           url = new URL("file://" + xmlFile);
           el = getXMLElementFromURL();
         } else if (fileMissing) {
           // well, let's make our own...
           el = makeNewConfig(tag);
         } else {
       System.out.println("Invalid URL");
       System.out.println(e);
         }
       }
     } catch (XMLException ex) {
       try {
         el = promptToOverwrite(xmlFile, tag);
       } catch (Exception e) {
         System.out.println("Problem opening window: " + e.toString());
         System.out.println("Error parsing XML code in configuration file");
         System.out.println(file);
         System.out.println("Manually deleting file may fix, but you'll lose settings.");
         System.out.println("error was: " + ex);
         file = null;
         el = new XMLElement(tag);
       }
     } catch (java.io.FileNotFoundException e) {
       // well, let's make our own...
       el = makeNewConfig(tag);
     } catch (Exception ex) {
       System.out.println("Unknown Exception");
       System.out.println(ex);
     }
     root = new XmlConfigNode(el);
   }
  private XMLElement promptToOverwrite(String xmlFile, String tag) {
    XMLElement el;
    int response = JOptionPane.showConfirmDialog (null, "Problem Parsing Settings " + xmlFile + ", Should I replace?", "Replace Faulty Settings File?", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
     if (response == JOptionPane.OK_OPTION) {
       el = makeNewConfig(tag);
     } else {
       LogBuffer.println("Using dummy config nodes");
       file = null;
       el = new XMLElement(tag);
     }
    return el;
  }
   private XMLElement makeNewConfig(String tag) {
       LogBuffer.println("Making new configuration file " + file);
       changed = true;
       return  new XMLElement(tag);
   }
  
    /**
     * Construct new configuration information source
     *
     * @param xmlUrl url from which the text came from, since nanoxml sucks so damn hard.
     */
   public XmlConfig(java.net.URL xmlUrl, String tag) {
     url = xmlUrl;
     XMLElement el = null;
     if (url != null) {
       try {
          el = getXMLElementFromURL();
       } catch (XMLException ex) {
         LogBuffer.println("Error parsing XML code in configuration url");
         LogBuffer.println(url.toString());
         ex.printStackTrace();
         url = null;
         el = new XMLElement(ex.toString());
       } catch (java.security.AccessControlException sec) {
         sec.printStackTrace();
         throw sec;
       } catch (Exception ex) {
         //      el = new XMLElement(ex.toString());
         LogBuffer.println(ex.toString());
         ex.printStackTrace();
       }
     }
    
     if (el == null) {
       el = new XMLElement(tag);
     }
    
     root = new XmlConfigNode(el);
   }
    /**
     * This factors out the common code to open an XMLElement from a URL
     * It is used by the URL constructor, and also as a fallback by the file
     * constructor.
     *
     * @return an XMLElement representing the contents of the file
     * @throws IOException
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws XMLException
     */
    private XMLElement getXMLElementFromURL() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, XMLException {
      XMLElement el;
      String xmlText     = "";
      Reader st          = new InputStreamReader(url.openStream());
      int ch             = st.read();
      while (ch != -1) {
        char[] cbuf  = new char[1];
        cbuf[0] = (char) ch;
        xmlText = xmlText + new String(cbuf);
        ch = st.read();
      }
IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
Reader breader = new StringReader(xmlText);
IXMLReader reader = new StdXMLReader(breader);
parser.setReader(reader);
el = (XMLElement) parser.parse();
      return el;
    }

    /**
     * returns node if it exists, otherwise makes a new one.
     */
    public ConfigNode getNode(String name) {
  ConfigNode t =root.fetchFirst(name);
  // just return if exists
  if (t != null) return t;
  //otherwise, create and return
  return root.create(name);
    }

    /**
     * returns node if it exists, otherwise makes a new one.
     */
    public ConfigNode getRoot() {
        return root;
    }

    /**
     * Store current configuration data structure in XML file
     *
     */
   public void store() {
     if (changed == false) {
       LogBuffer.println("Not printing config to file, config is unchanged.");
       return;
     }
     if (file == null) {
       LogBuffer.println("Not printing config to file, file is null.");
       return;
     }
     try {
       OutputStream os = new FileOutputStream(file);
       XMLWriter w = new XMLWriter(os);
       w.write(root.root);
       changed = false;
       LogBuffer.println("Successfully stored config file " + file);
     } catch (Exception e) {
       LogBuffer.logException(e);
       System.out.println("Caught exception " + e);
     }
   }
   
    /**
     * Unit test, tries to load arg[0] as an xml file
     *
     * @param args Command line arguments
     */
    public static void main(String[] args) {
  XmlConfig c = new XmlConfig(args[0], "TestConfig")
  System.out.println(c);
  c.store();
    }
   
    public String toString() {
  return "XmlConfig object based on file " + file + "\n"
      + " url " + url + "\n" + root;
    }

    // inner class, used to implement ConfigNode
    private class XmlConfigNode implements ConfigNode{
  IXMLElement root;
  public XmlConfigNode(IXMLElement e) {
      root = e;
  }
  public void store() {
    XmlConfig.this.store();
  }
  public ConfigNode create(String name) {
    if (root == null) {
      LogBuffer.println("Warning: root is null, creating dummy config node");
      return new DummyConfigNode(name);
    }
      XMLElement kid = new XMLElement(name);
      root.addChild(kid);
      XmlConfig.this.changed = true;
      return new XmlConfigNode(kid);
   }
  public ConfigNode[] fetch(String name) {
      Vector kids = root.getChildrenNamed(name);
      ConfigNode [] ret = new XmlConfigNode[kids.size()];
      for (int i = 0; i < kids.size(); i++) {
    ret[i] = new XmlConfigNode((XMLElement) kids.elementAt(i));
      }
      return ret;
  }
 
  public ConfigNode fetchFirst(String string) {
      if (root == null) return null;
      IXMLElement kid = root.getFirstChildNamed(string);
      if (kid == null) return null;
      return new XmlConfigNode(kid);
  }
  public ConfigNode fetchOrCreate(String string) {
    ConfigNode t = fetchFirst(string);
    // just return if exists
    if (t != null) return t;
    //otherwise, create and return
    return create(string);
  }

  public boolean equals(Object cn) {
      return (((XmlConfigNode)cn).root == root);
  }
   
  public void remove(ConfigNode configNode) {
      root.removeChild(((XmlConfigNode)configNode).root);
      XmlConfig.this.changed = true;
  }

  public void removeAll(String string) {
      ConfigNode [] ret = fetch(string);
      for (int i = 0; i < ret.length; i++) {
    remove(ret[i]);
      }
  }

  public void setLast(ConfigNode configNode) {
      remove(configNode);
      root.addChild(((XmlConfigNode) configNode).root);
      XmlConfig.this.changed = true;
  }
 
  /**
   * determine if a particular attribute is defined for this node.
   */
   public boolean hasAttribute(String string) {
     return root.hasAttribute(string);
   }

  public double getAttribute(String string, double d) {
      Double val = Double.valueOf(root.getAttribute(string, Double.toString(d)));
      return val.doubleValue();
  }
  public int getAttribute(String string, int i) {
      return root.getAttribute(string, i);
  }
  public String getAttribute(String string, String dval) {
      return root.getAttribute(string, dval);
  }

  public void setAttribute(String att, double val, double dval) {
      double cur = getAttribute(att, dval);
      if (cur != val) {
    XmlConfig.this.changed = true;
    root.setAttribute(att, Double.toString(val));
      }
  }

  public void setAttribute(String att, int val, int dval) {
      int cur = getAttribute(att, dval);
      if (cur != val) {
    XmlConfig.this.changed = true;
    root.setAttribute(att, Integer.toString(val));
      }
  }
  public void setAttribute(String att, String val, String dval) {
      String cur = getAttribute(att, dval);
      if ((cur == null) || (!cur.equals(val))) {
    XmlConfig.this.changed = true;
    root.setAttribute(att, val);
      }
  }
  public String toString() {
      String ret = "Root:" + root.getFullName() + "\n";
      for (Enumeration e = root.enumerateChildren();
     e.hasMoreElements(); ) {
    ret += " " + ((XMLElement) e.nextElement()).getFullName() + "\n";
      }
      return ret;
  }
    }
   
    private String file = null;
  private java.net.URL url = null;
    private XmlConfigNode root = null;
    private boolean changed = false;
   
    /**
     * This is a non-object-oriented general purpose static method
     * to create a window listener that will call ConfigNode.store()
     * when the window it is listening to is closed. There is nothing
     * particular to the XmlConfigNode class about it, but I can't think
     * of a better place to put it.
     *
     * Wherenever a settings panel which affects the config is closed, we want those changes to be saved.
   *
   * returns a WindowListener which will store theconfig every time a window it listens on is closed.
   *
     * @param node node to store
     * @return window listener to attach to windows
     */
    public static WindowListener getStoreOnWindowClose(final ConfigNode node) {
     // don't share, or you might end up listening to stale old windows...
     // do window listeners keep a pointer to the things they listen to, or is it the other way around?
     // it seems like it's probably the other way around.
     // in which case, it's bad for observable things to stay around for longer than their observers.
     // anyways, the overhead of making a new one is pretty small.
     return new WindowListener() {
         public void windowActivated(WindowEvent e) {
           // nothing...
         }
         public void windowClosed(WindowEvent e) {
           node.store();
         }
         public void windowClosing(WindowEvent e) {
           // nothing...
         }
         public void windowDeactivated(WindowEvent e) {
           // nothing...
         }
         public void windowDeiconified(WindowEvent e) {
           // nothing...
         }
         public void windowIconified(WindowEvent e) {
           // nothing...
         }
         public void windowOpened(WindowEvent e) {
           // nothing...
         }
     };
    }
    /**
     *  change the file that this xml config is backed by
     *  and store the config
     * 
     * @param file
     */
  public void setFile(String file) {
    this.file = file;
    changed = true;
    store();
  }
}
TOP

Related Classes of edu.stanford.genetics.treeview.XmlConfig

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.