blob: fd29bf8df041349dec1d1d98411384eaf334043a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.websvc.manager;
import org.netbeans.modules.websvc.manager.api.WebServiceDescriptor;
import org.netbeans.modules.websvc.manager.spi.WebServiceManagerExt;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.websvc.manager.codegen.Wsdl2Java;
import org.netbeans.modules.websvc.jaxwsmodelapi.WSService;
import org.netbeans.modules.websvc.jaxwsmodelapi.wsdlmodel.WsdlModel;
import org.netbeans.modules.websvc.jaxwsmodelapi.wsdlmodel.WsdlModelProvider;
import org.netbeans.modules.websvc.manager.model.WebServiceListModel;
import org.netbeans.modules.websvc.manager.model.WebServiceData;
import org.netbeans.modules.websvc.manager.model.WebServiceGroup;
import org.netbeans.modules.websvc.saas.spi.websvcmgr.WsdlServiceProxyDescriptor;
import org.netbeans.modules.websvc.saas.util.WsdlUtil;
import org.netbeans.modules.xml.retriever.Retriever;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
public final class WebServiceManager {
public static final String WEBSVC_HOME = WebServiceDescriptor.WEBSVC_HOME;
private int mutatorCount;
private static final WebServiceManager INSTANCE = new WebServiceManager();
private WebServiceManager() {
}
public static WebServiceManager getInstance() {
return INSTANCE;
}
public void addWebService(WebServiceData wsData) throws IOException {
addWebService(wsData, false);
}
/**
* Add webservice to the Web Service List Model.
* @param wsData The WebServiceData to add
* @param compile true if the client should be compiled immediately; ignored if client has already been compiled
*
* @throws java.io.IOException
*/
public void addWebService(WebServiceData wsData, boolean compile) throws IOException {
try {
incrementMutatorCount();
WebServiceListModel listModel = WebServiceListModel.getInstance();
if (wsData.getState().equals(WebServiceData.State.WSDL_UNRETRIEVED) ||
(wsData.getState().equals(WebServiceData.State.WSDL_RETRIEVING) &&
!wsData.isResolved())) {
wsData.setState(WebServiceData.State.WSDL_RETRIEVING);
File localWsdlFile = null;
try {
localWsdlFile = copyWsdlResources(wsData.getOriginalWsdlUrl());
} catch (IOException ex) {
wsData.setState(WebServiceData.State.WSDL_UNRETRIEVED);
throw ex;
}
File catalogFile = new File(WEBSVC_HOME, WsdlUtil.getCatalogForWsdl(wsData.getOriginalWsdlUrl()));
wsData.setWsdlFile(localWsdlFile.getAbsolutePath());
wsData.setCatalog(catalogFile.getAbsolutePath());
wsData.setState(WebServiceData.State.WSDL_RETRIEVED);
}
assert wsData.getWsdlFile() != null;
WsdlModel wsdlModel = getWsdlModel(wsData);
boolean dataInModel = listModel.webServiceExists(wsData);
if (wsdlModel == null) {
wsData.setResolved(false);
removeWebService(wsData, true, false);
return;
} else if (wsdlModel.getServices().isEmpty()) {
// If there are no services in the WSDL, warn the user
removeWebService(wsData);
String message = NbBundle.getMessage(WebServiceManager.class, "WS_NO_METHODS_ERROR");
NotifyDescriptor d = new NotifyDescriptor.Message(message);
DialogDisplayer.getDefault().notify(d);
return;
} else if (dataInModel) {
// for adding of services already in the model, only add a single service
boolean assigned = false;
for (WSService service : wsdlModel.getServices()) {
if (service.getName().equals(wsData.getName())) {
assigned = true;
wsData.setWsdlService(service);
wsData.setResolved(true);
}
}
if (!assigned) {
WSService defaultService = wsdlModel.getServices().get(0);
wsData.setWsdlService(defaultService);
wsData.setName(defaultService.getName());
wsData.setResolved(true);
}
listModel.getWebServiceGroup(wsData.getGroupId()).modify(wsData.getId());
try {
if (compile && !wsData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILED)) {
compileService(wsData);
}
} finally {
if (wsData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILE_FAILED)) {
wsData.setResolved(false);
}
}
} else {
// Create WebServiceData for each service and add to the model
boolean first = true;
for (WSService service : wsdlModel.getServices()) {
WebServiceData newData;
if (first) {
first = false;
newData = wsData;
} else {
newData = new WebServiceData(wsData.getWsdlFile(), wsData.getOriginalWsdlUrl(), wsData.getGroupId());
}
newData.setWsdlService(service);
newData.setResolved(true);
newData.setName(service.getName());
listModel.addWebService(newData);
WebServiceGroup group = listModel.getWebServiceGroup(newData.getGroupId());
if (group != null) {
group.add(newData.getId());
}
try {
if (compile && !newData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILED)) {
compileService(newData);
}
} finally {
if (newData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILE_FAILED)) {
removeWebService(newData);
}
}
}
}
} finally {
save();
}
}
public WsdlModel getWsdlModel(WebServiceData wsData) throws IOException {
File localWsdlFile = new File(wsData.getWsdlFile());
URL wsdlUrl = localWsdlFile.toURI().toURL();
WsdlModelProvider wsdlModelProvider = null;
Collection<? extends WsdlModelProvider> providers = Lookup.getDefault().
lookupAll(WsdlModelProvider.class);
boolean notAccepted = false;
if (providers != null) {
for (WsdlModelProvider provider : providers) {
if (provider.canAccept(wsdlUrl)) {
wsdlModelProvider = provider;
break;
} else {
notAccepted = true;
}
}
}
WsdlModel wsdlModel = null;
Throwable exc = null;
if (wsdlModelProvider != null) {
String packageName = wsData.getPackageName();
if(packageName == null || packageName.trim().length() == 0)
packageName = wsdlModelProvider.getEffectivePackageName();
File catalogFile = new File(wsData.getCatalog());
URL catalogUrl = catalogFile.toURI().toURL();
try {
wsdlModel = wsdlModelProvider.getWsdlModel(wsdlUrl, packageName,
catalogUrl, true );
} catch (Exception ex) {
Throwable e = ex.getCause();
exc = (e == null ? ex : e);
}
}
if (wsdlModel == null) {
wsData.setResolved(false);
removeWebService(wsData, true, false);
if (wsdlModelProvider == null && notAccepted) {
DialogDisplayer.getDefault().notify(
new DialogDescriptor.Message(NbBundle.getMessage(WebServiceManager.class, "JAX_RPC_MODELER_ERROR")));
} else if (wsdlModelProvider != null) {
Throwable ex = wsdlModelProvider.getCreationException();
if (ex != null) {
DialogDisplayer.getDefault().notify(
new DialogDescriptor.Message(NbBundle.getMessage(WebServiceManager.class, "JAX_WS_MODEL_CREATION_ERROR", ex.getLocalizedMessage())));
} else if (exc != null) {
Logger.getLogger(WebServiceManager.class.getName()).log(Level.WARNING,
NbBundle.getMessage(WebServiceManager.class, "JAX_WS_MODELER_ERROR"), exc);
} else {
String message = NbBundle.getMessage(WebServiceManager.class, "WS_MODELER_ERROR");
exc = new IllegalStateException(message);
Exceptions.printStackTrace(exc);
}
} else {
String message = NbBundle.getMessage(WebServiceManager.class, "WS_MODELER_ERROR");
exc = new IllegalStateException(message);
Exceptions.printStackTrace(exc);
}
}
return wsdlModel;
}
public
void refreshWebService(WebServiceData wsData) throws IOException {
removeWebService(wsData, false, true);
wsData.setWsdlFile(null);
wsData.setState(WebServiceData.State.WSDL_UNRETRIEVED);
wsData.setCatalog(null);
wsData.setWsdlService(null);
wsData.setJaxRpcDescriptorPath(null);
wsData.setJaxRpcDescriptor(null);
wsData.setJaxWsDescriptor(null);
wsData.setJaxWsDescriptorPath(null);
addWebService(wsData, true);
}
public void resetWebService(WebServiceData wsData) {
removeWebService(wsData, false, true);
wsData.setWsdlFile(null);
wsData.setState(WebServiceData.State.WSDL_UNRETRIEVED);
wsData.setCatalog(null);
wsData.setWsdlService(null);
wsData.setJaxRpcDescriptorPath(null);
wsData.setJaxRpcDescriptor(null);
wsData.setJaxWsDescriptor(null);
wsData.setJaxWsDescriptorPath(null);
}
/**
* Add webservice to the Web Service List Model.
*
* @param wsdl the wsdl URL
* @param packageName the package for the webservice java classes
* @param groupId the id of the group the webservice belongs to
*
* @throws java.io.IOException if the web service could not be added
*/
public WebServiceData addWebService(String wsdl, String packageName, String groupId) throws IOException {
WebServiceData wsData = new WebServiceData(wsdl, groupId);
wsData.setPackageName(packageName);
wsData.setResolved(false);
addWebService(wsData, true);
return wsData;
}
/**
* Removes a webservice from the Web Service List Model.
* Client jars and other data are deleted from the filesystem.
*
* @param wsData the WebService to remove
*/
public void removeWebService(WebServiceData wsData) {
removeWebService(wsData, true, true);
}
private void removeWebService(WebServiceData wsData, boolean removeFromModel, boolean deleteWsdl) {
try {
incrementMutatorCount();
if (removeFromModel) {
WebServiceListModel.getInstance().removeWebService(wsData.getId());
}
Collection<? extends WebServiceManagerExt> extensions = Lookup.getDefault().lookupAll(WebServiceManagerExt.class);
WebServiceDescriptor jaxRpcDescriptor = wsData.getJaxRpcDescriptor();
WebServiceDescriptor jaxWsDescriptor = wsData.getJaxWsDescriptor();
for (WebServiceManagerExt extension : extensions) {
if (jaxRpcDescriptor != null) {
extension.wsServiceRemovedExt(jaxRpcDescriptor);
}
if (jaxWsDescriptor != null) {
extension.wsServiceRemovedExt(jaxWsDescriptor);
}
}
deleteWsArtifacts(jaxRpcDescriptor);
deleteWsArtifacts(jaxWsDescriptor);
// remove w/s directory
if (wsData.getName() != null) {
new File(WEBSVC_HOME, wsData.getName()).delete();
}
if (wsData.getWsdlFile() == null) {
return;
}
if (!deleteWsdl) {
return;
}
WebServiceListModel model = WebServiceListModel.getInstance();
for (WebServiceData data : model.getWebServiceSet()) {
if (data != wsData && wsData.getWsdlFile().equals(data.getWsdlFile())) {
deleteWsdl = false;
break;
}
}
if (deleteWsdl) {
// remove the top-level wsdl file
rmDir(new File(wsData.getWsdlFile()));
if (wsData.getCatalog() != null) {
File catalogFile = new File(wsData.getCatalog());
if (catalogFile.exists()) {
rmDir(catalogFile.getParentFile());
}
}
}
} finally {
save();
}
}
/**
* Utility method to remove the web service and delete any generated artifacts
* @param proxyDescriptor the WebServiceDescriptor representing a set of proxy jars
*/
private void deleteWsArtifacts(WebServiceDescriptor proxyDescriptor) {
if (proxyDescriptor == null) {
return;
}
File proxyRoot = proxyDescriptor.getXmlDescriptorFile().getParentFile();
assert proxyRoot != null;
// delete all registered jar files
for (WebServiceDescriptor.JarEntry jar : proxyDescriptor.getJars()) {
File jarFile = new File(proxyRoot, jar.getName());
jarFile.delete();
}
// delete xml descriptor
proxyDescriptor.getXmlDescriptorFile().delete();
// remove the empty directory
proxyRoot.delete();
}
private static void rmDir(File dir) {
if (dir == null) {
return;
}
FileObject fo = FileUtil.toFileObject(dir);
if (fo != null) {
FileLock lock = null;
try {
lock = fo.lock();
fo.delete(lock);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
} finally {
if (lock != null) {
lock.releaseLock();
}
}
}
}
static File copyWsdlResources(String wsdlUrl) throws IOException {
File userDirFile = new File(WEBSVC_HOME);
File catalogFile = new File(userDirFile, WsdlUtil.getCatalogForWsdl(wsdlUrl));
File dir = catalogFile.getParentFile();
boolean success = false;
dir = catalogFile.getParentFile();
try {
FileObject dirFO = FileUtil.createFolder(dir);
URI catalog = catalogFile.toURI();
URI wsdlUri = new URL(wsdlUrl).toURI();
Retriever retriever = Retriever.getDefault();
FileObject wsdlFO = retriever.retrieveResource(dirFO, catalog, wsdlUri);
if (wsdlFO == null) {
throw new IOException(NbBundle.getMessage(WebServiceManager.class, "WSDL_COPY_ERROR"));
}
FileUtil.createFolder(new File(WEBSVC_HOME));
File result = FileUtil.toFile(wsdlFO);
success = true;
return result;
} catch (URISyntaxException ex) {
throw new IOException(ex.getLocalizedMessage());
} finally {
if (catalogFile.exists() && !success) {
rmDir(catalogFile.getParentFile());
}
}
}
public static synchronized void compileService(WebServiceData wsData) {
boolean compileAttempted = false;
try {
if (WebServiceListModel.getInstance().getWebService(wsData.getId()) == null ||
wsData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILED) ||
wsData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILING)) {
return;
}
wsData.setState(WebServiceData.State.WSDL_SERVICE_COMPILING);
compileAttempted = true;
Collection<? extends WebServiceManagerExt> extensions = Lookup.getDefault().lookupAll(WebServiceManagerExt.class);
WSService svc = wsData.getWsdlService();
// compile the WSDL and create the proxy jars
Wsdl2Java wsdl2Java = new Wsdl2Java(wsData);
boolean success = wsdl2Java.createProxyJars();
if (!success) {
return;
}
URL wsdl = new File(wsData.getWsdlFile()).toURI().toURL();
String packageName = wsData.getEffectivePackageName();
if (wsData.isJaxRpcEnabled()) {
WebServiceDescriptor jaxRpcDescriptor = new WebServiceDescriptor(wsData.getName(), packageName, WebServiceDescriptor.JAX_RPC_TYPE, wsdl, new File(WEBSVC_HOME, wsData.getJaxRpcDescriptorPath()), svc);
jaxRpcDescriptor.addJar(wsData.getName() + ".jar", WebServiceDescriptor.JarEntry.PROXY_JAR_TYPE);
jaxRpcDescriptor.addJar(wsData.getName() + "-src.jar", WebServiceDescriptor.JarEntry.SRC_JAR_TYPE);
wsData.setJaxRpcDescriptor(jaxRpcDescriptor);
}
if (wsData.isJaxWsEnabled()) {
WebServiceDescriptor jaxWsDescriptor = new WebServiceDescriptor(wsData.getName(), packageName, WebServiceDescriptor.JAX_WS_TYPE, wsdl, new File(WEBSVC_HOME, wsData.getJaxWsDescriptorPath()), svc);
jaxWsDescriptor.addJar(wsData.getName() + ".jar", WebServiceDescriptor.JarEntry.PROXY_JAR_TYPE);
jaxWsDescriptor.addJar(wsData.getName() + "-src.jar", WebServiceDescriptor.JarEntry.SRC_JAR_TYPE);
wsData.setJaxWsDescriptor(jaxWsDescriptor);
}
// create additional classes and jars from registered consumers
// (e.g. designtime API implementations, client beans, dataproviders, etc.)
boolean hasJaxWsConsumer = false;
boolean hasJaxRpcConsumer = false;
for (WebServiceManagerExt extension : extensions) {
if (wsData.getJaxRpcDescriptor() != null) {
if (extension.wsServiceAddedExt(wsData.getJaxRpcDescriptor())) {
hasJaxRpcConsumer = true;
}
}
if (wsData.getJaxWsDescriptor() != null) {
if (extension.wsServiceAddedExt(wsData.getJaxWsDescriptor())) {
hasJaxWsConsumer = true;
}
}
}
// delete everything if no consumer could be created, otherwise
// only delete the artifacts of the failed ws type
if (!hasJaxWsConsumer && !hasJaxRpcConsumer) {
WebServiceManager.getInstance().removeWebService(wsData);
} else if (!hasJaxWsConsumer && wsData.getJaxWsDescriptor() != null) {
WebServiceManager.getInstance().deleteWsArtifacts(wsData.getJaxWsDescriptor());
wsData.setJaxWsDescriptor(null);
wsData.setJaxWsDescriptorPath(null);
wsData.setJaxWsEnabled(false);
} else if (!hasJaxRpcConsumer && wsData.getJaxRpcDescriptor() != null) {
WebServiceManager.getInstance().deleteWsArtifacts(wsData.getJaxRpcDescriptor());
wsData.setJaxRpcDescriptor(null);
wsData.setJaxRpcDescriptorPath(null);
wsData.setJaxRpcEnabled(false);
}
if (hasJaxWsConsumer || hasJaxRpcConsumer) {
wsData.setState(WebServiceData.State.WSDL_SERVICE_COMPILED);
wsData.setCompiled(true);
}
} catch (IOException ex) {
Logger.getGlobal().log(Level.INFO, ex.getLocalizedMessage(), ex);
} finally {
if (!wsData.getState().equals(WebServiceData.State.WSDL_SERVICE_COMPILED) && compileAttempted) {
wsData.setState(WebServiceData.State.WSDL_SERVICE_COMPILE_FAILED);
} else {
saveDescriptor(wsData);
}
}
}
private synchronized void incrementMutatorCount() {
mutatorCount++;
//System.out.println("incrementMutatorCount() mutatorCount = " + mutatorCount);
}
private synchronized void save() {
if (--mutatorCount <= 0) {
if (WebServiceListModel.getInstance().isDirty()) {
//System.out.println("saving ws model");
new WebServicePersistenceManager().save();
WebServiceListModel.getInstance().setDirty(false);
}
}
//System.out.println("save() mutatorCount = " + mutatorCount);
}
private static void saveDescriptor(WebServiceData data) {
WebServicePersistenceManager mgr = new WebServicePersistenceManager();
try {
WebServiceDescriptor desc = data.getJaxWsDescriptor();
mgr.saveDescriptor(desc);
desc = data.getJaxRpcDescriptor();
mgr.saveDescriptor(desc);
} catch (Exception ex) {
}
}
}