Package net.sf.jeters.configuration.io

Source Code of net.sf.jeters.configuration.io.XMLConfigurationWriter

/*
* JETERS – Java Extensible Text Replacement System
* Copyright (C) 2006–2008  Tobias Knerr
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
*/

package net.sf.jeters.configuration.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;

import net.sf.jeters.configuration.Configuration;
import nu.xom.*;


// TODO: all sysouts to user interface (Exceptions?)


/**
* class that reads from and writes to XML configuration files
*
* @author Tobias Knerr
*/
public class XMLConfigurationWriter implements ConfigurationStorage {
   
  /**
   * reads the configuration of a component from the corresponding xml file
   *
   * @param configuredClass  class to read configuration for; != null
   * @return                 configuration for component
   *                         or null if the file does not exist
   */
  public Configuration read(Class<?> configuredClass){

    if (configuredClass == null) {
      throw new NullPointerException("componentClass must not be null");
    }
   
    String componentName = configuredClass.getSimpleName();
   
    File configFile = getConfigFile(componentName);
     
    if (!configFile.exists()) {
      return null;
    } else{
 
      Configuration configuration = new Configuration(configuredClass);
     
      try {
     
        //get a xml-document object from the file       
       
        Builder builder = new Builder();
       
        Document configurationDocument = builder.build(configFile);
       
        //get configuration set from the xml document
       
        Element xmlRootElement = configurationDocument.getRootElement();
       
        if( xmlRootElement == null ){
          System.out.println("error: file \"" + configFile + "\" is not a valid configuration file: <configuration>-tags missing");
        }
       
        else{
       
          Elements xmlConfigurationElements = xmlRootElement.getChildElements("conf");
         
          for( int xmlConfigurationElementIndex = 0; xmlConfigurationElementIndex < xmlConfigurationElements.size(); ++ xmlConfigurationElementIndex ){
           
            Element xmlConfigurationElement = xmlConfigurationElements.get(xmlConfigurationElementIndex);       
           
            String name = null;
            String type = null;
            boolean list = false;
           
            Attribute attributeName = xmlConfigurationElement.getAttribute("name");
            if( attributeName != null ){
              name = attributeName.getValue();
            }
            else{
              System.out.println("warning: configuration data partially invalid: no name attribute at \"conf\" child element " + String.valueOf(xmlConfigurationElementIndex) );
            }
           
            Attribute attributeType = xmlConfigurationElement.getAttribute("type");
            if( attributeType != null ){
              type = attributeType.getValue();
            }
            else{
              System.out.println("warning: configuration data partially invalid: no type attribute at \"conf\" child element " + String.valueOf(xmlConfigurationElementIndex) );
            }

            Attribute attributeList = xmlConfigurationElement.getAttribute("list");
            if( attributeList != null ){
              list = stringToBoolean(attributeList.getValue());
            }
           
            if (name != null && type != null) {
             
              Field field = null;
              for (Field f : configuration.getConfigurableFields()) {
                if (f.getName().equals(name)) {
                  field = f;
                  break;
                }
              }
             
              if (field != null) {
             
                if (!list) {
                       
                  String data = null;
                 
                  if( xmlConfigurationElement.getChildCount() > 0 ){             
                    Node dataText = xmlConfigurationElement.getChild(0);             
                    if( dataText != null ){
                      data = ((Text)dataText).getValue();
                    }
                  }
                                   
                  if (data == null) {
                    data = "";
                  }
                 
                  if (type.toLowerCase().equals("integer")) {
                    configuration.setValue(field, Integer.parseInt(data));
                  } else if (type.toLowerCase().equals("float")) {
                    configuration.setValue(field, Float.parseFloat(data));
                  } else if (type.toLowerCase().equals("string")) {
                    configuration.setValue(field, data);
                  } else if (type.toLowerCase().equals("boolean")) {
                    configuration.setValue(field, stringToBoolean(data))
                  }
                 
                } else { // list
                 
                  List<String> dataList = new LinkedList<String>();
                 
                  Elements childs = xmlConfigurationElement.getChildElements("entry");
                 
                  if (childs.size() > 0) {
                    for (int i = 0; i < childs.size(); i++) {
                      dataList.add(childs.get(i).getValue());           
                    }
                  } else {
                    //note: getChild also returns the element's text
                    Text text = (Text)xmlConfigurationElement.getChild(0);
                    if (text != null) {
                      dataList.add(text.getValue());
                    }
                  }
                 
                  if (type.toLowerCase().equals("integer")) { 
 
                    List<Integer> ints = new LinkedList<Integer>();
                    for (String data : dataList) {
                      ints.add(Integer.parseInt(data));
                    }
                   
                    configuration.setValue(field,
                        ints.toArray(new Integer[ints.size()]));
 
                  } else if (type.toLowerCase().equals("float")) {
                   
                    List<Float> floats = new LinkedList<Float>();
                    for (String data : dataList) {
                      floats.add(Float.parseFloat(data));
                    }
                   
                    configuration.setValue(field,
                        floats.toArray(new Float[floats.size()]));
 
                  } else if (type.toLowerCase().equals("string")) {
 
                    configuration.setValue(field,
                        dataList.toArray(new String[dataList.size()]));
 
                  } else if (type.toLowerCase().equals("boolean")) {
 
                    List<Boolean> bools = new LinkedList<Boolean>();
                    for (String data : dataList) {
                      bools.add(stringToBoolean(data));
                    }

                    configuration.setValue(field,
                        bools.toArray(new Boolean[bools.size()]));
 
                  }
                 
                }
             
              }
             
            }
               
          }
       
        }
       
      } catch (ParsingException e) {
        System.out.println("warning: a ParsingException occurred" +
            " reading from file \"" + configFile + "\":" +
            e.toString() + "\"");
      } catch (IOException e) {
        System.out.println("warning: a IOException occurred reading" +
            " from file \"" + configFile + "\":"
            + e.toString() + "\"");
      }       
     
      return configuration;   
     
    }
   
  }
 
