001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
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; either
009: * version 2.1 of the License, or any later version.
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: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: JDefinitionWriter.java 6860 2005-05-27 15:01:25Z sauthieg $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.ws;
025:
026: import java.io.File;
027: import java.io.FileOutputStream;
028: import java.io.IOException;
029: import java.io.OutputStreamWriter;
030: import java.io.Writer;
031: import java.nio.charset.Charset;
032: import java.util.Iterator;
033: import java.util.List;
034: import java.util.Map;
035: import javax.wsdl.Definition;
036: import javax.wsdl.Import;
037: import javax.wsdl.Types;
038: import javax.wsdl.WSDLException;
039: import javax.wsdl.extensions.ExtensibilityElement;
040: import javax.wsdl.extensions.UnknownExtensibilityElement;
041: import javax.wsdl.extensions.schema.Schema;
042: import javax.wsdl.factory.WSDLFactory;
043: import javax.wsdl.xml.WSDLWriter;
044: import org.w3c.dom.Document;
045: import org.objectweb.jonas_lib.xml.XMLSerializer;
046: import org.objectweb.jonas.common.Log;
047: import org.objectweb.util.monolog.api.BasicLevel;
048: import org.objectweb.util.monolog.api.Logger;
049:
050: /**
051: * Wrote the given Definition and all imported WSDL to the given base directory.
052: * @author Guillaume Sauthier
053: */
054: public class JDefinitionWriter {
055:
056: /** WSDL Directory */
057: private File base;
058:
059: /** charset */
060: private Charset cs;
061:
062: /** Definition to write */
063: private Definition definition;
064:
065: /** base WSDL filename */
066: private String filename;
067:
068: /** logger */
069: private static Logger logger = Log.getLogger(Log.JONAS_WS_PREFIX);
070:
071: /**
072: * Constructs a new JDefinitionWriter that will wrote the given Definition
073: * and all imported WSDL to the given base directory.
074: * @param def base Definition
075: * @param context Context where file should be wrote (MUST exists)
076: * @param cs Charset to use
077: * @param filename base Definition filename
078: */
079: public JDefinitionWriter(Definition def, File context, Charset cs,
080: String filename) {
081: if (!context.exists()) {
082: throw new IllegalArgumentException("Context MUST exists : "
083: + context);
084: }
085: this .definition = def;
086: if (context.isDirectory()) {
087: this .base = context;
088: } else {
089: this .base = context.getParentFile();
090: }
091: this .cs = cs;
092: this .filename = filename;
093: }
094:
095: /**
096: * Write the given Definition into the base directory
097: * @throws IOException if a file or directory cannot be created
098: * @throws WSDLException if WSDLWriter is not able to write its Definition
099: */
100: public void write() throws IOException, WSDLException {
101: writeDefinition(definition, base, filename);
102: Map imports = definition.getImports();
103: for (Iterator ns = imports.keySet().iterator(); ns.hasNext();) {
104: // for each nsURI, we have a List of Import
105: String uri = (String) ns.next();
106: List importeds = (List) imports.get(uri);
107: // for each import related to the given ns
108: for (Iterator imp = importeds.iterator(); imp.hasNext();) {
109: Import imported = (Import) imp.next();
110:
111: // create a resolved URL to know if the import is relative or
112: // not to the base
113: String locURI = imported.getLocationURI();
114: if (!locURI.startsWith("http://")) {
115: // locResolvedURL starts with the base URI, so it's a
116: // relative import
117: // and we should wrote it.
118: Definition impDef = imported.getDefinition();
119: if (locURI.toLowerCase().endsWith("wsdl")) {
120: // if we have another WSDL
121: JDefinitionWriter jdw = new JDefinitionWriter(
122: impDef, new File(base, filename)
123: .getCanonicalFile(), cs, locURI);
124: jdw.write();
125: } else {
126: // Assume this is a types import
127: Types types = impDef.getTypes();
128: if (types != null) {
129: List extList = types
130: .getExtensibilityElements();
131: for (Iterator extIt = extList.iterator(); extIt
132: .hasNext();) {
133: ExtensibilityElement ext = (ExtensibilityElement) extIt
134: .next();
135: Document doc = null;
136:
137: if (ext instanceof Schema) {
138: // schema handling
139: Schema schema = (Schema) ext;
140: doc = schema.getElement()
141: .getOwnerDocument();
142: } else if (ext instanceof UnknownExtensibilityElement) {
143: // other XML
144: UnknownExtensibilityElement unknownExtElem = (UnknownExtensibilityElement) ext;
145: doc = unknownExtElem.getElement()
146: .getOwnerDocument();
147: }
148:
149: if (doc != null) {
150: // we have something to serialize
151: File dir = new File(base, filename)
152: .getCanonicalFile()
153: .getParentFile();
154: writeDocument(doc, dir, locURI);
155: }
156: }
157: }
158: }
159: }
160: }
161: }
162: }
163:
164: /**
165: * @param doc XML Document to write
166: * @param base storing directory
167: * @param locURI Document filename (may include directories)
168: * @throws IOException if OutputStream cannot be created
169: */
170: private void writeDocument(Document doc, File base, String locURI)
171: throws IOException {
172: XMLSerializer ser = new XMLSerializer(doc);
173: File file = new File(base, locURI).getCanonicalFile();
174: logger.log(BasicLevel.DEBUG, "Writing XML Document in " + file);
175: createParentIfNeeded(file);
176: Writer writer = new OutputStreamWriter(new FileOutputStream(
177: file), cs);
178: ser.serialize(writer);
179: writer.close();
180: }
181:
182: /**
183: * @param def Definition to write (that does not write imported files)
184: * @param base storing directory
185: * @param filename Definition filename
186: * @throws WSDLException if WSDLWriter failed to wrote the Definition
187: * @throws IOException if OutputStream cannot be created
188: */
189: private void writeDefinition(Definition def, File base,
190: String filename) throws WSDLException, IOException {
191: WSDLFactory factory = WSDLFactory.newInstance();
192: WSDLWriter writer = factory.newWSDLWriter();
193: File wsdl = new File(base, filename).getCanonicalFile();
194: logger.log(BasicLevel.DEBUG, "Writing WSDL Definition in "
195: + wsdl);
196: createParentIfNeeded(wsdl);
197: Writer w = new OutputStreamWriter(new FileOutputStream(wsdl),
198: cs);
199: writer.writeWSDL(def, w);
200: w.close();
201: }
202:
203: /**
204: * Creates the parent of the given file as a directory
205: * @param file with a parent that must be a directory
206: * @throws IOException if directory cannot be created
207: */
208: private void createParentIfNeeded(File file) throws IOException {
209: File parent = file.getParentFile();
210: if (!parent.exists()) {
211: if (!parent.mkdirs()) {
212: // cannot create directory
213: throw new IOException("Cannot create directory "
214: + parent.getCanonicalPath());
215: }
216: } else if (!parent.isDirectory()) {
217: // parent exists but is not a directory
218: throw new IOException("Parent " + parent.getCanonicalPath()
219: + " already exists but is not a directory.");
220: }
221: }
222: }
|