Package de.chris_soft.nanodoa.web

Source Code of de.chris_soft.nanodoa.web.DocumentServer

/**
* NanoDoA - File based document archive
*
* Copyright (C) 2011-2012 Christian Packenius, christian.packenius@googlemail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package de.chris_soft.nanodoa.web;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import de.chris_soft.nanoarchive.Archive;
import de.chris_soft.utilities.FileUtils;
import de.chris_soft.utilities.web.HtmlWebsite;
import fi.iki.elonen.NanoHTTPD;

/**
* HTTP server and html page building.
* @author Christian Packenius.
*/
public class DocumentServer extends NanoHTTPD {
  private Map<String, Class<? extends HtmlWebsite>> name2websiteClass = new HashMap<String, Class<? extends HtmlWebsite>>();

  private String indexWebsite = null;

  private final Response unknownSiteResponse = new Response(HTTP_NOTIMPLEMENTED, MIME_PLAINTEXT, "Website not found!");

  private final Archive documentArchive;

  /**
   * Constructor.
   * @param documentArchive DocumentArchive.
   * @param port Port for http serving.
   * @throws Exception
   */
  public DocumentServer(Archive documentArchive, int port) throws Exception {
    super(port, new File("web"));
    this.documentArchive = documentArchive;
    DocumentRetrievalWebsite.archive = this.documentArchive;
    System.out.println("Document server started at port " + port + ".");
    addDistinctWebsites();
  }

  private void addDistinctWebsites() throws NoSuchMethodException, InstantiationException, IllegalAccessException,
      InvocationTargetException {
    addWebsite(DocumentRetrievalWebsite.class);
    addWebsite(DocumentSearchWebsite.class);
    indexWebsite = new DocumentSearchWebsite().getWebsiteName();
  }

  /**
   * Adds a specific website to the web application.
   * @param websiteClass Website class for the website.
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   * @throws InstantiationException
   * @throws NoSuchMethodException
   */
  public void addWebsite(Class<? extends HtmlWebsite> websiteClass) throws NoSuchMethodException,
      InstantiationException, IllegalAccessException, InvocationTargetException {
    String websiteName = createWebsiteObject(null, websiteClass, null).getWebsiteName();
    name2websiteClass.put(websiteName, websiteClass);
  }

  /**
   * Set the website that is shown if no site name is given in the uri.
   * @param siteName Name of the initial website.
   */
  public void setIndexWebsite(String siteName) {
    indexWebsite = siteName;
  }

  /**
   * @see fi.iki.elonen.NanoHTTPD#serve(java.lang.String, java.lang.String,
   *      java.util.Properties, java.util.Properties, java.util.Properties)
   */
  @Override
  public Response serve(String uri, String method, Properties header, Properties parms, Properties files) {
    try {
      if (new File("web" + uri).exists()) {
        return getFileResponseFromURI(uri);
      }
      System.out.println("DocumentServer quest: " + method + " " + uri + " " + parms);
      System.out.println("              header: " + header);
      List<String> uriParts = getUriParts(uri);
      String siteName = getSiteName(uriParts);
      return getResponseByWebsiteName(parms, siteName, uriParts);
    }
    catch (Exception e) {
      return unknownSiteResponse;
    }
  }

  /**
   * Set file in URI as HTTP response.
   * @param uri URI representing the file.
   * @return File-Response.
   * @throws IOException
   */
  public Response getFileResponseFromURI(String uri) throws IOException {
    File file = new File("web" + uri);
    return getFileResponseFromFile(file);
  }

  /**
   * Set file as HTTP response.
   * @param file File to send as response.
   * @return File-Response.
   * @throws IOException
   */
  public Response getFileResponseFromFile(File file) throws IOException {
    String mimeType = theMimeTypes.get(FileUtils.getFileExtension(file));
    if (mimeType == null) {
      mimeType = MIME_PLAINTEXT;
    }
    byte[] fileContent = FileUtils.readFileAsBytes(file);
    return new Response(HTTP_OK, mimeType, fileContent);
  }

  private Response getResponseByWebsiteName(Properties parms, String siteName, List<String> uriParts)
      throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
    Class<? extends HtmlWebsite> websiteClass = name2websiteClass.get(siteName);
    if (websiteClass == null) {
      return unknownSiteResponse;
    }
    HtmlWebsite website = createWebsiteObject(parms, websiteClass, uriParts);
    try {
      return getResponseFromWebsite(website);
    }
    catch (IOException e) {
      return getFileNotFoundWebsiteContent();
    }
  }

  private Response getResponseFromWebsite(HtmlWebsite website) throws IOException {
    String websiteContent = website.getSiteContent();
    File file = website.getResponseFile();
    if (file == null) {
      return new Response(HTTP_OK, MIME_HTML, websiteContent);
    }
    if (file.exists()) {
      System.out.println("Serve file: " + file.getAbsolutePath());
      // Das folgende funktioniert bei Google Chrome schlicht nicht:
      // return serveFile("/" + file.getName(), new Properties(),
      // file.getParentFile(), false);
      return getFileResponseFromFile(file);
    }
    return getFileNotFoundWebsiteContent();
  }

  private Response getFileNotFoundWebsiteContent() {
    String websiteContent = new DocumentNotFoundWebsite().getSiteContent();
    return new Response(HTTP_OK, MIME_HTML, websiteContent);
  }

  private HtmlWebsite createWebsiteObject(Properties parms, Class<? extends HtmlWebsite> websiteClass,
      List<String> uriParts) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
      InvocationTargetException {
    Constructor<? extends HtmlWebsite> websiteConstructor = websiteClass.getConstructor();
    HtmlWebsite website = websiteConstructor.newInstance();
    website.setParameters(parms);
    return website;
  }

  private String getSiteName(List<String> uriParts) {
    final String siteName;
    if (uriParts.isEmpty()) {
      siteName = indexWebsite;
    }
    else {
      siteName = uriParts.remove(0);
    }
    return siteName;
  }

  private List<String> getUriParts(String uri) {
    List<String> uriParts = new ArrayList<String>();
    int k;
    while (uri != null && uri.length() > 0) {
      if (uri.startsWith("/")) {
        uri = uri.substring(1);
      }
      else if ((k = uri.indexOf('/')) >= 0) {
        uriParts.add(uri.substring(0, k));
        uri = uri.substring(k + 1).trim();
      }
      else {
        uriParts.add(uri);
        break;
      }
    }
    return uriParts;
  }
}
TOP

Related Classes of de.chris_soft.nanodoa.web.DocumentServer

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.