Package org.mule.transport.http.transformers

Source Code of org.mule.transport.http.transformers.ObjectToHttpClientMethodRequest

/*
* $Id: ObjectToHttpClientMethodRequest.java 22270 2011-06-27 16:14:30Z mike.schilling $
* --------------------------------------------------------------------------------------
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/

package org.mule.transport.http.transformers;

import org.mule.RequestContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleMessage;
import org.mule.api.config.MuleProperties;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.OutputHandler;
import org.mule.api.transport.PropertyScope;
import org.mule.message.ds.StringDataSource;
import org.mule.transformer.AbstractMessageTransformer;
import org.mule.transformer.types.DataTypeFactory;
import org.mule.transport.NullPayload;
import org.mule.transport.http.HttpConnector;
import org.mule.transport.http.HttpConstants;
import org.mule.transport.http.StreamPayloadRequestEntity;
import org.mule.transport.http.i18n.HttpMessages;
import org.mule.util.IOUtils;
import org.mule.util.ObjectUtils;
import org.mule.util.SerializationUtils;
import org.mule.util.StringUtils;

import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.activation.URLDataSource;

import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.OptionsMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.TraceMethod;
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;

/**
* <code>ObjectToHttpClientMethodRequest</code> transforms a MuleMessage into a
* HttpClient HttpMethod that represents an HttpRequest.
*/
public class ObjectToHttpClientMethodRequest extends AbstractMessageTransformer
{
    public ObjectToHttpClientMethodRequest()
    {
        setReturnDataType(DataTypeFactory.create(HttpMethod.class));
        registerSourceType(DataTypeFactory.MULE_MESSAGE);
        registerSourceType(DataTypeFactory.BYTE_ARRAY);
        registerSourceType(DataTypeFactory.STRING);
        registerSourceType(DataTypeFactory.INPUT_STREAM);
        registerSourceType(DataTypeFactory.create(OutputHandler.class));
        registerSourceType(DataTypeFactory.create(NullPayload.class));
    }

    @Override
    public Object transformMessage(MuleMessage msg, String outputEncoding) throws TransformerException
    {
        String method = detectHttpMethod(msg);
        try
        {
            HttpMethod httpMethod;

            if (HttpConstants.METHOD_GET.equals(method))
            {
                httpMethod = createGetMethod(msg, outputEncoding);
            }
            else if (HttpConstants.METHOD_POST.equalsIgnoreCase(method))
            {
                httpMethod = createPostMethod(msg, outputEncoding);
            }
            else if (HttpConstants.METHOD_PUT.equalsIgnoreCase(method))
            {
                httpMethod = createPutMethod(msg, outputEncoding);
            }
            else if (HttpConstants.METHOD_DELETE.equalsIgnoreCase(method))
            {
                httpMethod = createDeleteMethod(msg);
            }
            else if (HttpConstants.METHOD_HEAD.equalsIgnoreCase(method))
            {
                httpMethod = createHeadMethod(msg);
            }
            else if (HttpConstants.METHOD_OPTIONS.equalsIgnoreCase(method))
            {
                httpMethod = createOptionsMethod(msg);
            }
            else if (HttpConstants.METHOD_TRACE.equalsIgnoreCase(method))
            {
                httpMethod = createTraceMethod(msg);
            }
            else
            {
                throw new TransformerException(HttpMessages.unsupportedMethod(method));
            }

            // Allow the user to set HttpMethodParams as an object on the message
            final HttpMethodParams params = (HttpMethodParams) msg.removeProperty(
                HttpConnector.HTTP_PARAMS_PROPERTY, PropertyScope.OUTBOUND);
            if (params != null)
            {
                httpMethod.setParams(params);
            }
            else
            {
                // TODO we should probably set other properties here
                final String httpVersion = msg.getOutboundProperty(HttpConnector.HTTP_VERSION_PROPERTY,
                    HttpConstants.HTTP11);
                if (HttpConstants.HTTP10.equals(httpVersion))
                {
                    httpMethod.getParams().setVersion(HttpVersion.HTTP_1_0);
                }
                else
                {
                    httpMethod.getParams().setVersion(HttpVersion.HTTP_1_1);
                }
            }

            setHeaders(httpMethod, msg);

            return httpMethod;
        }
        catch (final Exception e)
        {
            throw new TransformerException(this, e);
        }
    }

    protected String detectHttpMethod(MuleMessage msg)
    {
        String method = msg.getOutboundProperty(HttpConnector.HTTP_METHOD_PROPERTY, null);
        if (method == null)
        {
            method = msg.getInvocationProperty(HttpConnector.HTTP_METHOD_PROPERTY, HttpConstants.METHOD_POST);
        }
        return method;
    }

