001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.maven.xmlcodegen;
017:
018: import org.eclipse.xsd.XSDAttributeDeclaration;
019: import org.eclipse.xsd.XSDAttributeGroupDefinition;
020: import org.eclipse.xsd.XSDAttributeUse;
021: import org.eclipse.xsd.XSDElementDeclaration;
022: import org.eclipse.xsd.XSDNamedComponent;
023: import org.eclipse.xsd.XSDParticle;
024: import org.eclipse.xsd.XSDSchema;
025: import org.eclipse.xsd.XSDTypeDefinition;
026: import org.geotools.xml.Schemas;
027: import java.io.IOException;
028: import java.util.ArrayList;
029: import java.util.HashSet;
030: import java.util.Iterator;
031: import java.util.List;
032: import java.util.Map;
033: import java.util.Set;
034: import java.util.logging.Level;
035: import java.util.logging.Logger;
036:
037: /**
038: * Generates bindings for types, elements, and attributes declared in an xml
039: * schema.
040: * <p>
041: * Usage Example:
042: * <pre>
043: * <code>
044: * XSDSchem schema = ...
045: * BindingGenerator g = new BindingGenerator();
046: * g.setPackageBase( "org.geotools.xml.xs" );
047: * g.setLocation( "/home/user" );
048: * g.generate( schema );
049: * </code>
050: * </pre>
051: * </p>
052: *
053: * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
054: *
055: */
056: public class BindingGenerator extends AbstractGenerator {
057: static Logger logger = org.geotools.util.logging.Logging
058: .getLogger("org.geotools.xml");
059: boolean generatingBindingInterface = true;
060: boolean generatingBindingConfiguration = true;
061: boolean generateAttributes = true;
062: boolean generateElements = true;
063: boolean generateTypes = true;
064: boolean generateConfiguration = true;
065: boolean generateSchemaLocationResolver = true;
066:
067: Set included = null;
068:
069: /**
070: * Map of string, class which define the name and type of binding constructor
071: * arguments.
072: */
073: Map/*<String,Class>*/bindingConstructorArguments;
074:
075: public void setBindingConstructorArguments(
076: Map bindingConstructorArguments) {
077: this .bindingConstructorArguments = bindingConstructorArguments;
078: }
079:
080: public void setGeneratingBindingConfiguration(
081: boolean generatingBindingConfiguration) {
082: this .generatingBindingConfiguration = generatingBindingConfiguration;
083: }
084:
085: public void setGeneratingBindingInterface(
086: boolean generatingBindingInterface) {
087: this .generatingBindingInterface = generatingBindingInterface;
088: }
089:
090: public void setGenerateAttributes(boolean generateAttributes) {
091: this .generateAttributes = generateAttributes;
092: }
093:
094: public void setGenerateElements(boolean generateElements) {
095: this .generateElements = generateElements;
096: }
097:
098: public void setGenerateTypes(boolean generateTypes) {
099: this .generateTypes = generateTypes;
100: }
101:
102: public void setIncluded(Set included) {
103: this .included = included;
104: }
105:
106: public void generate(XSDSchema schema) {
107: List components = new ArrayList();
108:
109: if (generateElements) {
110: List elements = schema.getElementDeclarations();
111:
112: for (Iterator e = elements.iterator(); e.hasNext();) {
113: XSDElementDeclaration element = (XSDElementDeclaration) e
114: .next();
115: generate(element, schema);
116:
117: if (target(element, schema)) {
118: components.add(element);
119: }
120: }
121: }
122:
123: if (generateTypes) {
124: List types = GeneratorUtils.allTypes(schema);
125:
126: for (Iterator t = types.iterator(); t.hasNext();) {
127: XSDTypeDefinition type = (XSDTypeDefinition) t.next();
128: generate(type, schema);
129:
130: if (target(type, schema)) {
131: components.add(type);
132: }
133: }
134: }
135:
136: if (generateAttributes) {
137: List attributes = schema.getAttributeDeclarations();
138:
139: for (Iterator a = attributes.iterator(); a.hasNext();) {
140: XSDAttributeDeclaration attribute = (XSDAttributeDeclaration) a
141: .next();
142: generate(attribute, schema);
143:
144: if (target(attribute, schema)) {
145: components.add(attribute);
146: }
147: }
148: }
149:
150: if (generatingBindingConfiguration) {
151: try {
152: String result = execute("BindingConfigurationTemplate",
153: new Object[] { schema, components });
154: write(result, prefix(schema).toUpperCase()
155: + "BindingConfiguration");
156: } catch (Exception e) {
157: String msg = "Error generating binding configuration";
158: logger.log(Level.WARNING, msg, e);
159: }
160: }
161:
162: if (generatingBindingInterface) {
163: try {
164: String result = execute("BindingInterfaceTemplate",
165: schema);
166: write(result, prefix(schema).toUpperCase());
167: } catch (Exception e) {
168: String msg = "Error generating binding interface";
169: logger.log(Level.WARNING, msg, e);
170: }
171: }
172: }
173:
174: boolean included(XSDNamedComponent c) {
175: return included != null ? included.contains(c.getName()) : true;
176: }
177:
178: boolean target(XSDNamedComponent c, XSDSchema schema) {
179: return c.getTargetNamespace().equals(
180: schema.getTargetNamespace());
181: }
182:
183: void generate(XSDNamedComponent c, XSDSchema schema) {
184: if (!target(c, schema)) {
185: return;
186: }
187:
188: if (!included(c)) {
189: return;
190: }
191:
192: logger.info("Generating binding for " + c.getName());
193: try {
194: String result = execute("CLASS", new Object[] { c,
195: bindingConstructorArguments });
196: write(result, name(c));
197: } catch (Exception ioe) {
198: String msg = "Unable to generate binding for " + c;
199: logger.log(Level.WARNING, msg, ioe);
200: }
201: }
202:
203: String name(XSDNamedComponent c) {
204: return c.getName().substring(0, 1).toUpperCase()
205: + c.getName().substring(1) + "Binding";
206: }
207:
208: public static void main(String[] args) throws Exception {
209: XSDSchema schema = Schemas
210: .parse("/home/jdeolive/devel/geotools/trunk/demo/xml-po/src/main/xsd/po.xsd");
211: System.out.println(schema.getQNamePrefixToNamespaceMap());
212: // ArrayList cargList = new ArrayList();
213: // HashSet includedTypes = new HashSet();
214: // BindingGenerator g = new BindingGenerator();
215: //
216: // if (args.length == 0) {
217: // usage();
218: // System.exit(0);
219: // }
220: //
221: // for (int i = 0; i < args.length; i++) {
222: // String arg = args[i];
223: //
224: // if ("--help".equals(arg)) {
225: // usage();
226: // System.exit(0);
227: // }
228: //
229: // if ("--schema".equals(arg)) {
230: // schema = Schemas.parse(args[++i]);
231: // } else if ("--output".equals(arg)) {
232: // g.setLocation(args[++i]);
233: // } else if ("--package".equals(arg)) {
234: // g.setPackageBase(args[++i]);
235: // } else if ("--include-type".equals(arg)) {
236: // includedTypes.add(args[++i]);
237: // } else if ("--carg".equals(arg)) {
238: // try {
239: // cargList.add(Class.forName(args[++i]));
240: // } catch (ClassNotFoundException e) {
241: // String msg = "Could not load class: " + args[i];
242: // throw (IllegalArgumentException) new IllegalArgumentException(msg)
243: // .initCause(e);
244: // }
245: // } else if ("--noelements".equals(arg)) {
246: // g.setGenerateElements(false);
247: // } else if ("--noattributes".equals(arg)) {
248: // g.setGenerateAttributes(false);
249: // } else if ("--notypes".equals(arg)) {
250: // g.setGenerateTypes(false);
251: // } else if ("--no-binding-interface".equals(arg)) {
252: // g.setGeneratingBindingInterface( false );
253: // } else if ("--no-binding-configuration".equals(arg)) {
254: // g.setGeneratingBindingConfiguration( false );
255: // }
256: //
257: // }
258: //
259: // Class[] cargs = null;
260: //
261: // if (!cargList.isEmpty()) {
262: // cargs = (Class[]) cargList.toArray(new Class[cargList.size()]);
263: // }
264: //
265: // if (schema == null) {
266: // String msg = "ERROR: schema not specified";
267: // usage();
268: //
269: // throw new IllegalArgumentException(msg);
270: // }
271: //
272: // if (g.getLocation() == null) {
273: // g.setLocation(System.getProperty("user.dir"));
274: // }
275: //
276: // g.setIncludedTypes(includedTypes);
277: // //g.setBindingConstructorArguments(cargs);
278: // g.generate(schema);
279: }
280:
281: public static void usage() {
282: System.out.println("Options");
283: System.out.println("\t\t--help: Print this message");
284: System.out.println("\t\t--schema <path>: Path to schema file");
285: System.out
286: .println("\t\t--output <path>: Path to output directory");
287: System.out
288: .println("\t\t--package <package>: Package out writen files");
289: System.out
290: .println("\t\t--include-type <type>: Include a single type");
291: System.out
292: .println("\t\t--carg <class>: Qualified class name of binding constructor argument");
293: System.out
294: .println("\t\t--noelements: Turn off element binding generation");
295: System.out
296: .println("\t\t--noattributes: Turn off attribute binding generation");
297: System.out
298: .println("\t\t--notypes: Turn off type binding generation");
299: System.out
300: .println("\t\t--no-binding-interface: Turn off binding interface generation");
301: System.out
302: .println("\t\t--no-binding-configuration: Turn off binding configuration generation");
303: }
304: }
|