001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.webservices;
018
019 import java.util.ArrayList;
020 import java.util.Map;
021 import javax.wsdl.*;
022 import javax.wsdl.extensions.soap.SOAPBinding;
023 import javax.wsdl.extensions.soap.SOAPBody;
024 import javax.xml.namespace.QName;
025
026 import org.apache.geronimo.validator.ValidationContext;
027 import org.apache.geronimo.validator.ValidationFailure;
028
029 public class LightWeightMappingValidator extends WSDLVisitor {
030
031 private ArrayList operationNames;
032 private ValidationContext context;
033
034 private static final QName XSD_STRING = new QName("http://www.w3.org/2001/XMLSchema", "string");
035
036 public LightWeightMappingValidator(Definition definition) {
037 super(definition);
038 }
039
040 public ValidationContext validate() {
041 if (context == null) {
042 context = new ValidationContext(definition.getQName().toString());
043 walkTree();
044 }
045 return context;
046 }
047
048 public boolean isValid() {
049 ValidationContext context = validate();
050 return !context.hasFailures() && !context.hasErrors();
051 }
052
053 protected void begin() {
054 operationNames = new ArrayList();
055 }
056
057 protected void visit(Definition definition) {
058 if (definition.getServices().values().size() != 1) {
059 context.addFailure(new ValidationFailure("A lightweight RPC/Encoded service must contain only one Service"));
060 }
061 }
062
063 protected void visit(Output output) {
064 Map outputParts = output.getMessage().getParts();
065 if (outputParts.size() != 0 && outputParts.size() != 1) {
066 context.addFailure(new ValidationFailure("The output message must contain zero or one parts: " + output.getName()));
067 }
068
069 }
070
071 protected void visit(Operation operation) {
072 if (!operationNames.add(operation.getName())) {
073 context.addFailure(new ValidationFailure("No two operations can have the same name: " + operation.getName()));
074 }
075 }
076
077 protected void visit(Fault fault) {
078 Part message = fault.getMessage().getPart("message");
079 if (message == null) {
080 context.addFailure(new ValidationFailure("The fault message must contain one part named 'message' : " + fault.getName()));
081 } else if (!XSD_STRING.equals(message.getTypeName())) {
082 context.addFailure(new ValidationFailure("The fault message must contain one part of type 'xsd:string' : " + fault.getName()));
083 }
084 }
085
086
087 protected void visit(BindingInput bindingInput) {
088 SOAPBody body = getSOAPBody(bindingInput.getExtensibilityElements());
089 String encoding = body.getUse();
090 if (encoding == null || !encoding.equals("encoded")) {
091 context.addFailure(new ValidationFailure("The use attribute of the binding input operation must be 'encoded': " + bindingInput.getName()));
092 }
093 }
094
095 protected void visit(BindingOutput bindingOutput) {
096 SOAPBody body = getSOAPBody(bindingOutput.getExtensibilityElements());
097 String encoding = body.getUse();
098 if (encoding == null || !encoding.equals("encoded")) {
099 context.addFailure(new ValidationFailure("The use attribute of the binding output operation must be 'encoded': " + bindingOutput.getName()));
100 }
101 }
102
103 protected void visit(BindingFault bindingFault) {
104 SOAPBody body = getSOAPBody(bindingFault.getExtensibilityElements());
105 String encoding = body.getUse();
106 if (encoding == null || !encoding.equals("encoded")) {
107 context.addFailure(new ValidationFailure("The use attribute of the binding fault operation must be 'encoded': " + bindingFault.getName()));
108 }
109 }
110
111 protected void visit(Binding binding) {
112 SOAPBinding soapBinding = getSOAPBinding(binding);
113 if (soapBinding == null || soapBinding.getStyle() == null || !soapBinding.getStyle().equals("rpc")) {
114 context.addFailure(new ValidationFailure("The messaging style of the binding must be rpc: " + binding.getQName()));
115 }
116 }
117
118 protected void visit(Service service) {
119 if (service.getPorts().values().size() != 1) {
120 context.addFailure(new ValidationFailure("A lightweight RPC/Encoded service must contain only one Port"));
121 }
122 }
123 }