blob: 1086a29ed67987a13211fe9bf4081d87ee516691 [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.maven.jaxws;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.netbeans.api.project.Project;
import org.netbeans.modules.j2ee.dd.api.webservices.PortComponent;
import org.netbeans.modules.j2ee.dd.api.webservices.WebserviceDescription;
import org.netbeans.modules.j2ee.dd.api.webservices.Webservices;
import org.netbeans.modules.j2ee.dd.api.webservices.WebservicesMetadata;
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
import org.netbeans.modules.j2ee.metadata.model.api.MetadataModel;
import org.netbeans.modules.j2ee.metadata.model.api.MetadataModelAction;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.websvc.jaxws.light.api.JAXWSLightSupport;
import org.netbeans.modules.websvc.jaxws.light.api.JaxWsService;
import org.netbeans.modules.websvc.jaxws.light.spi.JAXWSLightSupportFactory;
import org.netbeans.modules.websvc.jaxws.light.spi.JAXWSLightSupportImpl;
import org.netbeans.modules.websvc.jaxws.light.spi.JAXWSLightSupportProvider;
import org.netbeans.modules.websvc.project.api.WebService;
import org.netbeans.modules.websvc.project.spi.LookupMergerSupport;
import org.netbeans.modules.websvc.project.spi.WebServiceFactory;
import org.netbeans.modules.websvc.project.spi.WebServiceDataProvider;
import org.netbeans.spi.project.LookupMerger;
import org.netbeans.spi.project.ProjectServiceProvider;
import org.netbeans.spi.project.ui.ProjectOpenedHook;
import org.openide.filesystems.FileObject;
import org.openide.util.RequestProcessor;
/**
*
* @author mkuchtiak
*/
@ProjectServiceProvider(projectType="org-netbeans-modules-maven",
service={JAXWSLightSupportProvider.class, WebServiceDataProvider.class, ProjectOpenedHook.class})
public class MavenJaxWsSupportProvider extends ProjectOpenedHook
implements JAXWSLightSupportProvider, WebServiceDataProvider, PropertyChangeListener
{
private static final RequestProcessor MAVEN_WS_RP =
new RequestProcessor("MavenJaxWsSupportProvider.WS_REQUEST_PROCESSOR"); //NOI18N
private static final RequestProcessor rp =
new RequestProcessor("MavenJaxWsSupportProvider-request-processor"); // NOI18N
private RequestProcessor.Task pomChangesTask = MAVEN_WS_RP.create(new Runnable() {
@Override
public void run() {
reactOnPomChanges();
}
});
private static final Logger LOG = Logger.getLogger(MavenJaxWsSupportProvider.class.getName());
private JAXWSLightSupport jaxWsSupport;
private PropertyChangeListener pcl;
private NbMavenProject mp;
private Project prj;
private volatile String serverInstance;
//private MetadataModel<WebservicesMetadata> wsModel;
private List<WebService> providers = new LinkedList<WebService>();
private List<WebService> consumers = new LinkedList<WebService>();
public MavenJaxWsSupportProvider(final Project prj) {
JAXWSLightSupportImpl spiJAXWSSupport = new MavenJAXWSSupportImpl(prj);
this.prj = prj;
this.jaxWsSupport = JAXWSLightSupportFactory.createJAXWSSupport(spiJAXWSSupport);
jaxWsSupport.addPropertyChangeListener(this);
}
/* (non-Javadoc)
* @see org.netbeans.spi.project.ui.ProjectOpenedHook#projectClosed()
*/
@Override
protected void projectClosed() {
}
/* (non-Javadoc)
* @see org.netbeans.spi.project.ui.ProjectOpenedHook#projectOpened()
*/
@Override
protected void projectOpened() {
MAVEN_WS_RP.post(new Runnable() {
public void run() {
registerPCL();
J2eeModuleProvider provider = prj.getLookup().lookup(
J2eeModuleProvider.class);
MetadataModel<WebservicesMetadata> model = jaxWsSupport
.getWebservicesMetadataModel();
if (model != null) {
registerAnnotationListener(model);
}
serverInstance = provider == null ? null : provider
.getServerInstanceID();
// wsModel = model;
}
});
rp.post(new Runnable() {
@Override
public void run() {
WSUtils.detectWsdlClients(prj, jaxWsSupport);
}
});
}
@Override
public JAXWSLightSupport findJAXWSSupport() {
return jaxWsSupport;
}
@Override
public List<WebService> getServiceProviders() {
return providers;
}
@Override
public List<WebService> getServiceConsumers() {
return consumers;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener pcl) {
jaxWsSupport.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
jaxWsSupport.removePropertyChangeListener(pcl);
}
@LookupMerger.Registration(projectType="org-netbeans-modules-maven")
public static LookupMerger<WebServiceDataProvider> getLookupMerger(){
return LookupMergerSupport.createWebServiceDataProviderMerger();
}
void registerPCL() {
unregisterPCL();
mp = prj.getLookup().lookup(NbMavenProject.class);
mp.addPropertyChangeListener(this);
}
void registerAnnotationListener(final MetadataModel<WebservicesMetadata> wsModel) {
try {
wsModel.runReadActionWhenReady(new MetadataModelAction<WebservicesMetadata, Void>() {
@Override
public Void run(final WebservicesMetadata metadata) {
Webservices webServices = metadata.getRoot();
if (pcl != null) {
webServices.removePropertyChangeListener(pcl);
}
pcl = new WebservicesChangeListener(jaxWsSupport, wsModel);
webServices.addPropertyChangeListener(pcl);
return null;
}
});
} catch (java.io.IOException ex) {
ex.printStackTrace();
}
}
void unregisterPCL() {
if (mp != null) {
mp.removePropertyChangeListener(this);
}
}
/*void unregisterAnnotationListener() {
if (pcl != null) {
if (wsModel != null) {
try {
wsModel.runReadActionWhenReady(new MetadataModelAction<WebservicesMetadata, Void>() {
public Void run(final WebservicesMetadata metadata) {
Webservices webServices = metadata.getRoot();
webServices.removePropertyChangeListener(pcl);
return null;
}
});
} catch (java.io.IOException ex) {
ex.printStackTrace();
}
}
}
}*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (NbMavenProject.PROP_PROJECT.equals(evt.getPropertyName())) {
pomChangesTask.schedule(1000);
}
else if (JAXWSLightSupport.PROPERTY_SERVICE_ADDED.equals(evt.getPropertyName())) {
MavenWebService mavenService = new MavenWebService((JaxWsService) evt.getNewValue(), prj);
WebService webService = WebServiceFactory.createWebService(mavenService);
if (webService.isServiceProvider()) {
providers.add(webService);
} else {
consumers.add(webService);
}
}
else if (JAXWSLightSupport.PROPERTY_SERVICE_REMOVED.equals(evt.getPropertyName())) {
JaxWsService jaxWsService = (JaxWsService) evt.getOldValue();
if (jaxWsService.isServiceProvider()) {
String implClass = jaxWsService.getImplementationClass();
for (WebService service : providers) {
if (implClass.equals(service.getIdentifier())) {
providers.remove(service);
break;
}
}
} else {
String clientId = jaxWsService.getId();
for (WebService client : consumers) {
if (clientId != null && clientId.equals(client.getIdentifier())) {
consumers.remove(client);
break;
}
}
}
}
}
private void reactOnPomChanges() {
WSUtils.updateClients(prj, jaxWsSupport);
List<JaxWsService> services = jaxWsSupport.getServices();
if (services.size() > 0) {
J2eeModuleProvider provider = prj.getLookup().lookup(
J2eeModuleProvider.class);
String serverInstanceID = provider== null ? null :
provider.getServerInstanceID();
boolean instanceChanged = false;
if ( serverInstanceID == null ){
if ( serverInstance != null ){
instanceChanged = true;
}
}
else if (!serverInstanceID.equals( serverInstance)){
instanceChanged = true;
}
if ( instanceChanged ){
serverInstance = serverInstanceID;
MavenModelUtils.reactOnServerChanges(prj);
}
if (WSUtils.isWeb(prj)) {
for (JaxWsService s : services) {
if (s.isServiceProvider()) {
// add|remove sun-jaxws.xml and WS entries to web.xml file
// depending on selected target server
WSUtils.checkNonJSR109Entries(prj);
break;
}
}
}
}
}
private class WebservicesChangeListener implements PropertyChangeListener {
private JAXWSLightSupport jaxWsSupport;
private MetadataModel<WebservicesMetadata> wsModel;
private RequestProcessor.Task updateJaxWsTask = MAVEN_WS_RP.create(new Runnable() {
@Override
public void run() {
updateJaxWs();
}
});
WebservicesChangeListener(JAXWSLightSupport jaxWsSupport, MetadataModel<WebservicesMetadata> wsModel) {
this.jaxWsSupport = jaxWsSupport;
this.wsModel = wsModel;
updateJaxWsTask.schedule(1000);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
//requestModelUpdate();
updateJaxWsTask.schedule(1000);
}
private void updateJaxWs() {
try {
final Map<String, ServiceInfo> newServices = wsModel.runReadAction(
new MetadataModelAction<WebservicesMetadata, Map<String, ServiceInfo>>() {
@Override
public Map<String, ServiceInfo> run(WebservicesMetadata metadata) {
Map<String, ServiceInfo> result = new HashMap<String, ServiceInfo>();
Webservices webServices = metadata.getRoot();
for (WebserviceDescription wsDesc : webServices.getWebserviceDescription()) {
PortComponent[] ports = wsDesc.getPortComponent();
for (PortComponent port : ports) {
// key = imlpementation class package name
// value = service name
String implClass = port.getDisplayName();
if (WSUtils.isInSourceGroup(prj, implClass)) {
QName portName = port.getWsdlPort();
result.put(implClass,
new ServiceInfo(
wsDesc.getWebserviceDescriptionName(),
(portName == null ? null : portName.getLocalPart()),
implClass,
wsDesc.getWsdlFile()));
}
}
}
return result;
}
});
Runnable runnable = new Runnable() {
@Override
public void run() {
doUpdateJaxWs(newServices);
}
};
jaxWsSupport.runAtomic(runnable);
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
}
}
private void doUpdateJaxWs( Map<String, ServiceInfo> newServices ) {
List<JaxWsService> oldJaxWsServices = jaxWsSupport.getServices();
Map<String, JaxWsService> oldServices = new HashMap<String, JaxWsService>();
for (JaxWsService s : oldJaxWsServices) {
// implementationClass -> Service
if (s.isServiceProvider()) {
oldServices.put(s.getImplementationClass(), s);
}
}
// compare new services with existing
// looking for common services (implementationClass)
Set<String> commonServices = new HashSet<String>();
Set<String> keys1 = oldServices.keySet();
Set<String> keys2 = newServices.keySet();
for (String key : keys1) {
if (keys2.contains(key)) {
commonServices.add(key);
}
}
for (String key : commonServices) {
oldServices.remove(key);
newServices.remove(key);
}
// remove old services
boolean needToSave = false;
for (String key : oldServices.keySet()) {
jaxWsSupport.removeService(oldServices.get(key));
}
// add new services
for (String key : newServices.keySet()) {
ServiceInfo serviceInfo = newServices.get(key);
String wsdlLocation = serviceInfo.getWsdlLocation();
JaxWsService service = new JaxWsService(serviceInfo.getServiceName(), key);
if (wsdlLocation != null && wsdlLocation.length() > 0) {
service.setWsdlLocation(wsdlLocation);
if (wsdlLocation.startsWith("WEB-INF/wsdl/")) {
service.setLocalWsdl(wsdlLocation.substring(13));
} else if (wsdlLocation.startsWith("META-INF/wsdl/")) {
service.setLocalWsdl(wsdlLocation.substring(14));
} else {
service.setLocalWsdl(wsdlLocation);
}
FileObject wsdlFo = WSUtils.getLocalWsdl(jaxWsSupport, service.getLocalWsdl());
if (wsdlFo != null) {
service.setId(WSUtils.getUniqueId(wsdlFo.getName(), oldJaxWsServices));
}
service.setWsdlUrl(WSUtils.getOriginalWsdlUrl(prj, service.getId(), true));
}
service.setPortName(serviceInfo.getPortName());
jaxWsSupport.addService(service);
}
}
}
private static class ServiceInfo {
private String serviceName;
private String portName;
private String implClass;
private String wsdlLocation;
public ServiceInfo(String serviceName, String portName, String implClass, String wsdlLocation) {
this.serviceName = serviceName;
this.portName = portName;
this.implClass = implClass;
this.wsdlLocation = wsdlLocation;
}
public String getImplClass() {
return implClass;
}
public void setImplClass(String implClass) {
this.implClass = implClass;
}
public String getPortName() {
return portName;
}
public void setPortName(String portName) {
this.portName = portName;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getWsdlLocation() {
return wsdlLocation;
}
public void setWsdlLocation(String wsdlLocation) {
this.wsdlLocation = wsdlLocation;
}
}
}