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