| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.axis2.builder; |
| |
| import org.apache.axiom.om.OMAbstractFactory; |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axiom.soap.SOAP11Constants; |
| import org.apache.axiom.soap.SOAP12Constants; |
| import org.apache.axiom.soap.SOAPFactory; |
| import org.apache.axis2.AxisFault; |
| import org.apache.axis2.Constants; |
| import org.apache.axis2.java.security.AccessController; |
| import org.apache.axis2.addressing.EndpointReference; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.axis2.description.AxisBinding; |
| import org.apache.axis2.description.AxisBindingOperation; |
| import org.apache.axis2.description.AxisEndpoint; |
| import org.apache.axis2.description.WSDL20DefaultValueHolder; |
| import org.apache.axis2.description.WSDL2Constants; |
| import org.apache.axis2.i18n.Messages; |
| import org.apache.axis2.transport.http.util.URIEncoderDecoder; |
| import org.apache.axis2.util.MultipleEntryHashMap; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.UnsupportedEncodingException; |
| import java.security.PrivilegedAction; |
| import java.security.PrivilegedExceptionAction; |
| import java.security.PrivilegedActionException; |
| |
| |
| public class XFormURLEncodedBuilder implements Builder { |
| |
| private static final Log log = LogFactory.getLog(XFormURLEncodedBuilder.class); |
| |
| /** |
| * @return Returns the document element. |
| */ |
| public OMElement processDocument(InputStream inputStream, String contentType, |
| MessageContext messageContext) |
| throws AxisFault { |
| |
| MultipleEntryHashMap parameterMap = new MultipleEntryHashMap(); |
| SOAPFactory soapFactory; |
| AxisBindingOperation axisBindingOperation = |
| (AxisBindingOperation) messageContext.getProperty( |
| Constants.AXIS_BINDING_OPERATION); |
| String queryParameterSeparator = null; |
| String templatedPath = null; |
| if (axisBindingOperation != null) { |
| queryParameterSeparator = (String) axisBindingOperation |
| .getProperty(WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR); |
| templatedPath = |
| (String) axisBindingOperation.getProperty(WSDL2Constants.ATTR_WHTTP_LOCATION); |
| } |
| if (queryParameterSeparator == null) { |
| queryParameterSeparator = |
| WSDL20DefaultValueHolder.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR_DEFAULT; |
| } |
| |
| AxisEndpoint axisEndpoint = |
| (AxisEndpoint) messageContext.getProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME); |
| if (axisEndpoint != null) { |
| AxisBinding axisBinding = axisEndpoint.getBinding(); |
| String soapVersion = |
| (String) axisBinding.getProperty(WSDL2Constants.ATTR_WSOAP_VERSION); |
| soapFactory = getSOAPFactory(soapVersion); |
| } else { |
| soapFactory = getSOAPFactory(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); |
| } |
| EndpointReference endpointReference = messageContext.getTo(); |
| if (endpointReference == null) { |
| throw new AxisFault("Cannot create DocumentElement without destination EPR"); |
| } |
| |
| String requestURL = endpointReference.getAddress(); |
| try { |
| requestURL = extractParametersUsingHttpLocation(templatedPath, parameterMap, |
| requestURL, |
| queryParameterSeparator); |
| } catch (UnsupportedEncodingException e) { |
| throw AxisFault.makeFault(e); |
| } |
| |
| String query = requestURL; |
| int index; |
| if ((index = requestURL.indexOf("?")) > -1) { |
| query = requestURL.substring(index + 1); |
| } |
| |
| extractParametersFromRequest(parameterMap, query, queryParameterSeparator, |
| (String) messageContext.getProperty( |
| Constants.Configuration.CHARACTER_SET_ENCODING), |
| inputStream); |
| |
| |
| return BuilderUtil.buildsoapMessage(messageContext, parameterMap, |
| soapFactory); |
| } |
| |
| protected void extractParametersFromRequest(MultipleEntryHashMap parameterMap, |
| String query, |
| String queryParamSeparator, |
| final String charsetEncoding, |
| final InputStream inputStream) |
| throws AxisFault { |
| |
| if (query != null && !"".equals(query)) { |
| |
| String parts[] = query.split(queryParamSeparator); |
| for (int i = 0; i < parts.length; i++) { |
| int separator = parts[i].indexOf("="); |
| if (separator > 0) { |
| String value = parts[i].substring(separator + 1); |
| try { |
| value = URIEncoderDecoder.decode(value); |
| } catch (UnsupportedEncodingException e) { |
| throw AxisFault.makeFault(e); |
| } |
| |
| parameterMap |
| .put(parts[i].substring(0, separator), |
| value); |
| } |
| } |
| |
| } |
| |
| if (inputStream != null) { |
| try { |
| InputStreamReader inputStreamReader = |
| null; |
| try { |
| inputStreamReader = (InputStreamReader) AccessController.doPrivileged( |
| new PrivilegedExceptionAction() { |
| public Object run() throws UnsupportedEncodingException { |
| return new InputStreamReader(inputStream, charsetEncoding); |
| } |
| } |
| ); |
| } catch (PrivilegedActionException e) { |
| throw (UnsupportedEncodingException) e.getException(); |
| } |
| BufferedReader bufferedReader = new BufferedReader(inputStreamReader); |
| while (true) { |
| String line = bufferedReader.readLine(); |
| if (line != null) { |
| String parts[] = line.split( |
| WSDL20DefaultValueHolder.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR_DEFAULT); |
| for (int i = 0; i < parts.length; i++) { |
| int separator = parts[i].indexOf("="); |
| String value = parts[i].substring(separator + 1); |
| parameterMap.put(parts[i].substring(0, separator), |
| URIEncoderDecoder.decode(value)); |
| } |
| } else { |
| break; |
| } |
| } |
| } catch (IOException e) { |
| throw AxisFault.makeFault(e); |
| } |
| } |
| } |
| |
| /** |
| * Here is what I will try to do here. I will first try to identify the location of the first |
| * template element in the request URI. I am trying to deduce the location of that location |
| * using the httpLocation element of the binding (it is passed in to this |
| * method). |
| * If there is a contant part in the httpLocation, then I will identify it. For this, I get |
| * the index of {, from httpLocation param, and whatever to the left of it is the contant part. |
| * Then I search for this constant part inside the url. This will give us the access to the first |
| * template parameter. |
| * To find the end of this parameter, we need to get the index of the next constant, from |
| * httpLocation attribute. Likewise we keep on discovering parameters. |
| * <p/> |
| * Assumptions : |
| * 1. User will always append the value of httpLocation to the address given in the |
| * endpoint. |
| * 2. I was talking about the constants in the httpLocation. Those constants will not occur, |
| * to a reasonable extend, before the constant we are looking for. |
| * |
| * @param templatedPath |
| * @param parameterMap |
| */ |
| protected String extractParametersUsingHttpLocation(String templatedPath, |
| MultipleEntryHashMap parameterMap, |
| String requestURL, |
| String queryParameterSeparator) |
| throws AxisFault, UnsupportedEncodingException { |
| |
| |
| if (templatedPath != null && !"".equals(templatedPath) && templatedPath.indexOf("{") > -1) { |
| StringBuffer pathTemplate = new StringBuffer(templatedPath); |
| |
| // this will hold the index, from which we need to process the request URI |
| int startIndex = 0; |
| int templateStartIndex = 0; |
| int templateEndIndex = 0; |
| int indexOfNextConstant = 0; |
| |
| StringBuffer requestURIBuffer = new StringBuffer(requestURL); |
| |
| while (startIndex < requestURIBuffer.length()) { |
| // this will always hold the starting index of a template parameter |
| templateStartIndex = pathTemplate.indexOf("{", templateStartIndex); |
| |
| if (templateStartIndex > 0) { |
| // get the preceding constant part from the template |
| String constantPart = |
| pathTemplate.substring(templateEndIndex + 1, templateStartIndex); |
| constantPart = constantPart.replaceAll("\\{\\{","{"); |
| constantPart = constantPart.replaceAll("}}","}"); |
| |
| // get the index of the end of this template param |
| templateEndIndex = pathTemplate.indexOf("}", templateStartIndex); |
| if ((pathTemplate.length() -1) > templateEndIndex && pathTemplate.charAt(templateEndIndex +1) == '}') { |
| templateEndIndex = pathTemplate.indexOf("}", templateEndIndex +2); |
| } |
| |
| String parameterName = |
| pathTemplate.substring(templateStartIndex + 1, templateEndIndex); |
| // next try to find the next constant |
| templateStartIndex = pathTemplate.indexOf("{", templateEndIndex); |
| if (pathTemplate.charAt(templateStartIndex +1) == '{') { |
| templateStartIndex = pathTemplate.indexOf("{", templateStartIndex +2); |
| } |
| |
| int endIndexOfConstant = requestURIBuffer |
| .indexOf(constantPart, indexOfNextConstant) + constantPart.length(); |
| |
| if (templateStartIndex == -1) { |
| if (templateEndIndex == pathTemplate.length() - 1) { |
| |
| // We may have occations where we have templates of the form foo/{name}. |
| // In this case the next connstant will be ? and not the |
| // queryParameterSeparator |
| indexOfNextConstant = |
| requestURIBuffer |
| .indexOf("?", endIndexOfConstant); |
| if (indexOfNextConstant == -1) { |
| indexOfNextConstant = |
| requestURIBuffer |
| .indexOf(queryParameterSeparator, |
| endIndexOfConstant); |
| } |
| if (indexOfNextConstant > 0) { |
| addParameterToMap(parameterMap, parameterName, |
| requestURIBuffer.substring(endIndexOfConstant, |
| indexOfNextConstant)); |
| return requestURL.substring(indexOfNextConstant); |
| } else { |
| |
| addParameterToMap(parameterMap, parameterName, |
| requestURIBuffer.substring( |
| endIndexOfConstant)); |
| return ""; |
| } |
| |
| } else { |
| |
| constantPart = |
| pathTemplate.substring(templateEndIndex + 1, |
| pathTemplate.length()); |
| constantPart = constantPart.replaceAll("\\{\\{","{"); |
| constantPart = constantPart.replaceAll("}}","}"); |
| indexOfNextConstant = |
| requestURIBuffer.indexOf(constantPart, endIndexOfConstant); |
| |
| addParameterToMap(parameterMap, parameterName, |
| requestURIBuffer.substring( |
| endIndexOfConstant, indexOfNextConstant)); |
| |
| if (requestURIBuffer.length() > indexOfNextConstant + 1) { |
| return requestURIBuffer.substring(indexOfNextConstant + 1); |
| } |
| return ""; |
| } |
| } else { |
| |
| // this is the next constant from the template |
| constantPart = |
| pathTemplate |
| .substring(templateEndIndex + 1, templateStartIndex); |
| constantPart = constantPart.replaceAll("\\{\\{","{"); |
| constantPart = constantPart.replaceAll("}}","}"); |
| |
| indexOfNextConstant = |
| requestURIBuffer.indexOf(constantPart, endIndexOfConstant); |
| addParameterToMap(parameterMap, parameterName, requestURIBuffer.substring( |
| endIndexOfConstant, indexOfNextConstant)); |
| startIndex = indexOfNextConstant; |
| |
| } |
| |
| } |
| |
| } |
| } |
| |
| return requestURL; |
| } |
| |
| private void addParameterToMap(MultipleEntryHashMap parameterMap, String paramName, |
| String paramValue) |
| throws UnsupportedEncodingException, AxisFault { |
| try { |
| paramValue = URIEncoderDecoder.decode(paramValue); |
| } catch (UnsupportedEncodingException e) { |
| throw AxisFault.makeFault(e); |
| } |
| if (paramName.startsWith(WSDL2Constants.TEMPLATE_ENCODE_ESCAPING_CHARACTER)) { |
| parameterMap.put(paramName.substring(1), paramValue); |
| } else { |
| parameterMap.put(paramName, paramValue); |
| } |
| |
| } |
| |
| private SOAPFactory getSOAPFactory(String nsURI) throws AxisFault { |
| if (nsURI == null) { |
| return OMAbstractFactory.getSOAP12Factory(); |
| } |
| else if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(nsURI)) { |
| return OMAbstractFactory.getSOAP12Factory(); |
| } else if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(nsURI)) { |
| return OMAbstractFactory.getSOAP11Factory(); |
| } else { |
| throw new AxisFault(Messages.getMessage("invalidSOAPversion")); |
| } |
| } |
| } |