blob: 6780e48e2ff39b2f72cba92c9f89cb8bbaf73c44 [file] [log] [blame]
/*******************************************************************************
* 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.IWSDL11ValidationInfo;
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.IWSDL11ValidationInfo)
*/
public void validate(Object element, List parents, IWSDL11ValidationInfo 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, IWSDL11ValidationInfo 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, IWSDL11ValidationInfo 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, IWSDL11ValidationInfo 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, IWSDL11ValidationInfo 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;
}
}