org.jclouds.http.apachehc.ApacheHCUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.jclouds.http.apachehc.ApacheHCUtils.java

Source

/*
 * 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.jclouds.http.apachehc;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Set;

import javax.inject.Singleton;
import javax.ws.rs.HttpMethod;

import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;
import org.jclouds.JcloudsVersion;
import org.jclouds.http.HttpRequest;
import org.jclouds.io.ContentMetadataCodec;
import org.jclouds.io.MutableContentMetadata;
import org.jclouds.io.Payload;
import org.jclouds.io.payloads.BasePayload;
import org.jclouds.io.payloads.ByteArrayPayload;
import org.jclouds.io.payloads.DelegatingPayload;
import org.jclouds.io.payloads.FilePayload;
import org.jclouds.io.payloads.StringPayload;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HttpHeaders;

@Singleton
public class ApacheHCUtils {
    //TODO: look up httpclient version
    public static final String USER_AGENT = String.format("jclouds/%s httpclient/%s", JcloudsVersion.get(),
            "4.1.1");

    private final ContentMetadataCodec contentMetadataCodec;

    public ApacheHCUtils(ContentMetadataCodec contentMetadataCodec) {
        this.contentMetadataCodec = contentMetadataCodec;
    }

    public HttpUriRequest convertToApacheRequest(HttpRequest request) {
        HttpUriRequest apacheRequest;
        if (request.getMethod().equals(HttpMethod.HEAD)) {
            apacheRequest = new HttpHead(request.getEndpoint());
        } else if (request.getMethod().equals(HttpMethod.GET)) {
            apacheRequest = new HttpGet(request.getEndpoint());
        } else if (request.getMethod().equals(HttpMethod.DELETE)) {
            apacheRequest = new HttpDelete(request.getEndpoint());
        } else if (request.getMethod().equals(HttpMethod.PUT)) {
            apacheRequest = new HttpPut(request.getEndpoint());
            apacheRequest.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
        } else if (request.getMethod().equals(HttpMethod.POST)) {
            apacheRequest = new HttpPost(request.getEndpoint());
        } else {
            final String method = request.getMethod();
            if (request.getPayload() != null)
                apacheRequest = new HttpEntityEnclosingRequestBase() {

                    @Override
                    public String getMethod() {
                        return method;
                    }

                };
            else
                apacheRequest = new HttpRequestBase() {

                    @Override
                    public String getMethod() {
                        return method;
                    }

                };
            HttpRequestBase.class.cast(apacheRequest).setURI(request.getEndpoint());
        }
        Payload payload = request.getPayload();

        // Since we may remove headers, ensure they are added to the apache
        // request after this block
        if (apacheRequest instanceof HttpEntityEnclosingRequest) {
            if (payload != null) {
                addEntityForContent(HttpEntityEnclosingRequest.class.cast(apacheRequest), payload);
            }
        } else {
            apacheRequest.addHeader(HttpHeaders.CONTENT_LENGTH, "0");
        }

        for (Map.Entry<String, String> entry : request.getHeaders().entries()) {
            String header = entry.getKey();
            // apache automatically tries to add content length header
            if (!header.equals(HttpHeaders.CONTENT_LENGTH))
                apacheRequest.addHeader(header, entry.getValue());
        }
        apacheRequest.addHeader(HttpHeaders.USER_AGENT, USER_AGENT);
        return apacheRequest;
    }

    public void addEntityForContent(HttpEntityEnclosingRequest apacheRequest, Payload payload) {
        payload = payload instanceof DelegatingPayload ? DelegatingPayload.class.cast(payload).getDelegate()
                : payload;
        if (payload instanceof StringPayload) {
            StringEntity nStringEntity = null;
            try {
                nStringEntity = new StringEntity((String) payload.getRawContent());
            } catch (UnsupportedEncodingException e) {
                throw new UnsupportedOperationException("Encoding not supported", e);
            }
            nStringEntity.setContentType(payload.getContentMetadata().getContentType());
            apacheRequest.setEntity(nStringEntity);
        } else if (payload instanceof FilePayload) {
            apacheRequest.setEntity(
                    new FileEntity((File) payload.getRawContent(), payload.getContentMetadata().getContentType()));
        } else if (payload instanceof ByteArrayPayload) {
            ByteArrayEntity Entity = new ByteArrayEntity((byte[]) payload.getRawContent());
            Entity.setContentType(payload.getContentMetadata().getContentType());
            apacheRequest.setEntity(Entity);
        } else {
            InputStream inputStream = payload.getInput();
            if (payload.getContentMetadata().getContentLength() == null)
                throw new IllegalArgumentException("you must specify size when content is an InputStream");
            InputStreamEntity entity = new InputStreamEntity(inputStream,
                    payload.getContentMetadata().getContentLength());
            entity.setContentType(payload.getContentMetadata().getContentType());
            apacheRequest.setEntity(entity);
        }

        // TODO Reproducing old behaviour exactly; ignoring Content-Type, Content-Length and Content-MD5
        Set<String> desiredHeaders = ImmutableSet.of("Content-Disposition", "Content-Encoding", "Content-Language",
                "Expires");
        MutableContentMetadata md = payload.getContentMetadata();
        for (Map.Entry<String, String> entry : contentMetadataCodec.toHeaders(md).entries()) {
            if (desiredHeaders.contains(entry.getKey())) {
                apacheRequest.addHeader(entry.getKey(), entry.getValue());
            }
        }

        assert apacheRequest.getEntity() != null;
    }

    public static class HttpEntityPayload extends BasePayload<HttpEntity> {

        HttpEntityPayload(HttpEntity content) {
            super(content);
            getContentMetadata().setContentType(content.getContentType().getValue());
            getContentMetadata().setContentLength(content.getContentLength());
        }

        @Override
        public InputStream openStream() throws IOException {
            try {
                return content.getContent();
            } catch (IllegalStateException e) {
                throw Throwables.propagate(e);
            }
        }

        @Override
        public boolean isRepeatable() {
            return content.isRepeatable();
        }

        @Override
        public void release() {
            try {
                EntityUtils.consume(content);
            } catch (IOException e) {
            }
        }
    }

}