blob: 2a6ee879efb938e50ac4357f3316d7ff473ada89 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Shane Clarke.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Shane Clarke - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.ws.internal.jaxws.core.annotations.validation;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.ENDPOINT_INTERFACE;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.EXCLUDE;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.OPERATION_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.PORT_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.PORT_SUFFIX;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.SERVICE_NAME;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.SERVICE_SUFFIX;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.STYLE;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.TARGET_NAMESPACE;
import static org.eclipse.jst.ws.internal.jaxws.core.utils.JAXWSUtils.WSDL_LOCATION;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.xml.namespace.QName;
import org.eclipse.jst.ws.annotations.core.processor.AbstractAnnotationProcessor;
import org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.jaxws.core.JAXWSCoreMessages;
import org.eclipse.jst.ws.jaxws.core.utils.JDTUtils;
import org.eclipse.jst.ws.jaxws.core.utils.WSDLUtils;
import com.sun.mirror.declaration.AnnotationMirror;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.AnnotationValue;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.Declaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
public class WebServiceWSDLLocationRule extends AbstractAnnotationProcessor {
@Override
@SuppressWarnings("unchecked")
public void process() {
AnnotationTypeDeclaration annotationDeclaration = (AnnotationTypeDeclaration) environment
.getTypeDeclaration(WebService.class.getName());
Collection<Declaration> annotatedTypes = environment
.getDeclarationsAnnotatedWith(annotationDeclaration);
for (Declaration declaration : annotatedTypes) {
if (declaration instanceof ClassDeclaration) {
ClassDeclaration classDeclaration = (ClassDeclaration) declaration;
AnnotationMirror webService = AnnotationUtils.getAnnotation(declaration, WebService.class);
AnnotationValue wsdlLocationValue = AnnotationUtils.getAnnotationValue(webService, WSDL_LOCATION);
if (wsdlLocationValue == null) {
break;
}
String wsdlLocation = wsdlLocationValue.getValue().toString();
if (wsdlLocation != null && wsdlLocation.trim().length() > 0) {
try {
URL wsdlURL = new URL(wsdlLocation);
Definition definition = WSDLUtils.readWSDL(wsdlURL);
if (definition != null) {
QName serviceQName = getServiceQName(webService, (ClassDeclaration) declaration);
Service service = getService(definition, serviceQName);
if (service != null) {
String portName = getPortName(webService, classDeclaration);
Port port = getPort(service, portName);
if (port != null) {
Binding binding = port.getBinding();
validateBinding(binding, classDeclaration, webService, wsdlLocation);
Map<String, MethodDeclaration> methodMap = getWebMethods(classDeclaration,
webService);
List<Operation> operations = binding.getPortType().getOperations();
for (Operation operation : operations) {
MethodDeclaration methodDeclaration = methodMap.get(operation.getName());
if (methodDeclaration == null) {
printError(webService.getPosition(), JAXWSCoreMessages.bind(
JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_NO_OPERTATION_NAME,
operation.getName()));
} else {
AnnotationMirror oneway = AnnotationUtils.getAnnotation(
methodDeclaration, Oneway.class);
if (oneway != null && operation.getOutput() != null) {
printError(methodDeclaration.getPosition(), JAXWSCoreMessages.bind(
JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_WSDL_OPERATION_OUTPUT_METHOD_ONEWAY,
new Object[] {methodDeclaration.getSimpleName(), operation.getName()}));
}
}
}
} else {
printError(webService.getPosition(), JAXWSCoreMessages.bind(
JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_NO_PORT_NAME,
new Object[] {portName, wsdlLocation}));
}
} else {
printError(webService.getPosition(), JAXWSCoreMessages.bind(
JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_NO_SERVICE_NAME,
new Object[] {serviceQName.getLocalPart(), wsdlLocation}));
}
}
} catch (MalformedURLException murle) {
printError(wsdlLocationValue.getPosition(), murle.getLocalizedMessage());
} catch (IOException ioe) {
printNotice(wsdlLocationValue.getPosition(), JAXWSCoreMessages.bind(
JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_UNABLE_TO_LOCATE, wsdlLocation));
}
}
}
}
}
@SuppressWarnings("unchecked")
private void validateBinding(Binding binding, ClassDeclaration classDeclaration,
AnnotationMirror webService, String wsdlLocation) {
String style = javax.jws.soap.SOAPBinding.Style.DOCUMENT.name();
AnnotationMirror soapBindingAnnotation = getSOAPBinding(classDeclaration, webService);
if (soapBindingAnnotation != null) {
String styleValue = AnnotationUtils.getStringValue(soapBindingAnnotation, STYLE);
if (styleValue != null) {
style = styleValue;
}
}
List extensibilityElements = binding.getExtensibilityElements();
for (Object elementExtensible : extensibilityElements) {
if (elementExtensible instanceof SOAPBinding) {
SOAPBinding soapBinding = (SOAPBinding) elementExtensible;
if (style.compareToIgnoreCase(soapBinding.getStyle()) != 0) {
printError(soapBindingAnnotation == null ? webService.getPosition()
: soapBindingAnnotation.getPosition(),
JAXWSCoreMessages.bind(JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_SOAP_BINDING_STYLE,
new Object[] {wsdlLocation, soapBinding.getStyle(), style}));
}
}
if (elementExtensible instanceof SOAP12Binding) {
SOAP12Binding soap12Binding = (SOAP12Binding) elementExtensible;
if (style.compareToIgnoreCase(soap12Binding.getStyle()) != 0) {
printError(soapBindingAnnotation == null ? webService.getPosition()
: soapBindingAnnotation.getPosition(),
JAXWSCoreMessages.bind(JAXWSCoreMessages.WEBSERVICE_WSDL_LOCATION_SOAP_BINDING_STYLE,
new Object[] {wsdlLocation, soap12Binding.getStyle(), style}));
}
}
}
}
private AnnotationMirror getSOAPBinding(TypeDeclaration typeDeclaration, AnnotationMirror webService) {
String endpointInterface = AnnotationUtils.getStringValue(webService, ENDPOINT_INTERFACE);
if (endpointInterface != null) {
TypeDeclaration seiDeclaration = environment.getTypeDeclaration(endpointInterface);
if (seiDeclaration != null) {
typeDeclaration = seiDeclaration;
}
}
return AnnotationUtils.getAnnotation(typeDeclaration, javax.jws.soap.SOAPBinding.class);
}
private Map<String, MethodDeclaration> getWebMethods(TypeDeclaration typeDeclaration, AnnotationMirror webService) {
Map<String, MethodDeclaration> methodMap = new HashMap<String, MethodDeclaration>();
String endpointInterface = AnnotationUtils.getStringValue(webService, ENDPOINT_INTERFACE);
if (endpointInterface != null) {
TypeDeclaration seiDeclaration = environment.getTypeDeclaration(endpointInterface);
if (seiDeclaration != null) {
typeDeclaration = seiDeclaration;
}
}
Collection<? extends MethodDeclaration> methods = typeDeclaration.getMethods();
for (MethodDeclaration methodDeclaration : methods) {
AnnotationMirror webMethod = AnnotationUtils.getAnnotation(methodDeclaration, WebMethod.class);
if (webMethod != null && !isExluded(webMethod)) {
methodMap.put(getOperationName(webMethod, methodDeclaration), methodDeclaration);
} else {
methodMap.put(methodDeclaration.getSimpleName(), methodDeclaration);
}
}
return methodMap;
}
private boolean isExluded(AnnotationMirror webMethod) {
Boolean exclude = AnnotationUtils.getBooleanValue(webMethod, EXCLUDE);
if (exclude != null) {
return exclude.booleanValue();
}
return false;
}
private String getOperationName(AnnotationMirror webMethod, MethodDeclaration methodDeclaration) {
String operationName = AnnotationUtils.getStringValue(webMethod, OPERATION_NAME);
if (operationName != null) {
return operationName;
}
return methodDeclaration.getSimpleName();
}
@SuppressWarnings("unchecked")
private Service getService(Definition definition, QName serviceQName) {
Map servicesMap = definition.getServices();
Set<Map.Entry> servicesSet = servicesMap.entrySet();
for (Map.Entry<QName, Service> serviceEntry : servicesSet) {
QName serviceEntryKey = serviceEntry.getKey();
if (serviceEntryKey.equals(serviceQName)) {
return serviceEntry.getValue();
}
}
return null;
}
@SuppressWarnings("unchecked")
private Port getPort(Service service, String portName) {
Map portsMap = service.getPorts();
Set<Map.Entry> portsSet = portsMap.entrySet();
for (Map.Entry<String, Port> portEntry : portsSet) {
String portEntryKey = portEntry.getKey();
if (portEntryKey.equals(portName)) {
return portEntry.getValue();
}
}
return null;
}
private QName getServiceQName(AnnotationMirror webService, ClassDeclaration classDeclaration) {
String serviceName = AnnotationUtils.getStringValue(webService, SERVICE_NAME);
if (serviceName == null) {
serviceName = classDeclaration.getSimpleName() + SERVICE_SUFFIX;
}
return new QName(getTargetNamespace(webService, classDeclaration), serviceName);
}
private String getPortName(AnnotationMirror webService, ClassDeclaration classDeclaration) {
String portName = AnnotationUtils.getStringValue(webService, PORT_NAME);
if (portName == null) {
portName = classDeclaration.getSimpleName() + PORT_SUFFIX;
}
return portName;
}
private String getTargetNamespace(AnnotationMirror webService, ClassDeclaration classDeclaration) {
String targetNamespace = AnnotationUtils.getStringValue(webService, TARGET_NAMESPACE);
if (targetNamespace == null) {
targetNamespace = JDTUtils.getTargetNamespaceFromPackageName(
classDeclaration.getPackage().getQualifiedName());
}
return targetNamespace;
}
}