Package org.tamacat.httpd.core

Source Code of org.tamacat.httpd.core.AbstractHttpHandler

/*
* Copyright (c) 2009, TamaCat.org
* All rights reserved.
*/
package org.tamacat.httpd.core;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.http.HttpEntity;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.protocol.HttpContext;
import org.tamacat.httpd.config.ServiceUrl;
import org.tamacat.httpd.exception.HttpException;
import org.tamacat.httpd.exception.ServiceUnavailableException;
import org.tamacat.httpd.filter.HttpFilter;
import org.tamacat.httpd.filter.RequestFilter;
import org.tamacat.httpd.filter.ResponseFilter;
import org.tamacat.httpd.page.VelocityErrorPage;
import org.tamacat.httpd.util.RequestUtils;
import org.tamacat.httpd.util.ResponseUtils;
import org.tamacat.log.Log;
import org.tamacat.log.LogFactory;
import org.tamacat.util.ExceptionUtils;
import org.tamacat.util.PropertyUtils;
import org.tamacat.util.StringUtils;

/**
* <p>This class is implements of the abstraction of {@link HttpHandler} interface.
*/
public abstract class AbstractHttpHandler implements HttpHandler {
 
    static final Log LOG = LogFactory.getLog(AbstractHttpHandler.class);
    protected static final String DEFAULT_CONTENT_TYPE = "text/html; charset=UTF-8";

  private static Properties mimeTypes;
  private static String serverHome;

  /*
   * 1. using org/tamacat/httpd/mime-types.properties} in jar archive.
   * 2. override or add the mime-types.properties in CLASSPATH. (optional)
   */
    static {
      mimeTypes = PropertyUtils.marge(
          "org/tamacat/httpd/mime-types.properties", "mime-types.properties");
    try {
      serverHome = System.getProperty("server.home");
      if (serverHome == null) serverHome = System.getProperty("user.dir");
      File home = new File(serverHome);
      serverHome = home.getCanonicalPath();
    } catch (Exception e) {
      LOG.error(e);
    }
    }
 
  public static Properties getMimeTypes() {
    return mimeTypes;
  }
 
  protected VelocityErrorPage errorPage;
    protected ServiceUrl serviceUrl;
    protected String docsRoot;
    protected String encoding = "UTF-8";
   
    protected List<HttpFilter> filters = new ArrayList<HttpFilter>();
    protected List<RequestFilter> requestFilters = new ArrayList<RequestFilter>();
    protected List<ResponseFilter> responseFilters = new ArrayList<ResponseFilter>();
    protected ClassLoader loader;
   
  @Override
    public void setServiceUrl(ServiceUrl serviceUrl) {
      this.serviceUrl = serviceUrl;
      for (HttpFilter filter : filters) {
        filter.init(serviceUrl);
      }
    Properties props = PropertyUtils.getProperties("velocity.properties", getClassLoader());
      errorPage = new VelocityErrorPage(props);
    }
   
  @Override
  public void setHttpFilter(HttpFilter filter) {
    filters.add(filter);
    if (filter instanceof RequestFilter) {
      requestFilters.add((RequestFilter)filter);
    }
    if (filter instanceof ResponseFilter) {
      responseFilters.add((ResponseFilter)filter);
    }
  }
 
  /**
   * <p>Set the path of document root.
   * @param docsRoot
   */
  public void setDocsRoot(String docsRoot) {
    this.docsRoot = docsRoot.replace("${server.home}", serverHome).replace("\\", "/");
  }
 
  /**
   * <p>Set the character encoding. (default UTF-8)
   * @param encoding
   */
  public void setEncoding(String encoding) {
    this.encoding = encoding;
  }
 
  @Override
  public void handle(HttpRequest request, HttpResponse response,
      HttpContext context) {
    RequestUtils.setParameters(request, context, encoding);
    try {
      for (RequestFilter filter : requestFilters) {
        filter.doFilter(request, response, context);
      }
      doRequest(request, response, context);
    } catch (Exception e) {
      handleException(request, response, e);
    } finally {
      for (ResponseFilter filter : responseFilters) {
        filter.afterResponse(request, response, context);
      }
    }
  }
 
  /**
   * <p>When the exception is generated by processing {@link handleRequest},
   *  this method is executed.
   * 
   * @param request
   * @param response
   * @param e
   */
  protected void handleException(HttpRequest request, HttpResponse response, Exception e) {
    String html = null;
    if (e instanceof HttpException) {
      html = errorPage.getErrorPage(request, response, (HttpException)e);
    } else {
      if (LOG.isWarnEnabled()) {
        LOG.warn(ExceptionUtils.getStackTrace(e, 500));
      }
      html = errorPage.getErrorPage(request, response,
          new ServiceUnavailableException(e));
    }
    HttpEntity entity = getEntity(html);
    ResponseUtils.setEntity(response, entity);
  }
 
  /**
   * <p>Handling the request, this method is executed after {@link RequestFilter}.
   * @see {@link executeRequestFilter}
   * @param request
   * @param response
   * @param context
   * @throws HttpException
   * @throws IOException
   */
  protected abstract void doRequest(
        HttpRequest request, HttpResponse response, HttpContext context)
      throws HttpException, IOException;

  /**
   * <p>The entity is acquired based on the string.
   * @param html
   * @return {@link HttpEntity}
   */
  protected abstract HttpEntity getEntity(String html);
 
  /**
   * <p>The entity is acquired based on the file.
   * @param file
   * @return {@link HttpEntity}
   */
  protected abstract HttpEntity getFileEntity(File file);
 
  /**
   * <p>The contents type is acquired from the extension. <br>
   * The correspondence of the extension and the contents type is
   *  acquired from the {@code mime-types.properties} file. <br>
   * When there is no file and the extension cannot be acquired,
   * an {@link DEFAULT_CONTENT_TYPE} is returned.
   * @param file
   * @return contents type
   */
    protected String getContentType(File file) {
      if (file == null) return DEFAULT_CONTENT_TYPE;
      String fileName = file.getName();
      String ext = fileName.substring(fileName.lastIndexOf('.')+1, fileName.length());
      String contentType =  getMimeTypes().getProperty(ext.toLowerCase());
      return StringUtils.isNotEmpty(contentType)? contentType : DEFAULT_CONTENT_TYPE;
    }
   
    /**
     * <p>Returns the decoded URI.
     * @param uri
     * @return default decoding is UTF-8.
     */
    protected String getDecodeUri(String uri) {
      try {
        return URLDecoder.decode(uri, encoding);
      } catch (UnsupportedEncodingException e) {
        return uri;
      }
    }
   
    public void setClassLoader(ClassLoader loader) {
      this.loader = loader;
    }
   
    public ClassLoader getClassLoader() {
      return loader != null ? loader : getClass().getClassLoader();
    }
}
TOP

Related Classes of org.tamacat.httpd.core.AbstractHttpHandler

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.