Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » inst2xsd » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   package org.apache.xmlbeans.impl.inst2xsd;
   16   
   17   import org.apache.xmlbeans.SchemaTypeLoader;
   18   import org.apache.xmlbeans.XmlBeans;
   19   import org.apache.xmlbeans.XmlException;
   20   import org.apache.xmlbeans.XmlObject;
   21   import org.apache.xmlbeans.XmlOptions;
   22   import org.apache.xmlbeans.XmlError;
   23   import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
   24   import org.apache.xmlbeans.impl.inst2xsd.util.TypeSystemHolder;
   25   import org.apache.xmlbeans.impl.tool.CommandLine;
   26   
   27   import java.io.File;
   28   import java.io.IOException;
   29   import java.io.Reader;
   30   import java.util.ArrayList;
   31   import java.util.Collection;
   32   import java.util.Iterator;
   33   import java.util.Set;
   34   import java.util.HashSet;
   35   
   36   /**
   37    * @author Cezar Andrei (cezar.andrei at bea.com) Date: Jul 16, 2004
   38    *
   39    * This class generates a set of XMLSchemas from an instance XML document.
   40    *
   41    * How it works:
   42    *  - first: pass through all the instances, building a TypeSystemHolder structure
   43    *  - second: serialize the TypeSystemHolder structure into SchemaDocuments
   44    */
   45   public class Inst2Xsd
   46   {
   47       public static void main(String[] args)
   48       {
   49           if (args==null || args.length == 0)
   50           {
   51               printHelp();
   52               System.exit(0);
   53               return;
   54           }
   55   
   56           Set flags = new HashSet();
   57           flags.add("h");
   58           flags.add("help");
   59           flags.add("usage");
   60           flags.add("license");
   61           flags.add("version");
   62           flags.add("verbose");
   63           flags.add("validate");
   64   
   65           Set opts = new HashSet();
   66           opts.add("design");
   67           opts.add("simple-content-types");
   68           opts.add("enumerations");
   69           opts.add("outDir");
   70           opts.add("outPrefix");
   71   
   72           CommandLine cl = new CommandLine(args, flags, opts);
   73           Inst2XsdOptions inst2XsdOptions = new Inst2XsdOptions();
   74   
   75           if (cl.getOpt("license") != null)
   76           {
   77               CommandLine.printLicense();
   78               System.exit(0);
   79               return;
   80           }
   81   
   82           if (cl.getOpt("version") != null)
   83           {
   84               CommandLine.printVersion();
   85               System.exit(0);
   86               return;
   87           }
   88   
   89           if (cl.getOpt("h") != null || cl.getOpt("help") != null || cl.getOpt("usage") != null)
   90           {
   91               printHelp();
   92               System.exit(0);
   93               return;
   94           }
   95   
   96           String[] badopts = cl.getBadOpts();
   97           if (badopts.length > 0)
   98           {
   99               for (int i = 0; i < badopts.length; i++)
  100                   System.out.println("Unrecognized option: " + badopts[i]);
  101               printHelp();
  102               System.exit(0);
  103               return;
  104           }
  105   
  106           String design = cl.getOpt("design");
  107           if (design==null)
  108           {
  109               // default
  110           }
  111           else if (design.equals("vb"))
  112           {
  113               inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_VENETIAN_BLIND);
  114           }
  115           else if (design.equals("rd"))
  116           {
  117               inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_RUSSIAN_DOLL);
  118           }
  119           else if (design.equals("ss"))
  120           {
  121               inst2XsdOptions.setDesign(Inst2XsdOptions.DESIGN_SALAMI_SLICE);
  122           }
  123           else
  124           {
  125               printHelp();
  126               System.exit(0);
  127               return;
  128           }
  129   
  130           String simpleContent = cl.getOpt("simple-content-types");
  131           if (simpleContent==null)
  132           {
  133               //default
  134           }
  135           else if (simpleContent.equals("smart"))
  136           {
  137               inst2XsdOptions.setSimpleContentTypes(Inst2XsdOptions.SIMPLE_CONTENT_TYPES_SMART);
  138           }
  139           else if (simpleContent.equals("string"))
  140           {
  141               inst2XsdOptions.setSimpleContentTypes(Inst2XsdOptions.SIMPLE_CONTENT_TYPES_STRING);
  142           }
  143           else
  144           {
  145               printHelp();
  146               System.exit(0);
  147               return;
  148           }
  149   
  150           String enumerations = cl.getOpt("enumerations");
  151           if (enumerations==null)
  152           {
  153               // default
  154           }
  155           else if (enumerations.equals("never"))
  156           {
  157               inst2XsdOptions.setUseEnumerations(Inst2XsdOptions.ENUMERATION_NEVER);
  158           }
  159           else
  160           {
  161               try
  162               {
  163                   int intVal = Integer.parseInt(enumerations);
  164                   inst2XsdOptions.setUseEnumerations(intVal);
  165               }
  166               catch (NumberFormatException e)
  167               {
  168                   printHelp();
  169                   System.exit(0);
  170                   return;
  171               }
  172           }
  173   
  174           File outDir = new File( cl.getOpt("outDir")==null ? "." : cl.getOpt("outDir"));
  175   
  176           String outPrefix = cl.getOpt("outPrefix");
  177           if (outPrefix==null)
  178               outPrefix = "schema";
  179   
  180           inst2XsdOptions.setVerbose((cl.getOpt("verbose") != null));
  181           boolean validate = cl.getOpt("validate")!=null;
  182   
  183           File[] xmlFiles = cl.filesEndingWith(".xml");
  184           XmlObject[] xmlInstances = new XmlObject[xmlFiles.length];
  185   
  186           if ( xmlInstances.length==0 )
  187           {
  188               printHelp();
  189               System.exit(0);
  190               return;
  191           }
  192   
  193           int i = 0;
  194           try
  195           {
  196               for (i = 0; i < xmlFiles.length; i++)
  197               {
  198                   xmlInstances[i] = XmlObject.Factory.parse(xmlFiles[i]);
  199               }
  200           }
  201           catch (XmlException e)
  202           {
  203               System.err.println("Invalid xml file: '" + xmlFiles[i].getName() + "'. " + e.getMessage());
  204               return;
  205           }
  206           catch (IOException e)
  207           {
  208               System.err.println("Could not read file: '" + xmlFiles[i].getName() + "'. " + e.getMessage());
  209               return;
  210           }
  211   
  212           SchemaDocument[] schemaDocs = inst2xsd(xmlInstances, inst2XsdOptions);
  213   
  214           try
  215           {
  216               for (i = 0; i < schemaDocs.length; i++)
  217               {
  218                   SchemaDocument schema = schemaDocs[i];
  219   
  220                   if (inst2XsdOptions.isVerbose())
  221                       System.out.println("----------------------\n\n" + schema);
  222   
  223                   schema.save(new File(outDir, outPrefix + i + ".xsd"), new XmlOptions().setSavePrettyPrint());
  224               }
  225           }
  226           catch (IOException e)
  227           {
  228               System.err.println("Could not write file: '" + outDir + File.pathSeparator +  outPrefix + i + ".xsd" + "'. " + e.getMessage());
  229               return;
  230           }
  231   
  232           if (validate)
  233           {
  234               validateInstances(schemaDocs, xmlInstances);
  235           }
  236       }
  237   
  238       private static void printHelp()
  239       {
  240           System.out.println("Generates XMLSchema from instance xml documents.");
  241           System.out.println("Usage: inst2xsd [opts] [instance.xml]*");
  242           System.out.println("Options include:");
  243           System.out.println("    -design [rd|ss|vb] - XMLSchema design type");
  244           System.out.println("             rd  - Russian Doll Design - local elements and local types");
  245           System.out.println("             ss  - Salami Slice Design - global elements and local types");
  246           System.out.println("             vb  - Venetian Blind Design (default) - local elements and global complex types");
  247           System.out.println("    -simple-content-types [smart|string] - Simple content types detection (leaf text). Smart is the default");
  248           System.out.println("    -enumerations [never|NUMBER] - Use enumerations. Default value is " + Inst2XsdOptions.ENUMERATION_NOT_MORE_THAN_DEFAULT + ".");
  249           System.out.println("    -outDir [dir] - Directory for output files. Default is '.'");
  250           System.out.println("    -outPrefix [file_name_prefix] - Prefix for output file names. Default is 'schema'");
  251           System.out.println("    -validate - Validates input instances agaist generated schemas.");
  252           System.out.println("    -verbose - print more informational messages");
  253           System.out.println("    -license - print license information");
  254           System.out.println("    -help - help imformation");
  255       }
  256   
  257       private Inst2Xsd() {}
  258   
  259       // public entry points
  260   
  261       public static SchemaDocument[] inst2xsd(Reader[] instReaders, Inst2XsdOptions options)
  262           throws IOException, XmlException
  263       {
  264           XmlObject[] instances = new XmlObject[ instReaders.length ];
  265           for (int i = 0; i < instReaders.length; i++)
  266           {
  267               instances[i] = XmlObject.Factory.parse(instReaders[i]);
  268           }
  269           return inst2xsd(instances, options);
  270       }
  271   
  272       public static SchemaDocument[] inst2xsd(XmlObject[] instances, Inst2XsdOptions options)
  273       {
  274           if (options==null)
  275               options = new Inst2XsdOptions();
  276   
  277           // create structure
  278           TypeSystemHolder typeSystemHolder = new TypeSystemHolder();
  279   
  280           XsdGenStrategy strategy;
  281           switch (options.getDesign())
  282           {
  283               case Inst2XsdOptions.DESIGN_RUSSIAN_DOLL:
  284                   strategy = new RussianDollStrategy();
  285                   break;
  286   
  287               case Inst2XsdOptions.DESIGN_SALAMI_SLICE:
  288                   strategy = new SalamiSliceStrategy();
  289                   break;
  290   
  291               case Inst2XsdOptions.DESIGN_VENETIAN_BLIND:
  292                   strategy = new VenetianBlindStrategy();
  293                   break;
  294   
  295               default:
  296                   throw new IllegalArgumentException("Unknown design.");
  297           }
  298           // processDoc the instance
  299           strategy.processDoc(instances, options, typeSystemHolder);
  300   
  301           if (options.isVerbose())
  302               System.out.println("typeSystemHolder.toString(): " + typeSystemHolder);
  303   
  304           SchemaDocument[] sDocs = typeSystemHolder.getSchemaDocuments();
  305   
  306           return sDocs;
  307       }
  308   
  309       private static boolean validateInstances(SchemaDocument[] sDocs, XmlObject[] instances)
  310       {
  311           SchemaTypeLoader sLoader;
  312           Collection compErrors = new ArrayList();
  313           XmlOptions schemaOptions = new XmlOptions();
  314           schemaOptions.setErrorListener(compErrors);
  315           try
  316           {
  317               sLoader = XmlBeans.loadXsd(sDocs, schemaOptions);
  318           }
  319           catch (Exception e)
  320           {
  321               if (compErrors.isEmpty() || !(e instanceof XmlException))
  322               {
  323                   e.printStackTrace(System.out);
  324               }
  325               System.out.println("\n-------------------\n\nInvalid schemas.");
  326               for (Iterator errors = compErrors.iterator(); errors.hasNext(); )
  327               {
  328                   XmlError xe = (XmlError)errors.next();
  329                   System.out.println(xe.getLine() + ":" + xe.getColumn() + " " + xe.getMessage());
  330               }
  331               return false;
  332           }
  333   
  334           System.out.println("\n-------------------");
  335           boolean result = true;
  336   
  337           for (int i = 0; i < instances.length; i++)
  338           {
  339               XmlObject xobj;
  340   
  341               try
  342               {
  343                   xobj = sLoader.parse( instances[i].newXMLStreamReader(), null, new XmlOptions().setLoadLineNumbers() );
  344               }
  345               catch (XmlException e)
  346               {
  347                   System.out.println("Error:\n" + instances[i].documentProperties().getSourceName() + " not loadable: " + e);
  348                   e.printStackTrace(System.out);
  349                   result = false;
  350                   continue;
  351               }
  352   
  353               Collection errors = new ArrayList();
  354   
  355               if (xobj.schemaType() == XmlObject.type)
  356               {
  357                   System.out.println(instances[i].documentProperties().getSourceName() + " NOT valid.  ");
  358                   System.out.println("  Document type not found." );
  359                   result = false;
  360               }
  361               else if (xobj.validate(new XmlOptions().setErrorListener(errors)))
  362                   System.out.println("Instance[" + i + "] valid - " + instances[i].documentProperties().getSourceName());
  363               else
  364               {
  365                   System.out.println("Instance[" + i + "] NOT valid - " + instances[i].documentProperties().getSourceName());
  366                   for (Iterator it = errors.iterator(); it.hasNext(); )
  367                   {
  368                       XmlError xe = (XmlError)it.next();
  369                       System.out.println(xe.getLine() + ":" + xe.getColumn() + " " + xe.getMessage());
  370                   }
  371                   result = false;
  372               }
  373           }
  374   
  375           return result;
  376       }
  377   }

Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » inst2xsd » [javadoc | source]