org.commonjava.cartographer.rest.util.ResponseUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.commonjava.cartographer.rest.util.ResponseUtils.java

Source

/**
 * Copyright (C) 2013 Red Hat, Inc. (jdcasey@commonjava.org)
 *
 * Licensed 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.commonjava.cartographer.rest.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.digest.DigestUtils;
import org.commonjava.cartographer.rest.CartoRESTException;
import org.commonjava.cartographer.rest.dto.CreationDTO;
import org.commonjava.maven.galley.model.Transfer;
import org.commonjava.maven.galley.transport.htcli.model.HttpExchangeMetadata;
import org.commonjava.propulsor.deploy.undertow.util.ApplicationHeader;
import org.commonjava.propulsor.deploy.undertow.util.ApplicationStatus;
import org.commonjava.propulsor.deploy.undertow.util.HttpUtils;
import org.commonjava.propulsor.deploy.undertow.util.StandardApplicationContent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;

public final class ResponseUtils {

    private final static Logger LOGGER = LoggerFactory.getLogger(ResponseUtils.class);

    private ResponseUtils() {
    }

    public static Response formatRedirect(final URI uri) throws URISyntaxException {
        return Response.status(Status.MOVED_PERMANENTLY).location(uri).build();
    }

    public static Response formatCreatedResponse(final String baseUri, final String... params)
            throws URISyntaxException {
        final URI location = new URI(RestUtils.formatUrlTo(baseUri, params));
        return Response.created(location).build();
    }

    public static Response formatCreatedResponseWithJsonEntity(final URI location, final Object dto,
            final ObjectMapper objectMapper) {
        if (dto == null) {
            return Response.noContent().build();
        }

        Response response;
        try {
            response = Response.created(location).entity(objectMapper.writeValueAsString(dto))
                    .type(StandardApplicationContent.application_json).build();
        } catch (final JsonProcessingException e) {
            response = formatResponse(e, "Failed to serialize DTO to JSON: " + dto);
        }

        return response;
    }

    public static Response formatCreatedResponse(final String baseUri, final CreationDTO dto) {
        return Response.created(dto.getUri()).entity(dto.getJsonResponse()).build();
    }

    public static Response formatOkResponseWithJsonEntity(final String json) {
        return formatOkResponseWithEntity(json, StandardApplicationContent.application_json);
    }

    public static Response formatOkResponseWithJsonEntity(final Object dto, final ObjectMapper objectMapper) {
        if (dto == null) {
            return Response.noContent().build();
        }

        Response response;
        try {
            response = Response
                    .ok(objectMapper.writeValueAsString(dto), StandardApplicationContent.application_json).build();
        } catch (final JsonProcessingException e) {
            response = formatResponse(e, "Failed to serialize DTO to JSON: " + dto);
        }

        return response;
    }

    public static ResponseBuilder setInfoHeaders(final ResponseBuilder builder, final Transfer item,
            final String path, final boolean includeContentLength, final String contentType,
            final HttpExchangeMetadata exchangeMetadata) throws CartoRESTException {
        // I don't think we want to use the result from upstream; it's often junk...we should retain control of this.
        builder.header(ApplicationHeader.content_type.key(), contentType);

        boolean lastModSet = false;
        boolean lenSet = false;

        if (exchangeMetadata != null) {
            for (final Map.Entry<String, List<String>> headerSet : exchangeMetadata.getResponseHeaders()
                    .entrySet()) {
                final String key = headerSet.getKey();
                if (ApplicationHeader.content_type.upperKey().equals(key)) {
                    continue;
                } else if (ApplicationHeader.last_modified.upperKey().equals(key)) {
                    lastModSet = true;
                } else if (ApplicationHeader.content_length.upperKey().equals(key)) {
                    lenSet = true;
                    if (!includeContentLength) {
                        continue;
                    }
                }

                for (final String value : headerSet.getValue()) {
                    builder.header(key, value);
                }
            }
        }

        if (!lastModSet) {
            builder.header(ApplicationHeader.last_modified.key(), HttpUtils.formatDateHeader(item.lastModified()));
        }

        if (includeContentLength && !lenSet) {
            Logger logger = LoggerFactory.getLogger(ResponseUtils.class);
            logger.debug("Adding Content-Length header: {}", item.length());

            builder.header(ApplicationHeader.content_length.key(), item.length());
        }

        return builder;
    }

    public static ResponseBuilder setInfoHeaders(final ResponseBuilder builder, final File item,
            final boolean includeContentLength, final String contentType) throws CartoRESTException {
        // I don't think we want to use the result from upstream; it's often junk...we should retain control of this.
        builder.header(ApplicationHeader.content_type.key(), contentType);

        builder.header(ApplicationHeader.last_modified.key(), HttpUtils.formatDateHeader(item.lastModified()));

        if (includeContentLength) {
            builder.header(ApplicationHeader.content_length.key(), item.length());
        }

        return builder;
    }

    public static Response formatResponseFromMetadata(final HttpExchangeMetadata metadata) {
        int code = metadata.getResponseStatusCode();
        // 500-level error; use 502 response.
        Logger logger = LoggerFactory.getLogger(ResponseUtils.class);
        logger.info("Formatting response with code: {}", code);
        if (code / 100 == 5) {
            return Response.status(502).build();
        }

        return Response.status(code).build();
    }

    public static Response formatOkResponseWithEntity(final Object output, final String contentType) {
        return Response.ok(output).type(contentType).build();
    }

    public static Response formatBadRequestResponse(final String error) {
        final String msg = "{\"error\": \"" + error + "\"}\n";
        return Response.status(Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON).entity(msg).build();
    }

    public static Response formatResponse(final Throwable error) {
        return formulateResponse(null, error, null, false);
    }

    public static void throwError(final Throwable error) {
        formulateResponse(null, error, null, true);
    }

    public static Response formatResponse(final ApplicationStatus status, final Throwable error) {
        return formulateResponse(status, error, null, false);
    }

    public static void throwError(final ApplicationStatus status, final Throwable error) {
        formulateResponse(status, error, null, true);
    }

    public static Response formatResponse(final Throwable error, final String message) {
        return formulateResponse(null, error, message, false);
    }

    public static void throwError(final Throwable error, final String message) {
        formulateResponse(null, error, message, true);
    }

    public static Response formatResponse(final ApplicationStatus status, final Throwable error,
            final String message) {
        return formulateResponse(status, error, message, false);
    }

    public static void throwError(final ApplicationStatus status, final Throwable error, final String message) {
        formulateResponse(status, error, message, true);
    }

    private static Response formulateResponse(final ApplicationStatus status, final Throwable error,
            final String message, final boolean throwIt) {
        final String id = generateErrorId();
        final String msg = formatEntity(id, error, message).toString();
        Status code = Status.INTERNAL_SERVER_ERROR;

        if (status != null) {
            code = Status.fromStatusCode(status.code());
            LOGGER.debug("got error code from parameter: {}", code);
        } else if ((error instanceof CartoRESTException) && ((CartoRESTException) error).getCode() > 0) {
            final int sc = ((CartoRESTException) error).getCode();
            LOGGER.debug("got error code from exception: {}", sc);
            code = Status.fromStatusCode(sc);
        }

        LOGGER.error("Sending error response: {} {}\n{}", code.getStatusCode(), code.getReasonPhrase(), msg);

        Response response = Response.status(code)
                .header(ApplicationHeader.content_type.key(), StandardApplicationContent.text_plain).entity(msg)
                .build();

        if (throwIt) {
            throw new WebApplicationException(error, response);
        }

        return response;
    }

    public static String generateErrorId() {
        return DigestUtils.sha256Hex(Thread.currentThread().getName());

        //+ "@" + new SimpleDateFormat( "yyyy-MM-ddThhmmss.nnnZ" ).format( new Date() );
    }

    public static CharSequence formatEntity(final Throwable error) {
        return formatEntity(generateErrorId(), error, null);
    }

    public static CharSequence formatEntity(final String id, final Throwable error) {
        return formatEntity(id, error, null);
    }

    public static CharSequence formatEntity(final Throwable error, final String message) {
        return formatEntity(generateErrorId(), error, message);
    }

    public static CharSequence formatEntity(final String id, final Throwable error, final String message) {
        final StringWriter sw = new StringWriter();
        sw.append("Id: ").append(id);
        if (message != null) {
            sw.append("\nMessage: ").append(message);
        }

        sw.append(error.getMessage());

        final Throwable cause = error.getCause();
        if (cause != null) {
            sw.append("\nError:\n\n");
            cause.printStackTrace(new PrintWriter(sw));
        }

        sw.write('\n');

        return sw.toString();
    }

    public static ResponseBuilder markDeprecated(final ResponseBuilder rb, final String alt) {
        return rb.header(ApplicationHeader.deprecated.key(), alt);
    }

}