    protected HttpMethod createGetMethod(MuleMessage msg, String outputEncoding) throws Exception
    {
        final Object src = msg.getPayload();
        // TODO It makes testing much harder if we use the endpoint on the
        // transformer since we need to create correct message types and endpoints
        // URI uri = getEndpoint().getEndpointURI().getUri();
        final URI uri = getURI(msg);
        HttpMethod httpMethod;
        String query = uri.getRawQuery();

        httpMethod = new GetMethod(uri.toString());
        String paramName = msg.getOutboundProperty(HttpConnector.HTTP_GET_BODY_PARAM_PROPERTY, null);
        if (paramName != null)
        {
            paramName = URLEncoder.encode(paramName, outputEncoding);

            String paramValue;
            Boolean encode = msg.getInvocationProperty(HttpConnector.HTTP_ENCODE_PARAMVALUE);
            if (encode == null)
            {
                encode = msg.getOutboundProperty(HttpConnector.HTTP_ENCODE_PARAMVALUE, true);
            }

            if (encode)
            {
                paramValue = URLEncoder.encode(src.toString(), outputEncoding);
            }
            else
            {
                paramValue = src.toString();
            }

            if (!(src instanceof NullPayload) && !StringUtils.EMPTY.equals(src))
            {
                if (query == null)
                {
                    query = paramName + "=" + paramValue;
                }
                else
                {
                    query += "&" + paramName + "=" + paramValue;
                }
            }
        }

        httpMethod.setQueryString(query);
        return httpMethod;
    }

    protected HttpMethod createPostMethod(MuleMessage msg, String outputEncoding) throws Exception
    {
        URI uri = getURI(msg);
        PostMethod postMethod = new PostMethod(uri.toString());

        String bodyParameterName = getBodyParameterName(msg);
        Object src = msg.getPayload();
        if (src instanceof Map)
        {
            for (Map.Entry<?, ?> entry : ((Map<?, ?>) src).entrySet())
            {
                postMethod.addParameter(entry.getKey().toString(), entry.getValue().toString());
            }
        }
        else if (bodyParameterName != null)
        {
            postMethod.addParameter(bodyParameterName, src.toString());

        }
        else
        {
            setupEntityMethod(src, outputEncoding, msg, postMethod);
        }
        checkForContentType(msg, postMethod);

        return postMethod;
    }

    private void checkForContentType(MuleMessage msg, EntityEnclosingMethod method)
    {
        // if a content type was specified on the endpoint, use it
        String outgoingContentType = msg.getInvocationProperty(HttpConstants.HEADER_CONTENT_TYPE);
        if (outgoingContentType != null)
        {
            method.setRequestHeader(HttpConstants.HEADER_CONTENT_TYPE, outgoingContentType);
        }
    }