  /**
   * writes a configuration of a component to the corresponding
   * xml config file (if it exists)
   *
   * @param configuration  configuration to be transformed to xml, not null
   */
  public void write(Configuration configuration){
   
    if (configuration == null) {
      throw new NullPointerException("configuration must not be null");
    }
   
    String componentName = configuration.getConfiguredClass().getSimpleName();
   
    createConfigDirIfNecessary();
   
    if (configuration != null && configuration.getConfigurableFields().size() > 0) {
         
      //if there is a file named .JETERS, stop writing     
      if(!getConfigDir().isDirectory()){     
        System.err.println("error saving configuration:" +
            "can't create directory \"" + getConfigDir() +
            "\": file with that name exists")
        //TODO: log
      } else {
       
        File configFile = getConfigFile(componentName);
     
        /* create a xml tree for the elements */
       
        Element xmlConfigurationElement = new Element("configuration");
     
        for (Field field : configuration.getConfigurableFields()){
                   
          if( field != null ){

            Object value = configuration.getValue(field);
            if (value != null) {

              //create an XML element for the entry 
              Element newElement = createConfElementForField(field, value);

              if (newElement != null) {             
                //append the new element to the xmlConfigurationElement           
                xmlConfigurationElement.appendChild(newElement);             
              }

            }

          }
         
        }
       
        Document configurationDocument = new Document(xmlConfigurationElement);
       
       
        /* write the xml document to a file */
   
        try{
         
          FileOutputStream ostream = new FileOutputStream(configFile);
          Serializer configurationSerializer = new Serializer(ostream,"UTF-8");
               
          configurationSerializer.setIndent(4);
                 
          configurationSerializer.write(configurationDocument);
         
          ostream.close();
       
        } catch (IOException e) {   
          System.err.println("error saving configuration: problem" +
              " writing to file \"" + configFile +
              "\": " + e.getMessage());
          //TODO: log
        }   
       
      }
     
    }
       
  }

