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: */package org.apache.geronimo.webservices;
017:
018: import java.util.ArrayList;
019: import java.util.Map;
020: import javax.wsdl.*;
021: import javax.wsdl.extensions.soap.SOAPBinding;
022: import javax.wsdl.extensions.soap.SOAPBody;
023: import javax.xml.namespace.QName;
024:
025: import org.apache.geronimo.validator.ValidationContext;
026: import org.apache.geronimo.validator.ValidationFailure;
027:
028: public class LightWeightMappingValidator extends WSDLVisitor {
029:
030: private ArrayList operationNames;
031: private ValidationContext context;
032:
033: private static final QName XSD_STRING = new QName(
034: "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()
043: .toString());
044: walkTree();
045: }
046: return context;
047: }
048:
049: public boolean isValid() {
050: ValidationContext context = validate();
051: return !context.hasFailures() && !context.hasErrors();
052: }
053:
054: protected void begin() {
055: operationNames = new ArrayList();
056: }
057:
058: protected void visit(Definition definition) {
059: if (definition.getServices().values().size() != 1) {
060: context
061: .addFailure(new ValidationFailure(
062: "A lightweight RPC/Encoded service must contain only one Service"));
063: }
064: }
065:
066: protected void visit(Output output) {
067: Map outputParts = output.getMessage().getParts();
068: if (outputParts.size() != 0 && outputParts.size() != 1) {
069: context.addFailure(new ValidationFailure(
070: "The output message must contain zero or one parts: "
071: + output.getName()));
072: }
073:
074: }
075:
076: protected void visit(Operation operation) {
077: if (!operationNames.add(operation.getName())) {
078: context.addFailure(new ValidationFailure(
079: "No two operations can have the same name: "
080: + operation.getName()));
081: }
082: }
083:
084: protected void visit(Fault fault) {
085: Part message = fault.getMessage().getPart("message");
086: if (message == null) {
087: context.addFailure(new ValidationFailure(
088: "The fault message must contain one part named 'message' : "
089: + fault.getName()));
090: } else if (!XSD_STRING.equals(message.getTypeName())) {
091: context.addFailure(new ValidationFailure(
092: "The fault message must contain one part of type 'xsd:string' : "
093: + fault.getName()));
094: }
095: }
096:
097: protected void visit(BindingInput bindingInput) {
098: SOAPBody body = getSOAPBody(bindingInput
099: .getExtensibilityElements());
100: String encoding = body.getUse();
101: if (encoding == null || !encoding.equals("encoded")) {
102: context.addFailure(new ValidationFailure(
103: "The use attribute of the binding input operation must be 'encoded': "
104: + bindingInput.getName()));
105: }
106: }
107:
108: protected void visit(BindingOutput bindingOutput) {
109: SOAPBody body = getSOAPBody(bindingOutput
110: .getExtensibilityElements());
111: String encoding = body.getUse();
112: if (encoding == null || !encoding.equals("encoded")) {
113: context.addFailure(new ValidationFailure(
114: "The use attribute of the binding output operation must be 'encoded': "
115: + bindingOutput.getName()));
116: }
117: }
118:
119: protected void visit(BindingFault bindingFault) {
120: SOAPBody body = getSOAPBody(bindingFault
121: .getExtensibilityElements());
122: String encoding = body.getUse();
123: if (encoding == null || !encoding.equals("encoded")) {
124: context.addFailure(new ValidationFailure(
125: "The use attribute of the binding fault operation must be 'encoded': "
126: + bindingFault.getName()));
127: }
128: }
129:
130: protected void visit(Binding binding) {
131: SOAPBinding soapBinding = getSOAPBinding(binding);
132: if (soapBinding == null || soapBinding.getStyle() == null
133: || !soapBinding.getStyle().equals("rpc")) {
134: context.addFailure(new ValidationFailure(
135: "The messaging style of the binding must be rpc: "
136: + binding.getQName()));
137: }
138: }
139:
140: protected void visit(Service service) {
141: if (service.getPorts().values().size() != 1) {
142: context
143: .addFailure(new ValidationFailure(
144: "A lightweight RPC/Encoded service must contain only one Port"));
145: }
146: }
147: }
|