    protected String getBodyParameterName(MuleMessage message)
    {
        String bodyParameter = message.getOutboundProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY);
        if (bodyParameter == null)
        {
            bodyParameter = message.getInvocationProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY);
        }
        return bodyParameter;
    }

    protected HttpMethod createPutMethod(MuleMessage msg, String outputEncoding) throws Exception
    {
        URI uri = getURI(msg);
        PutMethod putMethod = new PutMethod(uri.toString());

        Object payload = msg.getPayload();
        setupEntityMethod(payload, outputEncoding, msg, putMethod);
        checkForContentType(msg, putMethod);
        return putMethod;
    }

    protected HttpMethod createDeleteMethod(MuleMessage message) throws Exception
    {
        URI uri = getURI(message);
        return new DeleteMethod(uri.toString());
    }

    protected HttpMethod createHeadMethod(MuleMessage message) throws Exception
    {
        URI uri = getURI(message);
        return new HeadMethod(uri.toString());
    }

    protected HttpMethod createOptionsMethod(MuleMessage message) throws Exception
    {
        URI uri = getURI(message);
        return new OptionsMethod(uri.toString());
    }

    protected HttpMethod createTraceMethod(MuleMessage message) throws Exception
    {
        URI uri = getURI(message);
        return new TraceMethod(uri.toString());
    }

    protected URI getURI(MuleMessage message) throws URISyntaxException, TransformerException
    {
        String endpointAddress = message.getOutboundProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, null);
        if (endpointAddress == null)
        {
            throw new TransformerException(
                HttpMessages.eventPropertyNotSetCannotProcessRequest(MuleProperties.MULE_ENDPOINT_PROPERTY),
                this);
        }
        return new URI(endpointAddress);
    }

    protected void setupEntityMethod(Object src, String encoding, MuleMessage msg,
        EntityEnclosingMethod postMethod) throws UnsupportedEncodingException, TransformerException
    {
        // Dont set a POST payload if the body is a Null Payload.
        // This way client calls can control if a POST body is posted explicitly
        if (!(msg.getPayload() instanceof NullPayload))
        {
            String outboundMimeType = (String) msg.getProperty(HttpConstants.HEADER_CONTENT_TYPE,
                PropertyScope.OUTBOUND);
            if (outboundMimeType == null)
            {
                outboundMimeType = (getEndpoint() != null ? getEndpoint().getMimeType() : null);
            }
            if (outboundMimeType == null)
            {
                outboundMimeType = HttpConstants.DEFAULT_CONTENT_TYPE;
                logger.info("Content-Type not set on outgoing request, defaulting to: " + outboundMimeType);
            }

            if (encoding != null && !"UTF-8".equals(encoding.toUpperCase())
                && outboundMimeType.indexOf("charset") == -1)
            {
                outboundMimeType += "; charset=" + encoding;
            }

            // Ensure that we have a cached representation of the message if we're
            // using HTTP 1.0
            final String httpVersion = msg.getOutboundProperty(HttpConnector.HTTP_VERSION_PROPERTY,
                HttpConstants.HTTP11);
            if (HttpConstants.HTTP10.equals(httpVersion))
            {
                try
                {
                    src = msg.getPayloadAsBytes();
                }
                catch (final Exception e)
                {
                    throw new TransformerException(this, e);
                }
            }

            if (msg.getOutboundAttachmentNames() != null && msg.getOutboundAttachmentNames().size() > 0)
            {
                try
                {
                    postMethod.setRequestEntity(createMultiPart(msg, postMethod));
                    return;
                }
                catch (final Exception e)
                {
                    throw new TransformerException(this, e);
                }
            }
            if (src instanceof String)
            {
                postMethod.setRequestEntity(new StringRequestEntity(src.toString(), outboundMimeType, encoding));
                return;
            }

            if (src instanceof InputStream)
            {
                postMethod.setRequestEntity(new InputStreamRequestEntity((InputStream) src, outboundMimeType));
            }
            else if (src instanceof byte[])
            {
                postMethod.setRequestEntity(new ByteArrayRequestEntity((byte[]) src, outboundMimeType));
            }
            else if (src instanceof OutputHandler)
            {
                final MuleEvent event = RequestContext.getEvent();
                postMethod.setRequestEntity(new StreamPayloadRequestEntity((OutputHandler) src, event));
            }
            else
            {
                final byte[] buffer = SerializationUtils.serialize((Serializable) src);
                postMethod.setRequestEntity(new ByteArrayRequestEntity(buffer, outboundMimeType));
            }
        }
        else if (msg.getOutboundAttachmentNames() != null && msg.getOutboundAttachmentNames().size() > 0)
        {
            try
            {
                postMethod.setRequestEntity(createMultiPart(msg, postMethod));
            }
            catch (Exception e)
            {
                throw new TransformerException(this, e);
            }
        }
    }

    protected void setHeaders(HttpMethod httpMethod, MuleMessage msg) throws TransformerException
    {
        for (String headerName : msg.getOutboundPropertyNames())
        {
            String headerValue = ObjectUtils.getString(msg.getOutboundProperty(headerName), null);

            if (headerName.startsWith(MuleProperties.PROPERTY_PREFIX))
            {
                // Define Mule headers a custom headers
                headerName = new StringBuffer(30).append("X-").append(headerName).toString();
                httpMethod.addRequestHeader(headerName, headerValue);

            }
            else if (!HttpConstants.RESPONSE_HEADER_NAMES.containsKey(headerName)
                     && !HttpConnector.HTTP_INBOUND_PROPERTIES.contains(headerName)
                     && !HttpConnector.HTTP_COOKIES_PROPERTY.equals(headerName))
            {

                httpMethod.addRequestHeader(headerName, headerValue);
            }
        }
    }

    protected MultipartRequestEntity createMultiPart(MuleMessage msg, EntityEnclosingMethod method)
        throws Exception
    {
        Part[] parts;
        int i = 0;
        if (msg.getPayload() instanceof NullPayload)
        {
            parts = new Part[msg.getOutboundAttachmentNames().size()];
        }
        else
        {
            parts = new Part[msg.getOutboundAttachmentNames().size() + 1];
            parts[i++] = new FilePart("payload", new ByteArrayPartSource("payload", msg.getPayloadAsBytes()));
        }

        for (final Iterator<String> iterator = msg.getOutboundAttachmentNames().iterator(); iterator.hasNext(); i++)
        {
            final String name = iterator.next();
            String fileName = name;
            final DataHandler dh = msg.getOutboundAttachment(name);
            if (dh.getDataSource() instanceof StringDataSource)
            {
                final StringDataSource ds = (StringDataSource) dh.getDataSource();
                parts[i] = new StringPart(ds.getName(), IOUtils.toString(ds.getInputStream()));
            }
            else
            {
                if (dh.getDataSource() instanceof FileDataSource)
                {
                    fileName = ((FileDataSource) dh.getDataSource()).getFile().getName();
                }
                else if (dh.getDataSource() instanceof URLDataSource)
                {
                    fileName = ((URLDataSource) dh.getDataSource()).getURL().getFile();
                    // Don't use the whole file path, just the file name
                    final int x = fileName.lastIndexOf("/");
                    if (x > -1)
                    {
                        fileName = fileName.substring(x + 1);
                    }
                }
                parts[i] = new FilePart(dh.getName(), new ByteArrayPartSource(fileName,
                    IOUtils.toByteArray(dh.getInputStream())), dh.getContentType(), null);
            }
        }

        return new MultipartRequestEntity(parts, method.getParams());
    }
}
TOP

Related Classes of org.mule.transport.http.transformers.ObjectToHttpClientMethodRequest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.