  /**
   * creates a xml element from a conf field
   *
   * @param entry  configuration field to create an element for, != null
   * @param entry  value of the field, != null
   * @return       xml element representing the configuration entry
   *               or null if the entry cannot be represented
   *               (usually because the value's data type is unsupported)
   */
  private Element createConfElementForField(Field field, Object value) {
   
    assert field != null && value != null;
   
    Element xmlConfElement = new Element("conf");
         
    /* get values for the attributes and the child element */
   
    xmlConfElement.addAttribute(new Attribute("name", field.getName()));

    String type;
    boolean list = false;
   
    if (int.class.isAssignableFrom(field.getType())) { 
     
      type = "integer";
      xmlConfElement.appendChild(
          String.valueOf((Integer)value));       
     
    } else if (float.class.isAssignableFrom(field.getType())) { 
     
      type = "float";
      xmlConfElement.appendChild(String.valueOf((Float)value));       
     
    } else if (String.class.isAssignableFrom(field.getType())) { 
     
      type = "string";
      xmlConfElement.appendChild(((String)value));     
     
    } else if (boolean.class.isAssignableFrom(field.getType())) { 
     
      type = "boolean";
      xmlConfElement.appendChild(Boolean.toString((Boolean)value));       
     
    } else if (int[].class.isAssignableFrom(field.getType())) { 
     
      type = "integer";
      list = true;
     
      for (Integer val : (Integer[])value) {
        Element child = new Element("entry");
        child.appendChild(val.toString());
        xmlConfElement.appendChild(child);
      }
       
    } else if (float[].class.isAssignableFrom(field.getType())) { 
     
      type = "float";
      list = true;
     
      for (Float val : (Float[])value) {
        Element child = new Element("entry");
        child.appendChild(val.toString());
        xmlConfElement.appendChild(child);
      }
     
    } else if (String[].class.isAssignableFrom(field.getType())) { 
     
      type = "string";
      list = true;
     
      for (String val : (String[])value) {
        Element child = new Element("entry");
        child.appendChild(val);
        xmlConfElement.appendChild(child);
      }
     
    } else if (boolean[].class.isAssignableFrom(field.getType())) { 
     
      type = "boolean";
      list = true;
     
      for (Boolean val : (Boolean[])value) {
        Element child = new Element("entry");
        child.appendChild(val.toString());
        xmlConfElement.appendChild(child);
      }
     
    }
   
    else {
      return null;
    }
   
    /* add attributes and child to the "xmlConfElement" */
   
    xmlConfElement.addAttribute(new Attribute("type", type));
   
    if (list) {
      xmlConfElement.addAttribute(new Attribute("list", "true"));
    }
           
    return xmlConfElement;
   
  }
 
  /**
   * provides the path of the directory for JETERS' configuration files
   *
   * @return  JETERS' config file directory
   */
  private static File getConfigDir() {
   
    String path =
      System.getProperty("user.home") + File.separator + ".JETERS";
   
    return new File(path);
  }
 
 
  /**
   * provides the path of the directory for JETERS' configuration files
   *
   * @param componentName  name of the component to get the config file for
   * @return  config file
   */
  private static File getConfigFile(String componentName) {
   
    String filename = componentName + ".xml";
   
    return new File(getConfigDir(), filename);
 
 
  /**
   * creates the directory for JETERS' configuration files if it does not
   * already exist (and no file with its name)
   */
  private static void createConfigDirIfNecessary() {
   
    File configDir = getConfigDir();
   
    if( ! configDir.exists() ){     
      configDir.mkdir();
      //read and execute access: only for owner
      configDir.setReadable(false, false);
      configDir.setReadable(true, true);
      configDir.setExecutable(false, false);
      configDir.setExecutable(true, true);
    }
       
  }
     
  private static final boolean stringToBoolean(String s) {
    return s.equalsIgnoreCase("true") || s.equals("1") || s.equals("yes");
 
 
}



TOP

Related Classes of net.sf.jeters.configuration.io.XMLConfigurationWriter

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.