name.martingeisse.api.handler.misc.ClasspathResourceHandler.java Source code

Java tutorial

Introduction

Here is the source code for name.martingeisse.api.handler.misc.ClasspathResourceHandler.java

Source

/**
 * Copyright (c) 2010 Martin Geisse
 *
 * This file is distributed under the terms of the MIT license.
 */

package name.martingeisse.api.handler.misc;

import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import name.martingeisse.api.handler.IApiRequestHandler;
import name.martingeisse.api.request.ApiRequestCycle;
import name.martingeisse.api.request.ApiRequestPathChain;

import org.apache.commons.io.IOUtils;

/**
 * This handler writes the contents of a classpath resource
 * to the response. 
 * 
 * The Content-Type must be specified since it cannot be detected
 * automatically. The characterEncoding must be specified for
 * text types.
 * 
 * The classpath scope is a class and determines the classpath
 * package/folder in which the resource is located as well as the
 * class loader used to load the resource. If it is null then the
 * class of this handler is used. This is only useful for
 * subclasses of this class since there are no classpath resource
 * in this package.
 *
 * The filename must be specified.
 */
public class ClasspathResourceHandler implements IApiRequestHandler {

    /**
     * the contentType
     */
    private final String contentType;

    /**
     * the characterEncoding
     */
    private final String characterEncoding;

    /**
     * the classpathScope
     */
    private final Class<?> classpathScope;

    /**
     * the classpathFilename
     */
    private final String classpathFilename;

    /**
     * Constructor.
     * @param contentType the Content-Type of the resource
     * @param classpathScope the scope class that determines the package to load the
     * resource from
     * @param classpathFilename the filename of the resource in the classpath
     */
    public ClasspathResourceHandler(final String contentType, final Class<?> classpathScope,
            final String classpathFilename) {
        this.contentType = contentType;
        this.characterEncoding = null;
        this.classpathScope = classpathScope;
        this.classpathFilename = classpathFilename;
    }

    /**
     * Constructor.
     * @param contentType the Content-Type of the resource
     * @param characterEncoding the character encoding (only needed for text types)
     * @param classpathScope the scope class that determines the package to load the
     * resource from
     * @param classpathFilename the filename of the resource in the classpath
     */
    public ClasspathResourceHandler(final String contentType, final String characterEncoding,
            final Class<?> classpathScope, final String classpathFilename) {
        this.contentType = contentType;
        this.characterEncoding = characterEncoding;
        this.classpathScope = classpathScope;
        this.classpathFilename = classpathFilename;
    }

    /**
     * Getter method for the contentType.
     * @return the contentType
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * Getter method for the classpathScope.
     * @return the classpathScope
     */
    public Class<?> getClasspathScope() {
        return classpathScope;
    }

    /**
     * Getter method for the classpathFilename.
     * @return the classpathFilename
     */
    public String getClasspathFilename() {
        return classpathFilename;
    }

    /* (non-Javadoc)
     * @see name.martingeisse.api.handler.IRequestHandler#handle(name.martingeisse.api.request.RequestCycle, name.martingeisse.api.request.RequestPathChain)
     */
    @Override
    public void handle(final ApiRequestCycle requestCycle, final ApiRequestPathChain path) throws Exception {
        HttpServletResponse response = requestCycle.getResponse();

        // set headers
        if (characterEncoding != null) {
            response.setCharacterEncoding(characterEncoding);
        }
        response.setContentType(contentType);

        // write the resource to the response body
        Class<?> scope = (this.classpathScope == null ? getClass() : this.classpathScope);
        String packageName = scope.getPackage().getName();
        String internalPath = "/" + packageName.replace('.', '/') + '/' + classpathFilename;
        try (InputStream inputStream = scope.getResourceAsStream(internalPath)) {
            if (inputStream == null) {
                throw new Exception("classpath resource not found: " + internalPath);
            }
            try (OutputStream outputStream = requestCycle.getOutputStream()) {
                IOUtils.copy(inputStream, outputStream);
                outputStream.flush();
            }
        }

    }

}