Package avm

Source Code of avm.AVMEngine

package avm;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.util.*;

import javax.swing.JComponent;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

import avm.WidgetAdapter;

public class AVMEngine {
  private static final String XML_ROOT_ELEMENT_TAG = "avm";
 
  private JComponent parent;
 
  private static Map<String, WidgetAdapter> adapterForWidgetType = new HashMap<String, WidgetAdapter>();
  private static Map<Class, String> widgetTypeForComponentType  = new HashMap<Class, String>();
 
 
  public static Map<String, WidgetAdapter> getAdapterForWidgetType() {
    return adapterForWidgetType;
  }
 
 
  public static Map<Class, String> getWidgetTypeForComponentType() {
    return widgetTypeForComponentType;
  }


  public AVMEngine(JComponent parent) {
    this.parent = parent;
   
    try {
      Class.forName("avm.ButtonAdapter");
      Class.forName("avm.TextboxAdapter");
    } catch (ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
   
    // ...
  }
 
  /**
   * Construct the widgets according to the specification in a file in the AWM XML format.
   *
   * @param  fileName  the file path of the AWM XML file
   */
  public void load(String fileName) {
    // Set up the XML parser and parse the AVM XML file
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder;
        Document document = null;
    try {
      documentBuilder = documentBuilderFactory.newDocumentBuilder();
      document = documentBuilder.parse(fileName);
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
      return;
    } catch (SAXException e) {
      e.printStackTrace();
      return;
    } catch (IOException e) {
      e.printStackTrace();
      return;
    }
   
    //TODO check for duplicated property names.
    //TODO Set a property to the default value if it is not found in the AVM XML.
    //TODO Handle the case that when an unrecognized property is read.
    Element element = document.getDocumentElement();
    NodeList widgetNodeList = element.getChildNodes();
    for (int i = 0; i < widgetNodeList.getLength(); i++) {
      Node node = widgetNodeList.item(i);
      //System.out.println("node:" + node + "---" + "Node type:" + node.getNodeType()); //debug
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        //It is a widget node. Process its properties.
        String widgetTypeName = node.getNodeName();
        WidgetAdapter adapter = adapterForWidgetType.get(widgetTypeName);
       
        String widgetName = null;
        JComponent widget = adapter.New();
        Set<String> readProperties = new HashSet<String>();
       
        NodeList propertyNodeList = node.getChildNodes();
        for (int j = 0; j < propertyNodeList.getLength(); j++) {
          Node propertyNode = propertyNodeList.item(j);
          if (propertyNode.getNodeType() == Node.ELEMENT_NODE) {
            String propertyName = propertyNode.getNodeName();
            if (readProperties.contains(propertyName)) {
              // TODO Output an error message or throw an exception?
              System.err.println("The property '" + propertyName + "' is duplicated.");
            } else {
              if (propertyName.equals("name")) {
                 widgetName = propertyNode.getTextContent();
                 widget.setName(widgetName);
              } else {
                String str = propertyNode.getTextContent();
                String type = adapter.getPropertyType(propertyName);
                try {
                  adapter.setProperty(widget, propertyName,
                    convertToObject(type, str));
                } catch (Exception e) {
                  System.err.println("invalid conversion: " + str + " as " + type);
                }
              }
            }
           
            readProperties.add(propertyName);
          }
        }
       
        // Set a property to the default value if it is not found in the AVM XML.
        for (String property : adapter.getAllPropertyNames()) {
          if (!readProperties.contains(property)) {
            adapter.resetPropertyToDefaultValue(widget, property);
          }
        }
       
        parent.add(widget);
      }
    }
  }
 
  public void save(String fileName) {
    //initializeWidgetTypeLookup();
   
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = null;
        Document doc = null;
        Element root = null;
    try {
      documentBuilder = documentBuilderFactory.newDocumentBuilder();
      doc = documentBuilder.newDocument();
      root = doc.createElement(XML_ROOT_ELEMENT_TAG);
      doc.appendChild(root);
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
      return;
    }
   
   
    //Read widgets one by one and read the properties of each widget.
    //Construct the widget node and its properties nodes with values and add
    //them to the DOM tree.
    //TODO Does each widget must have a name? Handle the case if the name is not found.
    for (Component component : parent.getComponents()) {
      JComponent widget = (JComponent)component;
      String widgetTypeName = widgetTypeForComponentType.get(widget.getClass());
     
      //Add the element node for this widget
      Element widgetElement = doc.createElement(widgetTypeName);
      root.appendChild(widgetElement);
     
      WidgetAdapter adapter = adapterForWidgetType.get(widgetTypeName);
     
      Element nameElement = doc.createElement("name");
      widgetElement.appendChild(nameElement);
      Text nameText = doc.createTextNode(widget.getName());
      nameElement.appendChild(nameText);
           
      //Read the properties of this widget.
      //Record the property if it does not have a default property value.
      //If it matches the default value of the property then it does not record it in the AVM XML file.
      for (String propertyName : adapter.getAllPropertyNames()) {
        if (!adapter.hasPropertyDefaultValue(widget, propertyName)) {
          Object propertyValue = adapter.getProperty(widget, propertyName);
          String type = adapter.getPropertyType(propertyName);
         
          Element propertyElement = doc.createElement(propertyName);
          widgetElement.appendChild(propertyElement);
          if (propertyValue != null) {
            Text valueText = null;
            try {
              valueText = doc.createTextNode(
                convertToString(type, propertyValue));
            } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
            propertyElement.appendChild(valueText);
          }
        }
      }
     
    }
   
    // Write the DOM tree to the output XML file
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer;
    try {
      transformer = transformerFactory.newTransformer();
      DOMSource source = new DOMSource(doc);
      File outputFile = new File(fileName);
      StreamResult result =  new StreamResult(outputFile);
      //StreamResult result =  new StreamResult(System.out); //debug
      transformer.transform(source, result);
    } catch (TransformerConfigurationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (TransformerException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 
  Object convertToObject(String type, String str) throws Exception {
    Object obj = null;
    if (type.equals("String")) {
      obj = str;
    } else if (type.equals("int")) {
      obj = Integer.parseInt(str);
    } else if (type.equals("boolean")) {
      if (str.equalsIgnoreCase("true")) {
        obj = true;
      } else if (str.equalsIgnoreCase("false")) {
        obj = false;
      } else {
        throw new Exception();
      }
    } else if (type.equals("Color")) {
      obj = Color.decode(str);
    } else if (type.equals("Font")) {
      // TODO Define a representation of a font that is independent of
      // Java implementation
      obj = Font.decode(str);
    } else {
      throw new Exception();
    }
    return obj;
  }
 
  String convertToString(String type, Object obj) throws Exception {
    String str = null;
    if (type.equals("String")) {
      str = obj.toString();
    } else if (type.equals("int")) {
      str = obj.toString();
    } else if (type.equals("boolean")) {
      str = obj.toString();
    } else if (type.equals("Color")) {
      int rgb = ((Color)obj).getRGB();
      str = "#" + Integer.toHexString(rgb).substring(2);
    } else if (type.equals("Font")) {
      // TODO Define a representation of a font that is independent of
      // Java implementation
      str = obj.toString();
    } else {
      throw new Exception();
    }
    return str;
  }
 
}
TOP

Related Classes of avm.AVMEngine

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.