View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2001-2002 (C) Intalio, Inc. All Rights Reserved.
42   *
43   * $Id$
44   */
45  
46  package org.exolab.castor.xml.schema.util;
47  
48  import java.io.FileWriter;
49  import java.io.IOException;
50  import java.io.PrintWriter;
51  import java.io.Reader;
52  import java.io.Writer;
53  
54  import org.castor.xml.BackwardCompatibilityContext;
55  import org.castor.xml.InternalContext;
56  import org.exolab.castor.util.NestedIOException;
57  import org.exolab.castor.xml.schema.Order;
58  import org.exolab.castor.xml.schema.Schema;
59  import org.exolab.castor.xml.schema.writer.SchemaWriter;
60  import org.xml.sax.InputSource;
61  import org.xml.sax.Parser;
62  import org.xml.sax.SAXException;
63  
64  /**
65   * A class for reading XML Schemas.
66   * 
67   * To generate an XML schema from a given XML document instance and write it to 
68   * a file, please use code similar to the following:
69   *
70   * InputSource inputSource = ...;
71   * XMLInstance2Schema xi2s = new XMLInstance2Schema();
72   * Schema schema = xi2s.createSchema(inputSource);
73   *
74   * Writer dstWriter = new FileWriter(...);
75   * xi2s.serializeSchema(dstWriter, schema);
76   * dstWriter.close();
77   * 
78   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
79   * @version $Revision$ $Date: 2006-01-16 13:22:58 -0700 (Mon, 16 Jan
80   *          2006) $
81   */
82  public class XMLInstance2Schema {
83  
84      /**
85       * The {@link InternalContext} used to get Parser from.
86       */
87      private InternalContext _internalContext;
88  
89      private Order _defaultGroup = Order.sequence;
90  
91      /**
92       * Creates a new XMLInstance2Schema
93       * 
94       */
95      public XMLInstance2Schema() {
96          super();
97          _internalContext = new BackwardCompatibilityContext();
98      }
99  
100     /**
101      * Creates an XML Schema using the given XML instance filename. The XML
102      * Schema created will be based on the specific XML instance document.
103      * 
104      * @param filename
105      *            the filename for the XML document
106      */
107     public Schema createSchema(String filename) throws IOException {
108         return createSchema(new InputSource(filename));
109     }
110 
111     /**
112      * Creates an XML Schema using the given Reader. The reader must be for an
113      * XML instance document. The XML Schema created will be based on the
114      * specific XML instance document.
115      * 
116      * @param reader
117      *            the Reader for the XML document
118      */
119     public Schema createSchema(Reader reader) throws IOException {
120         return createSchema(new InputSource(reader));
121     }
122 
123     /**
124      * Creates an XML Schema using the given InputSource. The InputSource must
125      * be for an XML instance document. The XML Schema created will be based on
126      * the specific XML instance document.
127      * 
128      * @param source
129      *            the InputSource for the XML document
130      */
131     public Schema createSchema(InputSource source) throws IOException {
132         XMLInstance2SchemaHandler handler = new XMLInstance2SchemaHandler();
133         handler.setDefaultGroupOrder(_defaultGroup);
134 
135         try {
136             Parser parser = _internalContext.getParser();
137             if (parser == null) {
138                 throw new IOException(
139                         "fatal error: unable to create SAX parser.");
140             }
141             parser.setDocumentHandler(handler);
142             parser.setErrorHandler(handler);
143             parser.parse(source);
144         } catch (org.xml.sax.SAXException sx) {
145             throw new NestedIOException(sx);
146         }
147         return handler.getSchema();
148     }
149 
150     /**
151      * Sets the default grouping as "all". By default groups will be treated as
152      * "sequence".
153      */
154     public void setDefaultGroupingAsAll() {
155         _defaultGroup = Order.all;
156     }
157 
158     /**
159      * Serializes a {@link Schema} instance to the given {@link Writer} instance.
160      * @param dstWriter The {@link Writer} instance to output the XML schema to.
161      * @param schema The XML {@link Schema} instance to be output.
162      * @throws IOException If there's a problem related to writing to the given {@link Writer} instance. 
163      * @throws SAXException If there's a problem related to SAX streaming.
164      */
165     public void serializeSchema(Writer dstWriter, Schema schema)
166             throws IOException, SAXException {
167         SchemaWriter schemaWriter = new SchemaWriter(dstWriter);
168         schemaWriter.write(schema);
169     }
170 
171     /**
172      * For testing purposes only.
173      * @deprecate Please see class documentation for an example of how to use
174      * this class. Or consider using the Ant task for the schema generator.
175      */
176     public static void main(String args[]) {
177 
178         if (args.length == 0) {
179             System.out.println("Missing filename");
180             System.out.println();
181             System.out
182                     .println("usage: java XMLInstance2Schema <input-file> [<output-file> (optional)]");
183             return;
184         }
185 
186         try {
187             XMLInstance2Schema xi2s = new XMLInstance2Schema();
188             Schema schema = xi2s.createSchema(args[0]);
189 
190             Writer dstWriter = null;
191             if (args.length > 1) {
192                 dstWriter = new FileWriter(args[1]);
193             } else {
194                 dstWriter = new PrintWriter(System.out, true);
195             }
196 
197             xi2s.serializeSchema(dstWriter, schema);
198             dstWriter.flush();
199         } catch (Exception ex) {
200             ex.printStackTrace();
201         }
202 
203     }
204 
205 }