| /******************************************************************************* |
| * Copyright (c) 2001, 2004 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.wst.wsdl.validation.internal.wsdl11.http; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ResourceBundle; |
| |
| import javax.wsdl.Binding; |
| import javax.wsdl.BindingInput; |
| import javax.wsdl.BindingOperation; |
| import javax.wsdl.Port; |
| import javax.wsdl.extensions.ExtensibilityElement; |
| import javax.wsdl.extensions.http.HTTPOperation; |
| |
| import org.eclipse.wst.wsdl.validation.internal.util.MessageGenerator; |
| import org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator; |
| import org.eclipse.wst.wsdl.validation.internal.wsdl11.WSDL11ValidationInfo; |
| |
| import com.ibm.wsdl.BindingImpl; |
| import com.ibm.wsdl.BindingInputImpl; |
| import com.ibm.wsdl.BindingOperationImpl; |
| import com.ibm.wsdl.PortImpl; |
| import com.ibm.wsdl.extensions.http.HTTPAddressImpl; |
| import com.ibm.wsdl.extensions.http.HTTPBindingImpl; |
| import com.ibm.wsdl.extensions.http.HTTPOperationImpl; |
| import com.ibm.wsdl.extensions.http.HTTPUrlEncodedImpl; |
| import com.ibm.wsdl.extensions.http.HTTPUrlReplacementImpl; |
| |
| /** |
| * The HTTP validator is an extension WSDL validator that validates all elements in the HTTP |
| * namespace. |
| */ |
| public class HTTPValidator implements IWSDL11Validator |
| { |
| private final String _ERROR_INVALID_PORT_ELEMENT = "_ERROR_INVALID_PORT_ELEMENT"; |
| private final String _ERROR_INVALID_BINDING_ELEMENT = "_ERROR_INVALID_BINDING_ELEMENT"; |
| private final String _ERROR_INVALID_BINDING_OPERATION_ELEMENT = "_ERROR_INVALID_BINDING_OPERATION_ELEMENT"; |
| private final String _ERROR_INVALID_BINDING_INPUT_ELEMENT = "_ERROR_INVALID_BINDING_INPUT_ELEMENT"; |
| private final String _ERROR_INVALID_HTTP_ELEMENT_FOR_LOCATION = "_ERROR_INVALID_HTTP_ELEMENT_FOR_LOCATION"; |
| private final String _ERROR_NO_LOCATION_FOR_ADDRESS = "_ERROR_NO_LOCATION_FOR_ADDRESS"; |
| private final String _ERROR_NO_HTTPBINDING_FOR_ADDRESS = "_ERROR_NO_HTTPBINDING_FOR_ADDRESS"; |
| private final String _ERROR_INVALID_BINDING_VERB = "_ERROR_INVALID_BINDING_VERB"; |
| private final String _ERROR_INVALID_LOCATION_URI = "_ERROR_INVALID_LOCATION_URI"; |
| private final String _ERROR_NO_HTTPBINDING_FOR_OPERATION = "_ERROR_NO_HTTPBINDING_FOR_OPERATION"; |
| private final String _ERROR_NOT_ONLY_ELEMENT_DEFINED = "_ERROR_NOT_ONLY_ELEMENT_DEFINED"; |
| private final String _ERROR_NO_HTTPOPERATION_FOR_URL = "_ERROR_NO_HTTPOPERATION_FOR_URL"; |
| |
| private final String GET = "GET"; |
| private final String POST = "POST"; |
| |
| private final String QUOTE = "'"; |
| private final String EMPTY_STRING = ""; |
| |
| private MessageGenerator messagegenerator; |
| |
| /** |
| * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.IWSDL11Validator#validate(java.lang.Object, java.util.List, org.eclipse.wsdl.validate.wsdl11.WSDL11ValidationInfo) |
| */ |
| public void validate(Object element, List parents, WSDL11ValidationInfo valInfo) |
| { |
| // Port HTTP definition |
| // make sure every port has only one address element defined |
| // if it is an address element, validate it |
| if (parents.get(0).getClass() == PortImpl.class) |
| { |
| if (element.getClass() == HTTPAddressImpl.class) |
| { |
| validateAddress(element, parents, valInfo); |
| } |
| else |
| { |
| ExtensibilityElement e = (ExtensibilityElement)element; |
| valInfo.addError( |
| messagegenerator.getString(_ERROR_INVALID_PORT_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), |
| element); |
| } |
| } |
| |
| // Binding HTTP definition |
| // A HTTP Binding must have a verb of GET or POST |
| else if (parents.get(0).getClass() == BindingImpl.class) |
| { |
| if (element.getClass() == HTTPBindingImpl.class) |
| { |
| validateBinding(element, parents, valInfo); |
| } |
| else |
| { |
| ExtensibilityElement e = (ExtensibilityElement)element; |
| valInfo.addError( |
| messagegenerator.getString(_ERROR_INVALID_BINDING_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), |
| element); |
| } |
| } |
| // Binding Operation HTTP definition |
| // A HTTP Operation has a location uri defined |
| else if (parents.get(0).getClass() == BindingOperationImpl.class) |
| { |
| if (element.getClass() == HTTPOperationImpl.class) |
| { |
| validateOperation(element, parents, valInfo); |
| } |
| else |
| { |
| ExtensibilityElement e = (ExtensibilityElement)element; |
| valInfo.addError( |
| messagegenerator.getString( |
| _ERROR_INVALID_BINDING_OPERATION_ELEMENT, |
| QUOTE + e.getElementType().getLocalPart() + QUOTE), |
| element); |
| } |
| |
| } |
| else if (parents.get(0).getClass() == BindingInputImpl.class) |
| { |
| // validate the HTTP urlEncoded and urlReplacement |
| if (element.getClass() == HTTPUrlEncodedImpl.class || element.getClass() == HTTPUrlReplacementImpl.class) |
| { |
| validateHttpUrl(element, parents, valInfo); |
| } |
| else |
| { |
| ExtensibilityElement e = (ExtensibilityElement)element; |
| valInfo.addError( |
| messagegenerator.getString(_ERROR_INVALID_BINDING_INPUT_ELEMENT, QUOTE + e.getElementType().getLocalPart() + QUOTE), |
| element); |
| } |
| } |
| |
| // in this case there has been a HTTP element defined that is not defined for this point in the HTTP namespace |
| else |
| { |
| ExtensibilityElement e = (ExtensibilityElement)element; |
| valInfo.addError( |
| messagegenerator.getString( |
| _ERROR_INVALID_HTTP_ELEMENT_FOR_LOCATION, |
| QUOTE + e.getElementType().getLocalPart() + QUOTE), |
| element); |
| } |
| |
| } |
| |
| /** |
| * @see org.eclipse.wst.wsdl.validation.internal.wsdl11.validator.IWSDL11Validator#setResourceBundle(java.util.ResourceBundle) |
| */ |
| public void setResourceBundle(ResourceBundle rb) |
| { |
| if (messagegenerator == null) |
| { |
| messagegenerator = new MessageGenerator(rb); |
| } |
| } |
| |
| /** |
| * Ensure that the HTTP address has a value specified for it's uri and that there is a HTTP Binding defined |
| * for the Binding specified in the port. |
| * |
| * @param element The HTTP address element. |
| * @param parents The list of parents of the HTTP address element. |
| * @param validatorcontroller The validator controller in charge of validation. |
| */ |
| protected void validateAddress(Object element, List parents, WSDL11ValidationInfo valInfo) |
| { |
| HTTPAddressImpl ha = (HTTPAddressImpl)element; |
| |
| String uri = ha.getLocationURI(); |
| if (uri == null || uri.equalsIgnoreCase(EMPTY_STRING)) |
| { |
| valInfo.addError(messagegenerator.getString(_ERROR_NO_LOCATION_FOR_ADDRESS), ha); |
| } |
| |
| Port port = (Port)parents.get(0); |
| |
| Binding binding = port.getBinding(); |
| |
| if (!hasHttpBinding(binding)) |
| { |
| valInfo.addError( |
| messagegenerator.getString( |
| _ERROR_NO_HTTPBINDING_FOR_ADDRESS, |
| QUOTE + binding.getQName().getLocalPart() + QUOTE, |
| QUOTE + port.getName() + QUOTE), |
| ha); |
| } |
| } |
| |
| /** |
| * Ensure the HTTP Binding defined is valid. A HTTP Binding must have a verb of GET or POST. |
| * |
| * @param element The HTTP binding element. |
| * @param parents The list of parents of the HTTP binding element. |
| * @param validatorcontroller The validator controller in charge of validation. |
| */ |
| protected void validateBinding(Object element, List parents, WSDL11ValidationInfo valInfo) |
| { |
| HTTPBindingImpl hb = (HTTPBindingImpl)element; |
| |
| String verb = hb.getVerb(); |
| |
| if (verb != null && !verb.equals(GET) && !verb.equals(POST)) |
| { |
| valInfo.addError(messagegenerator.getString(_ERROR_INVALID_BINDING_VERB, QUOTE + verb + QUOTE), element); |
| } |
| } |
| |
| /** |
| * An operation must have a location defined. A HTTP Binding must be specified to use an operation. |
| * |
| * @param element The HTTP operation element. |
| * @param parents The list of parents of the HTTP operation element. |
| * @param validatorcontroller The validator controller in charge of validation. |
| */ |
| protected void validateOperation(Object element, List parents, WSDL11ValidationInfo valInfo) |
| { |
| HTTPOperation ho = (HTTPOperation)element; |
| |
| String locationURI = ho.getLocationURI(); |
| |
| if (locationURI != null && locationURI.equalsIgnoreCase(EMPTY_STRING)) |
| { |
| valInfo.addError(messagegenerator.getString(_ERROR_INVALID_LOCATION_URI), element); |
| } |
| |
| Binding binding = (Binding)parents.get(1); |
| if (!hasHttpBinding(binding)) |
| { |
| valInfo.addError( |
| messagegenerator.getString(_ERROR_NO_HTTPBINDING_FOR_OPERATION, QUOTE + binding.getQName().getLocalPart() + QUOTE), |
| ho); |
| } |
| } |
| |
| /** |
| * Validate the HTTP urlReplacement or urlEncoded. Ensure the HTTP operation has been defined. |
| * Ensure that either element is the only element specified. |
| * |
| * @param element The HTTP binding operation element. |
| * @param parents The list of parents of the HTTP binding operation element. |
| * @param validatorcontroller The validator controller in charge of validation. |
| */ |
| protected void validateHttpUrl(Object element, List parents, WSDL11ValidationInfo valInfo) |
| { |
| BindingOperation operation = (BindingOperation)parents.get(1); |
| |
| String elementName; |
| if (element.getClass() == HTTPUrlEncodedImpl.class) |
| { |
| elementName = "urlEncoded"; |
| } |
| else if (element.getClass() == HTTPUrlReplacementImpl.class) |
| { |
| elementName = "urlReplacement"; |
| } |
| else |
| { |
| elementName = EMPTY_STRING; |
| } |
| |
| BindingInput input = (BindingInput)parents.get(0); |
| if (input.getExtensibilityElements().size() != 1) |
| { |
| valInfo.addError(messagegenerator.getString(_ERROR_NOT_ONLY_ELEMENT_DEFINED, elementName), element); |
| } |
| |
| if (!hasHttpOperation(operation)) |
| { |
| valInfo.addError( |
| messagegenerator.getString(_ERROR_NO_HTTPOPERATION_FOR_URL, QUOTE + operation.getName() + QUOTE, elementName), |
| element); |
| } |
| } |
| |
| /** |
| * Given a BindingOperation tells whether it has a HTTP operation defined for it. |
| * |
| * @param binding The HTTP binding operation element. |
| * @return True if there is an HTTP operation defined, false otherwise. |
| */ |
| protected boolean hasHttpOperation(BindingOperation operation) |
| { |
| if (operation != null) |
| { |
| List extelems = operation.getExtensibilityElements(); |
| if (extelems != null) |
| { |
| Iterator iextelems = extelems.iterator(); |
| while (iextelems.hasNext()) |
| { |
| if (iextelems.next().getClass() == HTTPOperationImpl.class) |
| { |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Given a binding returns true if it has a HTTP binding defined. |
| * |
| * @param binding The binding to check. |
| * @return True if there is an HTTP binding defined. |
| */ |
| protected boolean hasHttpBinding(Binding binding) |
| { |
| if (binding != null) |
| { |
| List extelems = binding.getExtensibilityElements(); |
| if (extelems != null) |
| { |
| Iterator iextelems = extelems.iterator(); |
| while (iextelems.hasNext()) |
| { |
| if (iextelems.next().getClass() == HTTPBindingImpl.class) |
| { |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| } |