Package com.sun.msv.generator

Source Code of com.sun.msv.generator.Driver$CommandLineException

/*
* @(#)$Id: Driver.java 1579 2003-07-16 20:49:53Z kohsuke $
*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the proprietary information of Sun Microsystems, Inc. 
* Use is subject to license terms.
*
*/
package com.sun.msv.generator;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.Random;
import java.util.Set;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import com.sun.msv.driver.textui.DebugController;
import com.sun.msv.grammar.ElementExp;
import com.sun.msv.grammar.Expression;
import com.sun.msv.grammar.ExpressionPool;
import com.sun.msv.grammar.Grammar;
import com.sun.msv.grammar.relax.RELAXModule;
import com.sun.msv.grammar.util.RefExpRemover;
import com.sun.msv.grammar.xmlschema.XMLSchemaGrammar;
import com.sun.msv.reader.dtd.DTDReader;
import com.sun.msv.reader.util.GrammarLoader;
import com.sun.msv.relaxns.grammar.RELAXGrammar;
import com.sun.msv.util.StringPair;
import com.sun.msv.verifier.Verifier;
import com.sun.msv.verifier.regexp.ElementsOfConcernCollector;
import com.sun.msv.verifier.regexp.REDocumentDeclaration;
import com.sun.msv.verifier.util.ErrorHandlerImpl;
import com.sun.msv.verifier.util.IgnoreErrorHandler;

/**
* command line driver.
*
* @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a>
*/
public class Driver {
 
  private static void usage() {
    System.err.println(
      "Sun XMLGenerator\n"+
      "----------------\n"+
      "Usage: XMLGenerator <options> <schema> [<output name>]\n"+
      "Options:\n"+
      "  -dtd      : use a DTD as a schema\n"+
      "  -ascii    : use US-ASCII characters only\n"+
      "  -seed <n> : set random seed\n"+
      "  -depth <n>: set cut back depth\n"+
      "  -width <n>: maximum number of times '*'/'+' are repeated\n" +
      "  -n <n>    : # of files to be generated\n" +
      "  -warning  : show warnings.\n"+
      "  -quiet    : be quiet.\n"+
            "  -root {<namespaceURI>}<localName>\n"+
            "      fix the root element to the given element\n"+
      "  -encoding <str>\n"+
      "      output encoding (Java name)\n"+
      "  -example <filename>\n"+
      "      use the given file as an example. tokens found in the example\n"+
      "      is used to generate documents\n"+
      "  -error <n>/<m>\n"+
      "      error ratio. generate n errors per m elemnts (average).\n"+
      "      to control error generation, see manual for details.\n"+
      "  -nocomment: suppress insertion of comments that indicate generated errors.\n"+
      "\n"+
      "  <output name> must include one '$'. '$' will be replaced by number.\n"+
      "  e.g., test.$.xml -> test.1.xml test.2.xml test.3.xml ...\n"+
      "  if omitted, generated file will be sent to stdout.\n"
      );
  }

  public static void main( String[] args ) throws Exception {
    try {
      Driver driver = new Driver();
      try {
        driver.parseArguments(args);
      } catch( CommandLineException e ) {
                System.err.println(e.getMessage());
        usage();
        System.exit(-1);
      }
     
      System.exit( driver.run(System.err) );
    } catch( DataTypeGenerator.GenerationException e ) {
      System.err.println(e.getMessage());
    }
  }
 
  protected double getRatio( String s ) {
    int idx = s.indexOf('/');
    double n = Double.parseDouble(s.substring(0,idx));
    double m = Double.parseDouble(s.substring(idx+1));
           
    double ratio = n/m;
           
    if( ratio<=0 || ratio>1 ) {
      System.err.println("error ratio out of range");
      usage();
      System.exit(-1);
    }
    return ratio;
  }
 
  public Grammar grammar;
  public String outputName=null;
  private String encoding="UTF-8";
  private boolean createError = false;
  private boolean validate = true;
  private boolean debug = false;
  private boolean quiet = false;
  private boolean warning = false;
  private GeneratorOption opt = new GeneratorOption();
  {
    opt.random = new Random();
  }
  private int number = 1;
 
    /** designated root element name. */
    private StringPair rootName = null;
 
  private SAXParserFactory factory = SAXParserFactory.newInstance();
  {
    factory.setNamespaceAware(true);
    factory.setValidating(false);
    try {
      factory.setFeature("http://xml.org/sax/features/validation",false);
      factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",false);
    } catch(Exception e) { ; }
  }

  private DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  {
    domFactory.setNamespaceAware(true);
    domFactory.setValidating(false);
  }
 
