DescriptorTest.java :  » Scripting » InstantJ » instantj » tst » Java Open Source

Java Open Source » Scripting » InstantJ 
InstantJ » instantj » tst » DescriptorTest.java
/**
 * InstantJ
 * 
 * Copyright (C) 2002 Nils Meier
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 */
package instantj.tst;

import instantj.reflect.PropertyException;
import instantj.reflect.ReflectAccess;
import instantj.compile.CompilationFailedException;
import instantj.expression.Expression;
import instantj.expression.EvaluationFailedException;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Runs tests read from configuration descriptors
 */
public class DescriptorTest implements FileFilter {
  
  /**
   * MAIN
   */
  public static void main(String[] args) {
    
    // Disclaimer
    System.out.println("InstantJ - "+ReflectAccess.getInstance().calcClassNameOf(DescriptorTest.class));
    
    // Check the args - we need the directory folder where
    // the test-cases reside in
    if (args.length!=1) {
      System.out.println("Usage: java instantj.tst.RunTests [folder]");
      return;
    }
    
    // Check if folder exists
    File folder = new File(args[0]);
    if (!folder.exists()) {
      System.out.println("Folder "+folder+" doesn't exist!");
      return;
    }

    // Run the test
    new DescriptorTest(folder);
    
    // Done
    System.out.println("Done");
    
    // .. we want to make sure that we actually quit 
    // (could have an awt thread sticking around)
    System.exit(0); 
  }
  
  /**
   * Constructor
   */
  private DescriptorTest(File folder) {

    // Try to get a parser
    SAXParser parser;
    try {
      parser = SAXParserFactory.newInstance().newSAXParser();
    } catch (Throwable t) {
      System.out.println("Couldn't instantiate SAXParser because of "+t.getClass().getName()+"#"+t.getMessage());
      return;      
    }
    
    // Try to open the tests
    File[] files = getTests(folder);
    for (int i = 0; i < files.length; i++) {
      test(files[i],parser);
    }
    
    // Done
  }
  
  /**
   * Callback whether we accept a given file or not
   */
  public boolean accept(File file) {
    return file.getAbsolutePath().endsWith(".xml");
  }
  
  /**
   * Helper that resolves tests from given folder
   */
  private File[] getTests(File folder) {
    
    // Info
    System.out.println("Looking for *.xml in "+folder);
    
    // Here's the list
    return folder.listFiles(this);
    
  }
  
  
  /**
   * Run a single test
   */
  private void test(File test, SAXParser parser) {

    // we have to handle the case of some IO problem    
    try {
      
      // open the file
      InputStream in = new FileInputStream(test);
      
      // and parse it
      Configuration conf = parse(in, parser);
      
      // and execute it
      evaluate(test, conf);
      
      // done
      in.close();
      
    } catch (SAXException e) {
      System.out.println("Parsing test "+test.getName()+" failed because of "+e.getClass().getName()+"#"+e.getMessage());
    } catch (IOException e) {
      System.out.println("Reading test "+test.getName()+" failed because of "+e.getClass().getName()+"#"+e.getMessage());
    }
    
  }
  
  /**
   * Evaluates an expression
   */
  private void evaluate(File test, Configuration conf) {

    System.out.print("Evaluating \""+conf.getTitle()+"\" ("+test+")"); 
      
    // Try to compile the expression
    Expression ex;
    try {
      ex = new Expression(conf.getExpression(),conf.getProperties());
    } catch (CompilationFailedException cfe) {
      System.out.println(" failed because of compilation problem: "+cfe.getMessage()); 
      cfe.printErrors(System.out);
      return;
    }
    
    // Try to evaluate the expression in its context
    Object result;
    try {
      // now we create an instance for the expression and let it grab 
      // necessary properties from the map we've collected but 
      // alternatively we could set properties ourselves with :
      //   ex.getInstance().set("something", somevalue).set("else", anothervalue).evaluate().
      result = ex.getInstance(conf.getValues()).evaluate();
    } catch (PropertyException mpe) {
      System.out.println(" failed : "+mpe.getMessage()); 
      return;
    } catch (EvaluationFailedException efe) {
      System.out.println(" failed : "+efe.getMessage()); 
      return;
    }

    // Done    
    System.out.println(" resulted in ("+result.getClass().getName()+") "+result); 
    
  }
  
  /**
   * Parses a test
   */
  private Configuration parse(InputStream in, SAXParser parser) throws IOException, SAXException {
    
    ExpressionDescriptorHandler handler = new ExpressionDescriptorHandler();
    parser.parse(in, handler);
    return handler.getConfiguration();

  }
  
  /**
   * An expression that's configured in the descriptor
   */
  static class Configuration {
    
    /** the title */
    private String title = null;
    
    /** the expression */
    private String expression = null;
    
