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 }