001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.builder;
020:
021: import org.apache.axiom.om.OMAbstractFactory;
022: import org.apache.axiom.om.OMElement;
023: import org.apache.axiom.soap.SOAP11Constants;
024: import org.apache.axiom.soap.SOAP12Constants;
025: import org.apache.axiom.soap.SOAPFactory;
026: import org.apache.axis2.AxisFault;
027: import org.apache.axis2.Constants;
028: import org.apache.axis2.addressing.EndpointReference;
029: import org.apache.axis2.context.MessageContext;
030: import org.apache.axis2.description.AxisBinding;
031: import org.apache.axis2.description.AxisBindingOperation;
032: import org.apache.axis2.description.AxisEndpoint;
033: import org.apache.axis2.description.WSDL20DefaultValueHolder;
034: import org.apache.axis2.description.WSDL2Constants;
035: import org.apache.axis2.i18n.Messages;
036: import org.apache.axis2.transport.http.util.URIEncoderDecoder;
037: import org.apache.axis2.util.MultipleEntryHashMap;
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040:
041: import java.io.BufferedReader;
042: import java.io.IOException;
043: import java.io.InputStream;
044: import java.io.InputStreamReader;
045: import java.io.UnsupportedEncodingException;
046:
047: public class XFormURLEncodedBuilder implements Builder {
048:
049: private static final Log log = LogFactory
050: .getLog(XFormURLEncodedBuilder.class);
051:
052: /**
053: * @return Returns the document element.
054: */
055: public OMElement processDocument(InputStream inputStream,
056: String contentType, MessageContext messageContext)
057: throws AxisFault {
058:
059: MultipleEntryHashMap parameterMap = new MultipleEntryHashMap();
060: SOAPFactory soapFactory;
061: AxisBindingOperation axisBindingOperation = (AxisBindingOperation) messageContext
062: .getProperty(Constants.AXIS_BINDING_OPERATION);
063: String queryParameterSeparator = null;
064: String templatedPath = null;
065: if (axisBindingOperation != null) {
066: queryParameterSeparator = (String) axisBindingOperation
067: .getProperty(WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR);
068: templatedPath = (String) axisBindingOperation
069: .getProperty(WSDL2Constants.ATTR_WHTTP_LOCATION);
070: }
071: if (queryParameterSeparator == null) {
072: queryParameterSeparator = WSDL20DefaultValueHolder.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR_DEFAULT;
073: }
074:
075: AxisEndpoint axisEndpoint = (AxisEndpoint) messageContext
076: .getProperty(WSDL2Constants.ENDPOINT_LOCAL_NAME);
077: if (axisEndpoint != null) {
078: AxisBinding axisBinding = axisEndpoint.getBinding();
079: String soapVersion = (String) axisBinding
080: .getProperty(WSDL2Constants.ATTR_WSOAP_VERSION);
081: soapFactory = getSOAPFactory(soapVersion);
082: } else {
083: soapFactory = getSOAPFactory(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);
084: }
085: EndpointReference endpointReference = messageContext.getTo();
086: if (endpointReference == null) {
087: throw new AxisFault(
088: "Cannot create DocumentElement without destination EPR");
089: }
090:
091: String requestURL = null;
092: try {
093: requestURL = URIEncoderDecoder.decode(endpointReference
094: .getAddress());
095: } catch (UnsupportedEncodingException e) {
096: throw AxisFault.makeFault(e);
097: }
098: try {
099: requestURL = extractParametersUsingHttpLocation(
100: templatedPath, parameterMap, requestURL,
101: queryParameterSeparator);
102: } catch (UnsupportedEncodingException e) {
103: throw AxisFault.makeFault(e);
104: }
105:
106: String query = requestURL;
107: int index;
108: if ((index = requestURL.indexOf("?")) > 0) {
109: query = requestURL.substring(index + 1);
110: }
111:
112: extractParametersFromRequest(
113: parameterMap,
114: query,
115: queryParameterSeparator,
116: (String) messageContext
117: .getProperty(Constants.Configuration.CHARACTER_SET_ENCODING),
118: inputStream);
119:
120: return BuilderUtil.buildsoapMessage(messageContext,
121: parameterMap, soapFactory);
122: }
123:
124: protected void extractParametersFromRequest(
125: MultipleEntryHashMap parameterMap, String query,
126: String queryParamSeparator, String charsetEncoding,
127: InputStream inputStream) throws AxisFault {
128:
129: if (query != null && !"".equals(query)) {
130:
131: String parts[] = query.split(queryParamSeparator);
132: for (int i = 0; i < parts.length; i++) {
133: int separator = parts[i].indexOf("=");
134: if (separator > 0) {
135: parameterMap.put(parts[i].substring(0, separator),
136: parts[i].substring(separator + 1));
137: }
138: }
139:
140: }
141:
142: if (inputStream != null) {
143: try {
144: InputStreamReader inputStreamReader = new InputStreamReader(
145: inputStream, charsetEncoding);
146: BufferedReader bufferedReader = new BufferedReader(
147: inputStreamReader);
148: while (true) {
149: String line = bufferedReader.readLine();
150: if (line != null) {
151: String parts[] = line
152: .split(WSDL20DefaultValueHolder.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR_DEFAULT);
153: for (int i = 0; i < parts.length; i++) {
154: int separator = parts[i].indexOf("=");
155: parameterMap.put(parts[i].substring(0,
156: separator), parts[i]
157: .substring(separator + 1));
158: }
159: } else {
160: break;
161: }
162: }
163: } catch (IOException e) {
164: throw AxisFault.makeFault(e);
165: }
166: }
167: }
168:
169: /**
170: * Here is what I will try to do here. I will first try to identify the location of the first
171: * template element in the request URI. I am trying to deduce the location of that location
172: * using the httpLocation element of the binding (it is passed in to this
173: * method).
174: * If there is a contant part in the httpLocation, then I will identify it. For this, I get
175: * the index of {, from httpLocation param, and whatever to the left of it is the contant part.
176: * Then I search for this constant part inside the url. This will give us the access to the first
177: * template parameter.
178: * To find the end of this parameter, we need to get the index of the next constant, from
179: * httpLocation attribute. Likewise we keep on discovering parameters.
180: * <p/>
181: * Assumptions :
182: * 1. User will always append the value of httpLocation to the address given in the
183: * endpoint.
184: * 2. I was talking about the constants in the httpLocation. Those constants will not occur,
185: * to a reasonable extend, before the constant we are looking for.
186: *
187: * @param templatedPath
188: * @param parameterMap
189: */
190: protected String extractParametersUsingHttpLocation(
191: String templatedPath, MultipleEntryHashMap parameterMap,
192: String requestURL, String queryParameterSeparator)
193: throws AxisFault, UnsupportedEncodingException {
194:
195: if (templatedPath != null && !"".equals(templatedPath)
196: && templatedPath.indexOf("{") > -1) {
197: StringBuffer pathTemplate = new StringBuffer(templatedPath);
198:
199: // this will hold the index, from which we need to process the request URI
200: int startIndex = 0;
201: int templateStartIndex = 0;
202: int templateEndIndex = 0;
203: int indexOfNextConstant = 0;
204:
205: StringBuffer requestURIBuffer = new StringBuffer(requestURL);
206:
207: while (startIndex < requestURIBuffer.length()) {
208: // this will always hold the starting index of a template parameter
209: templateStartIndex = pathTemplate.indexOf("{",
210: templateStartIndex);
211:
212: if (templateStartIndex > 0) {
213: // get the preceding constant part from the template
214: String constantPart = pathTemplate.substring(
215: templateEndIndex + 1, templateStartIndex);
216: constantPart = constantPart.replaceAll("\\{\\{",
217: "{");
218: constantPart = constantPart.replaceAll("}}", "}");
219:
220: // get the index of the end of this template param
221: templateEndIndex = pathTemplate.indexOf("}",
222: templateStartIndex);
223: if ((pathTemplate.length() - 1) > templateEndIndex
224: && pathTemplate
225: .charAt(templateEndIndex + 1) == '}') {
226: templateEndIndex = pathTemplate.indexOf("}",
227: templateEndIndex + 2);
228: }
229:
230: String parameterName = pathTemplate.substring(
231: templateStartIndex + 1, templateEndIndex);
232: // next try to find the next constant
233: templateStartIndex = pathTemplate.indexOf("{",
234: templateEndIndex);
235: if (pathTemplate.charAt(templateStartIndex + 1) == '{') {
236: templateStartIndex = pathTemplate.indexOf("{",
237: templateStartIndex + 2);
238: }
239:
240: int endIndexOfConstant = requestURIBuffer.indexOf(
241: constantPart, indexOfNextConstant)
242: + constantPart.length();
243:
244: if (templateStartIndex == -1) {
245: if (templateEndIndex == pathTemplate.length() - 1) {
246:
247: indexOfNextConstant = requestURIBuffer
248: .indexOf(queryParameterSeparator,
249: endIndexOfConstant);
250: if (indexOfNextConstant > 0) {
251: addParameterToMap(parameterMap,
252: parameterName,
253: requestURIBuffer.substring(
254: endIndexOfConstant,
255: indexOfNextConstant));
256: return requestURL
257: .substring(indexOfNextConstant);
258: } else {
259:
260: addParameterToMap(
261: parameterMap,
262: parameterName,
263: requestURIBuffer
264: .substring(endIndexOfConstant));
265: return "";
266: }
267:
268: } else {
269:
270: constantPart = pathTemplate.substring(
271: templateEndIndex + 1, pathTemplate
272: .length());
273: constantPart = constantPart.replaceAll(
274: "\\{\\{", "{");
275: constantPart = constantPart.replaceAll(
276: "}}", "}");
277: indexOfNextConstant = requestURIBuffer
278: .indexOf(constantPart,
279: endIndexOfConstant);
280:
281: addParameterToMap(parameterMap,
282: parameterName,
283: requestURIBuffer.substring(
284: endIndexOfConstant,
285: indexOfNextConstant));
286:
287: if (requestURIBuffer.length() > indexOfNextConstant + 1) {
288: return requestURIBuffer
289: .substring(indexOfNextConstant + 1);
290: }
291: return "";
292: }
293: } else {
294:
295: // this is the next constant from the template
296: constantPart = pathTemplate.substring(
297: templateEndIndex + 1,
298: templateStartIndex);
299: constantPart = constantPart.replaceAll(
300: "\\{\\{", "{");
301: constantPart = constantPart.replaceAll("}}",
302: "}");
303:
304: indexOfNextConstant = requestURIBuffer.indexOf(
305: constantPart, endIndexOfConstant);
306: addParameterToMap(parameterMap, parameterName,
307: requestURIBuffer.substring(
308: endIndexOfConstant,
309: indexOfNextConstant));
310: startIndex = indexOfNextConstant;
311:
312: }
313:
314: }
315:
316: }
317: }
318:
319: return requestURL;
320: }
321:
322: private void addParameterToMap(MultipleEntryHashMap parameterMap,
323: String paramName, String paramValue)
324: throws UnsupportedEncodingException {
325: if (paramName
326: .startsWith(WSDL2Constants.TEMPLATE_ENCODE_ESCAPING_CHARACTER)) {
327: parameterMap.put(paramName.substring(1), paramValue);
328: } else {
329: parameterMap.put(paramName, paramValue);
330: }
331:
332: }
333:
334: private SOAPFactory getSOAPFactory(String nsURI) throws AxisFault {
335: if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(nsURI)) {
336: return OMAbstractFactory.getSOAP12Factory();
337: } else if (SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI
338: .equals(nsURI)) {
339: return OMAbstractFactory.getSOAP11Factory();
340: } else {
341: throw new AxisFault(Messages
342: .getMessage("invalidSOAPversion"));
343: }
344: }
345: }
|