    /** the property types */
    private Map properties = new HashMap();
    
    /** the property values */
    private Map values = new HashMap();
    
    /** 
     * Helper that adds an property
     */
    void addProperty(String pName, String pType, String pValue) throws IllegalArgumentException {

      // We simply remember the tpye and value as java.lang.String and
      // rely on ReflectAccess underlying Expression to later transform
      // that into something typed
      properties.put(pName, pType);
      values.put(pName, pValue);
      
      // We could have used ReflectAccess here to provide something
      // that is already typed correctly, too
      //  Class  type  = ReflectAccess.getInstance().calcClass(pType);
      //  Object value = ReflectAccess.getInstance().calcTypedInstance(pValue, type);
      //  propertyTypes.put (pName, type);
      //  propertyValues.put(pName, value);
    }
    
    /**
     * Accessor - the expression
     */
    String getExpression() {
      return expression.toString();
    }
    
    /**
     * Accessor - the expression
     */
    void setExpression(String pExpression) {
      expression = pExpression;
    }
    
    /**
     * Accessor - the title
     */
    String getTitle() {
      return title;
    }
    
    /**
     * Accessor - the title
     */
    void setTitle(String pTitle) {
      title = pTitle;
    }
    
    /**
     * Gets the properties.
     * @return returns the mapping between property-names and -types
     */
    Map getProperties() {
      return properties;
    }
    
    /**
     * Gets the values.
     * @return returns the mapping between property-names and -values
     */
    Map getValues() {
      return values;
    }

  }
  
  
  /**
   * A SAX 'Default' Handler that knows how to read a test-case
   */
  /*package*/ static class ExpressionDescriptorHandler extends DefaultHandler {
    
    /** the result */
    private Configuration configuration = new Configuration();
    
    /** the expression we gather */
    private StringBuffer expression = new StringBuffer();
    
    /** the elements we know */
    private final static String 
      ELEM_TEST       = "test",
      ELEM_PROPERTY   = "property",
      ELEM_EXPRESSION = "expression";
      
    /** the attributes we know */
    private final static String
      ATTR_TYPE       = "type",
      ATTR_NAME       = "name",
      ATTR_VALUE      = "value";
      
    /**
     * @see DocumentHandler#startElement(String, AttributeList)
     */
    public void startElement (String uri, String localName, String elemName, Attributes attributes) throws SAXException {


      // we keep the element
      expression.append('<');
      expression.append(elemName);
      expression.append('>');
      
      // A property ?      
      if (ELEM_PROPERTY.equals(elemName)) {

        // .. get its attributes        
        String name  = attributes.getValue(ATTR_NAME );
        String type  = attributes.getValue(ATTR_TYPE );
        String value = attributes.getValue(ATTR_VALUE);
        
        // .. check validity
        if ((name==null)||(type==null)||(value==null)) {
          throw new SAXException("Element "+ELEM_PROPERTY+" requires attributes "+ATTR_NAME+"&"+ATTR_TYPE+"&"+ATTR_VALUE);
        }
        
        // .. and remember
        try {
          configuration.addProperty(name, type, value);
        } catch (IllegalArgumentException e) {
          throw new SAXException(e.getMessage()+" for attributes "+ATTR_NAME+"&"+ATTR_TYPE+"&"+ATTR_VALUE);
        }
        
      }
      
      // The expression?
      if (ELEM_EXPRESSION.equals(elemName)) {
        // .. the initial comment ends because that's the code we need
        expression.append("*/");
      }
      
      // The test?
      if (ELEM_TEST.equals(elemName)) {
        // .. get the title
        configuration.setTitle(attributes.getValue("title"));
      }
      
      // Done
    }
    
    /**
     * Receive notification of the end of an element.
     */
    public void endElement (String uri, String localName, String elemName) throws SAXException {
      // After the expression is considered to be comment again
      if (ELEM_EXPRESSION.equals(elemName)) {
        expression.append("/*");
      }
      // we keep the element
      expression.append("</");
      expression.append(elemName);
      expression.append('>');
    }    

    /**
     * Receive notification of character data inside an element.
     */
    public void characters (char ch[], int start, int length) throws SAXException {
      expression.append(ch, start, length);
    }
    
    /**
     * Returns the configuration
     */
    /*package*/ Configuration getConfiguration() {
      return configuration;
    }

    /**
     * Callback for startDocument
     */
    public void startDocument () throws SAXException {
      // we start out with a comment until we hit ELEM_EXPRESSION
      expression.append("/*");
    }    
    
    /**
     * Callback for endDocument
     */
    public void endDocument () throws SAXException {
      // we end the comment we started in the beginning
      expression.append("*/");
      // and keep the result
      configuration.setExpression(expression.toString());
    }    
    
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.