  // this set will receive tokens found in the given examples.
  public final Set exampleTokens = new java.util.HashSet();
  private DataTypeGeneratorImpl dtgi = new DataTypeGeneratorImpl();
  {
    opt.dtGenerator = dtgi;
    dtgi.tokens = exampleTokens;
  }
 
  /** Command line argument error. */
    private static class CommandLineException extends Exception {
        public CommandLineException( String msg ) { super(msg); }
    }
   
  /**
   * Parses the arguments and fill the fields accordingly.
   */
    public void parseArguments( String[] args ) throws CommandLineException, ParserConfigurationException {
    String grammarName=null;
    boolean dtdAsSchema = false;

    for( int i=0; i<args.length; i++ ) {
      if( args[i].equalsIgnoreCase("-debug") )  // secret option
        debug = true;
      else
      if( args[i].equalsIgnoreCase("-dtd") )
        dtdAsSchema = true;
      else
      if( args[i].equalsIgnoreCase("-quiet") )
        quiet = true;
      else
      if( args[i].equalsIgnoreCase("-warning") )
        warning = true;
      else
      if( args[i].equalsIgnoreCase("-ascii") )
        ((DataTypeGeneratorImpl)opt.dtGenerator).asciiOnly = true;
      else
      if( args[i].equalsIgnoreCase("-nocomment") )
        opt.insertComment = false;
      else
      if( args[i].equalsIgnoreCase("-depth") )
        opt.cutBackDepth = new Integer(args[++i]).intValue();
      else
      if( args[i].equalsIgnoreCase("-example") ) {
                String fileName = args[++i];
                try {
            XMLReader p = factory.newSAXParser().getXMLReader();
            p.setContentHandler( new ExampleReader(exampleTokens) );
            p.parse( getInputSource(fileName) );
                } catch( IOException e ) {
                    throw new CommandLineException("unable to parse "+fileName+" :"+e.getMessage());
                } catch( SAXException e ) {
                    throw new CommandLineException("unable to parse "+fileName+" :"+e.getMessage());
                }
      } else
      if( args[i].equalsIgnoreCase("-width") )
        opt.width = new Rand.UniformRand( opt.random, new Integer(args[++i]).intValue() );
      else
      if( args[i].equalsIgnoreCase("-n") ) {
        number = new Integer(args[++i]).intValue();
        if( number<1 number=1;
      }
      else
            if( args[i].equals("-root") ) {
                String root = args[++i];
                int idx = root.indexOf('}');
                if(idx<0)
                    // short form XXX
                    rootName = new StringPair( "", root );
                else
                    // full form {XXX}YYY
                    rootName = new StringPair( root.substring(1,idx), root.substring(idx+1) );
            }
            else
      if( args[i].equalsIgnoreCase("-encoding") )
        encoding = args[++i];
      else
      if( args[i].equalsIgnoreCase("-seed") )
        opt.random.setSeed( new Long(args[++i]).longValue() );
      else
      if( args[i].equalsIgnoreCase("-nonvalidate") )  // secret option
        validate = false;
      else
      if( args[i].startsWith("-error") ) {
        createError = true;
        if( args[i].equalsIgnoreCase("-error") ) {
          opt.probGreedyChoiceError=
          opt.probMissingAttrError=
          opt.probMissingElemError=
          opt.probMutatedAttrError=
          opt.probMutatedElemError=
          opt.probSeqError=
          opt.probSlipInAttrError=
          opt.probSlipInElemError=
          opt.probMissingPlus=
          opt.probAttrNameTypo=
          opt.probElemNameTypo=
            getRatio(args[++i]);
        }
        else
        if( args[i].equalsIgnoreCase("-error-greedyChoice") )
          opt.probGreedyChoiceError  = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-missingAttribute") )
          opt.probMissingAttrError  = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-missingElement") )
          opt.probMissingElemError  = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-mutatedAttribute") )
          opt.probMutatedAttrError  = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-mutatedElement") )
          opt.probMutatedElemError  = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-sequenceError") )
          opt.probSeqError      = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-slipInAttribute") )
          opt.probSlipInAttrError    = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-slipInElement") )
          opt.probSlipInElemError    = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-missingPlus") )
          opt.probMissingPlus      = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-attributeNameTypo") )
          opt.probAttrNameTypo    = getRatio(args[++i]);
        else
        if( args[i].equalsIgnoreCase("-error-attributeNameTypo") )
            opt.probElemNameTypo  = getRatio(args[++i]);
        else
          throw new CommandLineException("unrecognized option :" + args[i]);
       
      }
      else {
        if( args[i].charAt(0)=='-' )
          throw new CommandLineException("unrecognized option :" + args[i]);
         
        if( grammarName==null grammarName = args[i];
        else
        if( outputName==null ) outputName = args[i];
        else
                    throw new CommandLineException("too many parameters");
      }
    }
   
   
    if(grammarName!=null) {
      // load a schema
      if(!quiet)
        System.err.println("parsing a grammar: "+grammarName);
   
      InputSource is = getInputSource(grammarName);
   
            try {
          if(dtdAsSchema) {
            grammar = DTDReader.parse(
              is,
              new DebugController(warning,quiet),
              new ExpressionPool());
          } else {
            grammar = GrammarLoader.loadSchema(
              is,
              new DebugController(warning,quiet),
              factory);
          }
            } catch( IOException e ) {
                throw new CommandLineException("unable to parse "+grammarName+" :"+e.getMessage());
            } catch( SAXException e ) {
                throw new CommandLineException("unable to parse "+grammarName+" :"+e.getMessage());
            }
    }
  }
 
  /**
   * Generate XML instances.
   *
   * @return 0 if it run successfully. Non-zero if any error is encountered.
   */
  public int run( PrintStream out ) throws Exception {
   
    if( grammar==null ) {
      usage();
      return -1;
    }
   
   
    Expression topLevel  = grammar.getTopLevel();
   
    // polish up this AGM for instance generation.
    if( grammar instanceof RELAXGrammar
    ||  grammar instanceof RELAXModule )
      topLevel = topLevel.visit( new NoneTypeRemover(grammar.getPool()) );
   
    if( grammar instanceof XMLSchemaGrammar )
      topLevel = topLevel.visit( new SchemaLocationRemover(grammar.getPool()) );
   
 
    topLevel = topLevel.visit( new RefExpRemover(grammar.getPool(),true) );
       
        if(rootName!=null) {
            topLevel = findElement(topLevel,rootName);
            if(topLevel==null) {
                out.println("unable to find the specified root element: "+rootName);
                return -1;
            }
        }
       
    opt.pool = grammar.getPool();
   
    // generate instances
    //===========================================
    for( int i=0; i<number; i++ ) {
      if(!quiet) {
        if(number<=10 out.println("generating document #"+(i+1));
        else      out.print(">");
      }
     
      org.w3c.dom.Document dom;
      int retry=0;
     
      while(true) {
        dom = domFactory.newDocumentBuilder().newDocument();
        Generator.generate(topLevel,dom,opt);
       
        if(!validate)    break;
       
        // check the validity of generated document.
        DOM2toSAX2 d2s = new DOM2toSAX2();
        Verifier v = new Verifier(
          new REDocumentDeclaration(grammar),
          debug?
            (ErrorHandler)new ErrorHandlerImpl():
            (ErrorHandler)new IgnoreErrorHandler() );
        d2s.setContentHandler(v);
        d2s.traverse(dom);
       
        if( createError && !v.isValid() )  break;
        if( !createError && v.isValid() )  break;
       
        // do it again
        if( retry++ == 100 ) {
          out.println("unable to generate a proper instance.");
          return -1;
        }
      }
   
      // serialize it
      OutputStream os;
      if( outputName==null )    os = System.out;  // in case no output file name is specified
      else {
        int idx = outputName.indexOf('$');
        if( idx!=-1 ) {
          String s = Integer.toString(i);
          for( int j=s.length(); j<Integer.toString(number-1).length(); j++ )
            s = "0"+s;
         
          os = new FileOutputStream( outputName.substring(0,idx)+s+outputName.substring(idx+1) );
        }
        else
          os = new FileOutputStream( outputName );
      }
     
      DOMDecorator.decorate(dom);
     
      // write generated instance.
      XMLSerializer s = new XMLSerializer( os, new OutputFormat("XML",encoding,true) );
      s.serialize(dom);
     
      if( os!=System.out os.close();
    }

    out.println();
   
    return 0;
  }
 
    private Expression findElement( Expression exp, StringPair name ) {
       
        Vector vec = new Vector();
        new ElementsOfConcernCollector().collect( exp, vec );
       
        for( int i=0; i<vec.size(); i++ ) {
            ElementExp eexp = (ElementExp)vec.get(i);
            if(eexp.getNameClass().accepts(name))
                return eexp;
        }
       
        return null;
    }
   
  private static InputSource getInputSource( String fileOrURL ) {
    try {
      // try it as a file
      String path = new File(fileOrURL).getAbsolutePath();
      if (File.separatorChar != '/')
        path = path.replace(File.separatorChar, '/');
      if (!path.startsWith("/"))
        path = "/" + path;
//      if (!path.endsWith("/") && isDirectory())
//        path = path + "/";
      return new InputSource( new URL("file", "", path).toExternalForm() );
    } catch( Exception e ) {
      // try it as an URL
      return new InputSource(fileOrURL);
    }
  }
}
TOP

Related Classes of com.sun.msv.generator.Driver$CommandLineException

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.