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-2007 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: package org.netbeans.modules.websvc.manager;
042:
043: import org.netbeans.modules.websvc.manager.api.WebServiceDescriptor;
044: import org.netbeans.modules.websvc.manager.spi.WebServiceManagerExt;
045: import java.io.File;
046: import java.io.IOException;
047: import java.net.URI;
048: import java.net.URISyntaxException;
049: import java.net.URL;
050: import java.util.Collection;
051: import java.util.logging.Level;
052: import java.util.logging.Logger;
053: import org.netbeans.modules.websvc.manager.codegen.Wsdl2Java;
054: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModel;
055: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModeler;
056: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlModelerFactory;
057: import org.netbeans.modules.websvc.api.jaxws.wsdlmodel.WsdlService;
058:
059: import org.netbeans.modules.websvc.manager.model.WebServiceListModel;
060: import org.netbeans.modules.websvc.manager.model.WebServiceData;
061: import org.netbeans.modules.websvc.manager.model.WebServiceGroup;
062: import org.netbeans.modules.websvc.saas.util.WsdlUtil;
063: import org.netbeans.modules.xml.retriever.Retriever;
064: import org.openide.DialogDisplayer;
065: import org.openide.NotifyDescriptor;
066: import org.openide.filesystems.FileLock;
067: import org.openide.filesystems.FileObject;
068: import org.openide.filesystems.FileUtil;
069: import org.openide.util.Exceptions;
070: import org.openide.util.Lookup;
071: import org.openide.util.NbBundle;
072: import org.openide.util.RequestProcessor;
073:
074: public final class WebServiceManager {
075:
076: private static WebServiceManager wsMgr;
077: public static String WEBSVC_HOME = WebServiceDescriptor.WEBSVC_HOME;
078: private RequestProcessor modeler;
079:
080: private WebServiceManager() {
081: }
082:
083: public static WebServiceManager getInstance() {
084: if (wsMgr == null) {
085: wsMgr = new WebServiceManager();
086: }
087: return wsMgr;
088: }
089:
090: public void addWebService(WebServiceData wsData) throws IOException {
091: addWebService(wsData, false);
092: }
093:
094: /**
095: * Add webservice to the Web Service List Model.
096: * @param wsData The WebServiceData to add
097: * @param compile true if the client should be compiled immediately; ignored if client has already been compiled
098: *
099: * @throws java.io.IOException
100: */
101: public void addWebService(WebServiceData wsData, boolean compile)
102: throws IOException {
103: WebServiceListModel listModel = WebServiceListModel
104: .getInstance();
105:
106: if (wsData.getState().equals(
107: WebServiceData.State.WSDL_UNRETRIEVED)
108: || (wsData.getState().equals(
109: WebServiceData.State.WSDL_RETRIEVING) && !wsData
110: .isResolved())) {
111: wsData.setState(WebServiceData.State.WSDL_RETRIEVING);
112:
113: File localWsdlFile = copyWsdlResources(wsData
114: .getOriginalWsdlUrl());
115: File catalogFile = new File(WEBSVC_HOME, WsdlUtil
116: .getCatalogForWsdl(wsData.getOriginalWsdlUrl()));
117:
118: wsData.setWsdlFile(localWsdlFile.getAbsolutePath());
119: wsData.setCatalog(catalogFile.getAbsolutePath());
120: wsData.setState(WebServiceData.State.WSDL_RETRIEVED);
121: }
122:
123: assert wsData.getWsdlFile() != null;
124:
125: File localWsdlFile = new File(wsData.getWsdlFile());
126: URL wsdlUrl = localWsdlFile.toURI().toURL();
127:
128: WsdlModeler wsdlModeler = WsdlModelerFactory.getDefault()
129: .getWsdlModeler(wsdlUrl);
130: if (wsData.getPackageName() != null
131: && wsData.getPackageName().trim().length() > 0) {
132: wsdlModeler.setPackageName(wsData.getPackageName());
133: }
134: WsdlModel model = wsdlModeler.getAndWaitForWsdlModel();
135:
136: boolean dataInModel = listModel.webServiceExists(wsData);
137:
138: if (model == null) {
139: wsData.setResolved(false);
140: removeWebService(wsData, true, false);
141:
142: Throwable exc = wsdlModeler.getCreationException();
143: String cause = (exc != null) ? exc.getLocalizedMessage()
144: : null;
145: String excString = (exc != null) ? exc.getClass().getName()
146: + " - " + cause : null;
147: String message = NbBundle.getMessage(
148: WebServiceManager.class, "WS_MODELER_ERROR")
149: + "\n\n" + excString; // NOI18N
150: Exceptions.printStackTrace(Exceptions
151: .attachLocalizedMessage(exc, message));
152: return;
153: } else if (model.getServices().isEmpty()) {
154: // If there are no services in the WSDL, warn the user
155: removeWebService(wsData);
156: String message = NbBundle.getMessage(
157: WebServiceManager.class, "WS_NO_METHODS_ERROR");
158: NotifyDescriptor d = new NotifyDescriptor.Message(message);
159: DialogDisplayer.getDefault().notify(d);
160: return;
161: } else if (dataInModel) {
162: // for adding of services already in the model, only add a single service
163: boolean assigned = false;
164: for (WsdlService service : model.getServices()) {
165: if (service.getName().equals(wsData.getName())) {
166: assigned = true;
167: wsData.setWsdlService(service);
168: wsData.setResolved(true);
169: }
170: }
171:
172: if (!assigned) {
173: WsdlService defaultService = model.getServices().get(0);
174: wsData.setWsdlService(defaultService);
175: wsData.setName(defaultService.getName());
176: wsData.setResolved(true);
177: }
178:
179: listModel.getWebServiceGroup(wsData.getGroupId()).modify(
180: wsData.getId());
181:
182: try {
183: if (compile
184: && !wsData
185: .getState()
186: .equals(
187: WebServiceData.State.WSDL_SERVICE_COMPILED)) {
188: compileService(wsData);
189: }
190: } finally {
191: if (wsData
192: .getState()
193: .equals(
194: WebServiceData.State.WSDL_SERVICE_COMPILE_FAILED)) {
195: wsData.setResolved(false);
196: }
197: }
198: } else {
199: // Create WebServiceData for each service and add to the model
200: boolean first = true;
201: for (WsdlService service : model.getServices()) {
202: WebServiceData newData;
203: if (first) {
204: first = false;
205: newData = wsData;
206: } else {
207: newData = new WebServiceData(wsData.getWsdlFile(),
208: wsData.getOriginalWsdlUrl(), wsData
209: .getGroupId());
210: }
211:
212: newData.setWsdlService(service);
213: newData.setResolved(true);
214: newData.setName(service.getName());
215:
216: listModel.addWebService(newData);
217: WebServiceGroup group = listModel
218: .getWebServiceGroup(newData.getGroupId());
219: if (group != null) {
220: group.add(newData.getId());
221: }
222:
223: try {
224: if (compile
225: && !newData
226: .getState()
227: .equals(
228: WebServiceData.State.WSDL_SERVICE_COMPILED)) {
229: compileService(newData);
230: }
231: } finally {
232: if (newData
233: .getState()
234: .equals(
235: WebServiceData.State.WSDL_SERVICE_COMPILE_FAILED)) {
236: removeWebService(newData);
237: }
238: }
239: }
240: }
241: }
242:
243: public void refreshWebService(WebServiceData wsData)
244: throws IOException {
245: removeWebService(wsData, false, true);
246: wsData.setWsdlFile(null);
247: wsData.setState(WebServiceData.State.WSDL_UNRETRIEVED);
248: wsData.setCatalog(null);
249: wsData.setWsdlService(null);
250: wsData.setJaxRpcDescriptorPath(null);
251: wsData.setJaxRpcDescriptor(null);
252: wsData.setJaxWsDescriptor(null);
253: wsData.setJaxWsDescriptorPath(null);
254:
255: addWebService(wsData, true);
256: }
257:
258: public void resetWebService(WebServiceData wsData) {
259: removeWebService(wsData, false, true);
260:
261: wsData.setWsdlFile(null);
262: wsData.setState(WebServiceData.State.WSDL_UNRETRIEVED);
263: wsData.setCatalog(null);
264: wsData.setWsdlService(null);
265: wsData.setJaxRpcDescriptorPath(null);
266: wsData.setJaxRpcDescriptor(null);
267: wsData.setJaxWsDescriptor(null);
268: wsData.setJaxWsDescriptorPath(null);
269: }
270:
271: /**
272: * Add webservice to the Web Service List Model.
273: *
274: * @param wsdl the wsdl URL
275: * @param packageName the package for the webservice java classes
276: * @param groupId the id of the group the webservice belongs to
277: *
278: * @throws java.io.IOException if the web service could not be added
279: */
280: public WebServiceData addWebService(String wsdl,
281: String packageName, String groupId) throws IOException {
282: WebServiceData wsData = new WebServiceData(wsdl, groupId);
283: wsData.setPackageName(packageName);
284: wsData.setResolved(false);
285:
286: addWebService(wsData, true);
287: return wsData;
288: }
289:
290: /**
291: * Removes a webservice from the Web Service List Model.
292: * Client jars and other data are deleted from the filesystem.
293: *
294: * @param wsData the WebService to remove
295: */
296: public void removeWebService(WebServiceData wsData) {
297: removeWebService(wsData, true, true);
298: }
299:
300: private void removeWebService(WebServiceData wsData,
301: boolean removeFromModel, boolean deleteWsdl) {
302: if (removeFromModel) {
303: WebServiceListModel.getInstance().removeWebService(
304: wsData.getId());
305: }
306: Collection<? extends WebServiceManagerExt> extensions = Lookup
307: .getDefault().lookupAll(WebServiceManagerExt.class);
308: WebServiceDescriptor jaxRpcDescriptor = wsData
309: .getJaxRpcDescriptor();
310: WebServiceDescriptor jaxWsDescriptor = wsData
311: .getJaxWsDescriptor();
312:
313: for (WebServiceManagerExt extension : extensions) {
314: if (jaxRpcDescriptor != null) {
315: extension.wsServiceRemovedExt(jaxRpcDescriptor);
316: }
317: if (jaxWsDescriptor != null) {
318: extension.wsServiceRemovedExt(jaxWsDescriptor);
319: }
320: }
321:
322: deleteWsArtifacts(jaxRpcDescriptor);
323: deleteWsArtifacts(jaxWsDescriptor);
324:
325: // remove w/s directory
326: if (wsData.getName() != null) {
327: new File(WEBSVC_HOME, wsData.getName()).delete();
328: }
329:
330: if (wsData.getWsdlFile() == null) {
331: return;
332: }
333:
334: if (!deleteWsdl) {
335: return;
336: }
337:
338: WebServiceListModel model = WebServiceListModel.getInstance();
339: for (WebServiceData data : model.getWebServiceSet()) {
340: if (data != wsData
341: && wsData.getWsdlFile().equals(data.getWsdlFile())) {
342: deleteWsdl = false;
343: break;
344: }
345: }
346:
347: if (deleteWsdl) {
348: // remove the top-level wsdl file
349: rmDir(new File(wsData.getWsdlFile()));
350:
351: if (wsData.getCatalog() != null) {
352: File catalogFile = new File(wsData.getCatalog());
353: if (catalogFile.exists()) {
354: rmDir(catalogFile.getParentFile());
355: }
356: }
357: }
358: }
359:
360: public RequestProcessor getRequestProcessor() {
361: if (modeler == null) {
362: modeler = new RequestProcessor(
363: "Services/Web services-modeler"); // NOI18N
364: }
365:
366: return modeler;
367: }
368:
369: /**
370: * Utility method to remove the web service and delete any generated artifacts
371: * @param proxyDescriptor the WebServiceDescriptor representing a set of proxy jars
372: */
373: private void deleteWsArtifacts(WebServiceDescriptor proxyDescriptor) {
374: if (proxyDescriptor == null) {
375: return;
376: }
377:
378: File proxyRoot = proxyDescriptor.getXmlDescriptorFile()
379: .getParentFile();
380: assert proxyRoot != null;
381:
382: // delete all registered jar files
383: for (WebServiceDescriptor.JarEntry jar : proxyDescriptor
384: .getJars()) {
385: File jarFile = new File(proxyRoot, jar.getName());
386: jarFile.delete();
387: }
388:
389: // delete xml descriptor
390: proxyDescriptor.getXmlDescriptorFile().delete();
391:
392: // remove the empty directory
393: proxyRoot.delete();
394: }
395:
396: private static void rmDir(File dir) {
397: if (dir == null) {
398: return;
399: }
400:
401: FileObject fo = FileUtil.toFileObject(dir);
402: if (fo != null) {
403: FileLock lock = null;
404: try {
405: lock = fo.lock();
406: fo.delete(lock);
407: } catch (IOException ex) {
408: Exceptions.printStackTrace(ex);
409: } finally {
410: if (lock != null) {
411: lock.releaseLock();
412: }
413: }
414: }
415: }
416:
417: static File copyWsdlResources(String wsdlUrl) throws IOException {
418: File userDirFile = new File(WEBSVC_HOME);
419: File catalogFile = new File(userDirFile, WsdlUtil
420: .getCatalogForWsdl(wsdlUrl));
421: File dir = catalogFile.getParentFile();
422:
423: boolean success = false;
424: dir = catalogFile.getParentFile();
425: try {
426: FileObject dirFO = FileUtil.createFolder(dir);
427: URI catalog = catalogFile.toURI();
428: URI wsdlUri = new URL(wsdlUrl).toURI();
429:
430: Retriever retriever = Retriever.getDefault();
431: FileObject wsdlFO = retriever.retrieveResource(dirFO,
432: catalog, wsdlUri);
433:
434: if (wsdlFO == null) {
435: throw new IOException(NbBundle.getMessage(
436: WebServiceManager.class, "WSDL_COPY_ERROR"));
437: }
438:
439: FileObject userdir = FileUtil.createFolder(new File(
440: WEBSVC_HOME));
441: File result = FileUtil.toFile(wsdlFO);
442: success = true;
443: return result;
444: } catch (URISyntaxException ex) {
445: throw new IOException(ex.getLocalizedMessage());
446: } finally {
447: if (catalogFile.exists() && !success) {
448: rmDir(catalogFile.getParentFile());
449: }
450: }
451: }
452:
453: public static synchronized void compileService(WebServiceData wsData) {
454: boolean compileAttempted = false;
455: try {
456: if (WebServiceListModel.getInstance().getWebService(
457: wsData.getId()) == null
458: || wsData.getState().equals(
459: WebServiceData.State.WSDL_SERVICE_COMPILED)
460: || wsData
461: .getState()
462: .equals(
463: WebServiceData.State.WSDL_SERVICE_COMPILING)) {
464: return;
465: }
466: wsData
467: .setState(WebServiceData.State.WSDL_SERVICE_COMPILING);
468: compileAttempted = true;
469:
470: Collection<? extends WebServiceManagerExt> extensions = Lookup
471: .getDefault().lookupAll(WebServiceManagerExt.class);
472: WsdlService svc = wsData.getWsdlService();
473:
474: // compile the WSDL and create the proxy jars
475: Wsdl2Java wsdl2Java = new Wsdl2Java(wsData);
476: boolean success = wsdl2Java.createProxyJars();
477: if (!success) {
478: return;
479: }
480: URL wsdl = new File(wsData.getWsdlFile()).toURI().toURL();
481: String packageName = wsData.getEffectivePackageName();
482: if (wsData.isJaxRpcEnabled()) {
483: WebServiceDescriptor jaxRpcDescriptor = new WebServiceDescriptor(
484: wsData.getName(), packageName,
485: WebServiceDescriptor.JAX_RPC_TYPE, wsdl,
486: new File(WEBSVC_HOME, wsData
487: .getJaxRpcDescriptorPath()), svc);
488: jaxRpcDescriptor.addJar(wsData.getName() + ".jar",
489: WebServiceDescriptor.JarEntry.PROXY_JAR_TYPE);
490: jaxRpcDescriptor.addJar(wsData.getName() + "-src.jar",
491: WebServiceDescriptor.JarEntry.SRC_JAR_TYPE);
492:
493: wsData.setJaxRpcDescriptor(jaxRpcDescriptor);
494: }
495: if (wsData.isJaxWsEnabled()) {
496: WebServiceDescriptor jaxWsDescriptor = new WebServiceDescriptor(
497: wsData.getName(), packageName,
498: WebServiceDescriptor.JAX_WS_TYPE, wsdl,
499: new File(WEBSVC_HOME, wsData
500: .getJaxWsDescriptorPath()), svc);
501: jaxWsDescriptor.addJar(wsData.getName() + ".jar",
502: WebServiceDescriptor.JarEntry.PROXY_JAR_TYPE);
503: jaxWsDescriptor.addJar(wsData.getName() + "-src.jar",
504: WebServiceDescriptor.JarEntry.SRC_JAR_TYPE);
505:
506: wsData.setJaxWsDescriptor(jaxWsDescriptor);
507: }
508:
509: // create additional classes and jars from registered consumers
510: // (e.g. designtime API implementations, client beans, dataproviders, etc.)
511: boolean hasJaxWsConsumer = false;
512: boolean hasJaxRpcConsumer = false;
513: for (WebServiceManagerExt extension : extensions) {
514: if (wsData.getJaxRpcDescriptor() != null) {
515: if (extension.wsServiceAddedExt(wsData
516: .getJaxRpcDescriptor())) {
517: hasJaxRpcConsumer = true;
518: }
519: }
520: if (wsData.getJaxWsDescriptor() != null) {
521: if (extension.wsServiceAddedExt(wsData
522: .getJaxWsDescriptor())) {
523: hasJaxWsConsumer = true;
524: }
525: }
526: }
527:
528: // delete everything if no consumer could be created, otherwise
529: // only delete the artifacts of the failed ws type
530: if (!hasJaxWsConsumer && !hasJaxRpcConsumer) {
531: WebServiceManager.getInstance()
532: .removeWebService(wsData);
533: } else if (!hasJaxWsConsumer
534: && wsData.getJaxWsDescriptor() != null) {
535: WebServiceManager.getInstance().deleteWsArtifacts(
536: wsData.getJaxWsDescriptor());
537: wsData.setJaxWsDescriptor(null);
538: wsData.setJaxWsDescriptorPath(null);
539: wsData.setJaxWsEnabled(false);
540: } else if (!hasJaxRpcConsumer
541: && wsData.getJaxRpcDescriptor() != null) {
542: WebServiceManager.getInstance().deleteWsArtifacts(
543: wsData.getJaxRpcDescriptor());
544: wsData.setJaxRpcDescriptor(null);
545: wsData.setJaxRpcDescriptorPath(null);
546: wsData.setJaxRpcEnabled(false);
547: }
548:
549: if (hasJaxWsConsumer || hasJaxRpcConsumer) {
550: wsData
551: .setState(WebServiceData.State.WSDL_SERVICE_COMPILED);
552: wsData.setCompiled(true);
553: }
554: } catch (IOException ex) {
555: Logger.global.log(Level.INFO, ex.getLocalizedMessage(), ex);
556: } finally {
557: if (!wsData.getState().equals(
558: WebServiceData.State.WSDL_SERVICE_COMPILED)
559: && compileAttempted) {
560: wsData
561: .setState(WebServiceData.State.WSDL_SERVICE_COMPILE_FAILED);
562: }
563: }
564: }
565: }
|