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 }