001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.websvc.api.jaxws.wsdlmodel;
043:
044: import com.sun.tools.ws.processor.model.Model;
045: import com.sun.tools.ws.processor.modeler.wsdl.WSDLModeler;
046: import com.sun.tools.ws.wscompile.AbortException;
047: import com.sun.tools.ws.wscompile.BadCommandLineException;
048: import com.sun.tools.ws.wscompile.ErrorReceiver;
049: import com.sun.tools.ws.wscompile.WsimportOptions;
050: import com.sun.xml.ws.util.JAXWSUtils;
051: import java.io.File;
052: import java.net.URL;
053: import java.util.ArrayList;
054: import java.util.HashSet;
055: import java.util.List;
056: import java.util.Properties;
057: import java.util.Set;
058: import java.util.logging.Level;
059: import java.util.logging.Logger;
060: import org.apache.xml.resolver.CatalogManager;
061: import org.apache.xml.resolver.tools.CatalogResolver;
062: import org.openide.util.NbBundle;
063: import org.openide.util.RequestProcessor;
064: import org.xml.sax.EntityResolver;
065: import org.xml.sax.InputSource;
066: import org.xml.sax.SAXParseException;
067:
068: /**
069: *
070: * @author mkuchtiak
071: */
072: public class WsdlModeler {
073:
074: private WsdlModel wsdlModel;
075: private WSDLModeler ideWSDLModeler;
076: private URL wsdlUrl;
077: private URL[] bindings;
078: private URL catalog;
079: private EntityResolver entityResolver;
080: private Set<String> bindingFiles;
081: private String packageName;
082: private List<WsdlModelListener> modelListeners;
083: private List<WsdlChangeListener> wsdlChangeListeners;
084: RequestProcessor.Task task, task1;
085: int listenersSize;
086:
087: protected Properties properties;
088:
089: private Throwable creationException;
090:
091: /** Creates a new instance of WsdlModeler */
092: WsdlModeler(URL wsdlUrl) {
093: this .wsdlUrl = wsdlUrl;
094: modelListeners = new ArrayList<WsdlModelListener>();
095: wsdlChangeListeners = new ArrayList<WsdlChangeListener>();
096: task = RequestProcessor.getDefault().create(new Runnable() {
097: public void run() {
098: generateWsdlModel();
099: fireModelCreated(wsdlModel);
100: }
101: }, true);
102:
103: }
104:
105: public void setPackageName(String packageName) {
106: this .packageName = packageName;
107: }
108:
109: public String getPackageName() {
110: return packageName;
111: }
112:
113: public void setJAXBBindings(URL[] bindings) {
114: this .bindings = bindings;
115: }
116:
117: public URL[] getJAXBBindings() {
118: return bindings;
119: }
120:
121: public void setCatalog(URL catalog) {
122: this .catalog = catalog;
123: }
124:
125: public URL getCatalog() {
126: return catalog;
127: }
128:
129: void setWsdlUrl(URL url) {
130: wsdlUrl = url;
131: }
132:
133: public URL getWsdlUrl() {
134: return wsdlUrl;
135: }
136:
137: public Throwable getCreationException() {
138: return creationException;
139: }
140:
141: public WsdlModel getWsdlModel() {
142: return wsdlModel;
143: }
144:
145: public WsdlModel getAndWaitForWsdlModel() {
146: if (getWsdlModel() == null)
147: generateWsdlModel();
148: return wsdlModel;
149: }
150:
151: public void generateWsdlModel(WsdlModelListener listener,
152: final WsdlErrorHandler errorHandler) {
153: RequestProcessor.Task task = RequestProcessor.getDefault()
154: .create(new Runnable() {
155: public void run() {
156: generateWsdlModel(errorHandler);
157: synchronized (this ) {
158: fireModelCreated(wsdlModel);
159: }
160: }
161: }, true);
162: addWsdlModelListener(listener);
163: task.run();
164: }
165:
166: public void generateWsdlModel(WsdlModelListener listener) {
167: generateWsdlModel(listener, false);
168: }
169:
170: public void generateWsdlModel(WsdlModelListener listener,
171: boolean forceReload) {
172:
173: if (forceReload) {
174: try {
175: task.waitFinished(10000);
176: } catch (InterruptedException ex) {
177: }
178: addWsdlModelListener(listener);
179: task.schedule(0);
180: } else {
181: addWsdlModelListener(listener);
182: if (task.isFinished()) {
183: task.schedule(0);
184: }
185: }
186: }
187:
188: private void generateWsdlModel() {
189: this .generateWsdlModel(new CatchFirstErrorHandler());
190: }
191:
192: private void generateWsdlModel(WsdlErrorHandler errorHandler) {
193: WsimportOptions options = new WsimportOptions();
194: properties = new Properties();
195: bindingFiles = new HashSet<String>();
196: if (bindings != null) {
197: for (int i = 0; i < bindings.length; i++) {
198: try {
199: options.addBindings(JAXWSUtils
200: .absolutize(bindings[i].toExternalForm()));
201: } catch (BadCommandLineException ex) {
202: Logger.getLogger(this .getClass().getName()).log(
203: Level.FINE,
204: "WsdlModeler.generateWsdlModel", ex); //NOI18N
205: }
206: }
207: }
208: try {
209: if (wsdlUrl.toExternalForm().startsWith("http://")
210: || wsdlUrl.toExternalForm().startsWith("https://")) { //NOI18N
211: InputSource source = new InputSource(wsdlUrl
212: .toExternalForm());
213: options.addWSDL(source);
214: } else { // wsdl is in local file
215: options.addWSDL(new File(wsdlUrl.getFile()));
216: }
217: options.compatibilityMode = WsimportOptions.EXTENSION;
218:
219: if (packageName != null) {
220: options.defaultPackage = packageName;
221: }
222: if (catalog != null) {
223: CatalogManager manager = new CatalogManager(null);
224: manager.setCatalogFiles(catalog.toExternalForm());
225: options.entityResolver = entityResolver = new CatalogResolver(
226: manager);
227: }
228:
229: options.parseBindings(new IdeErrorReceiver(errorHandler));
230:
231: ideWSDLModeler = new WSDLModeler(options,
232: new IdeErrorReceiver(errorHandler));
233: Model tmpModel = ideWSDLModeler.buildModel();
234:
235: if (tmpModel != null) {
236: WsdlModel oldWsdlModel = wsdlModel;
237: wsdlModel = new WsdlModel(tmpModel);
238: fireWsdlModelChanged(oldWsdlModel, wsdlModel);
239: creationException = null;
240: } else {
241: WsdlModel oldWsdlModel = wsdlModel;
242: wsdlModel = null;
243: if (oldWsdlModel != null) {
244: fireWsdlModelChanged(oldWsdlModel, null);
245: }
246: SAXParseException parseError = null;
247: if (errorHandler instanceof CatchFirstErrorHandler) {
248: parseError = ((CatchFirstErrorHandler) errorHandler)
249: .getFirstError();
250: creationException = parseError;
251: }
252: if (parseError == null) {
253: creationException = new Exception(NbBundle
254: .getMessage(WsdlModeler.class,
255: "ERR_CannotGenerateModel", wsdlUrl
256: .toExternalForm()));
257: }
258: Logger.getLogger(this .getClass().getName()).log(
259: Level.FINE, "WsdlModeler.generateWsdlModel",
260: creationException); //NOI18N
261: }
262: } catch (Throwable ex) {
263: wsdlModel = null;
264: SAXParseException parseError = null;
265: if (errorHandler instanceof CatchFirstErrorHandler) {
266: parseError = ((CatchFirstErrorHandler) errorHandler)
267: .getFirstError();
268: creationException = parseError;
269: }
270: if (parseError == null) {
271: creationException = ex;
272: }
273: Logger.getLogger(this .getClass().getName()).log(Level.FINE,
274: "WsdlModeler.generateWsdlModel", ex); //NOI18N
275: }
276:
277: }
278:
279: private synchronized void addWsdlModelListener(
280: WsdlModelListener listener) {
281: // adding listener
282: if (listener != null)
283: modelListeners.add(listener);
284: }
285:
286: private synchronized void fireModelCreated(WsdlModel model) {
287: for (WsdlModelListener l : modelListeners) {
288: l.modelCreated(model);
289: }
290: // Removing all listeners
291: modelListeners.clear();
292: }
293:
294: private class IdeErrorReceiver extends ErrorReceiver {
295: private WsdlErrorHandler errorHandler;
296:
297: IdeErrorReceiver(WsdlErrorHandler errorHandler) {
298: this .errorHandler = errorHandler;
299: }
300:
301: public void warning(SAXParseException ex) throws AbortException {
302: Logger.getLogger(this .getClass().getName()).log(Level.FINE,
303: "WsdlModeler.generateWsdlModel", ex); //NOI18N
304: if (errorHandler != null) {
305: try {
306: errorHandler.warning(ex);
307: } catch (WsdlErrorHandler.AbortException abort) {
308: AbortException newEx = new AbortException();
309: newEx.initCause(abort);
310: throw newEx;
311: }
312: }
313: }
314:
315: public void info(SAXParseException ex) {
316: Logger.getLogger(this .getClass().getName()).log(Level.FINE,
317: "WsdlModeler.generateWsdlModel", ex); //NOI18N
318: if (errorHandler != null)
319: errorHandler.info(ex);
320: }
321:
322: public void fatalError(SAXParseException ex)
323: throws AbortException {
324: Logger.getLogger(this .getClass().getName()).log(Level.FINE,
325: "WsdlModeler.generateWsdlModel", ex); //NOI18N
326: if (errorHandler != null) {
327: try {
328: errorHandler.fatalError(ex);
329: } catch (WsdlErrorHandler.AbortException abort) {
330: AbortException newEx = new AbortException();
331: newEx.initCause(abort);
332: throw newEx;
333: }
334: }
335: }
336:
337: public void error(SAXParseException ex) throws AbortException {
338: Logger.getLogger(this .getClass().getName()).log(Level.FINE,
339: "WsdlModeler.generateWsdlModel", ex); //NOI18N
340: if (errorHandler != null) {
341: try {
342: errorHandler.error(ex);
343: } catch (WsdlErrorHandler.AbortException abort) {
344: AbortException newEx = new AbortException();
345: newEx.initCause(abort);
346: throw newEx;
347: }
348: }
349: }
350:
351: }
352:
353: public synchronized void addWsdlChangeListener(
354: WsdlChangeListener wsdlChangeListener) {
355: wsdlChangeListeners.add(wsdlChangeListener);
356: }
357:
358: public synchronized void removeWsdlChangeListener(
359: WsdlChangeListener wsdlChangeListener) {
360: wsdlChangeListeners.remove(wsdlChangeListener);
361: }
362:
363: private void fireWsdlModelChanged(WsdlModel oldWsdlModel,
364: WsdlModel newWsdlModel) {
365: for (WsdlChangeListener wsdlChangeListener : wsdlChangeListeners) {
366: wsdlChangeListener.wsdlModelChanged(oldWsdlModel,
367: newWsdlModel);
368: }
369: }
370:
371: private class CatchFirstErrorHandler implements WsdlErrorHandler {
372:
373: private SAXParseException firstError;
374:
375: public void warning(SAXParseException ex) throws AbortException {
376: }
377:
378: public void info(SAXParseException ex) {
379: }
380:
381: public void fatalError(SAXParseException ex)
382: throws AbortException {
383: if (firstError == null)
384: firstError = ex;
385: }
386:
387: public void error(SAXParseException ex) throws AbortException {
388: if (firstError == null)
389: firstError = ex;
390: }
391:
392: public SAXParseException getFirstError() {
393: return firstError;
394: }
395: }
396: }
|