Package org.jano

Source Code of org.jano.JanoServer

package org.jano;

import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response;
import fi.iki.elonen.NanoHTTPD.Response.Status;
import org.jano.resources.ResourceRef;
import org.jano.util.StringUtils;
import org.jano.zuss.ZussPlugin;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
* JANO (Java Nano web server)
* This is lightweight server-logic-less web server with ability to update/persist some resource content.
* Features:
*    + no servlet container required
*    + mount-based virtual resource system with access rights
*    + less-like CSS preprocessing
*    + ability to push back resource content
*/
public class JanoServer {

  private final NanoHTTPD httpd;
  private final ExecutorService requestExecutor = Executors.newCachedThreadPool();
  private final VirtualResourceSystem resourceSystem;
  private final List<JanoPlugin> plugins = new ArrayList<JanoPlugin>();

  protected JanoServer(JanoConfig config) {
    httpd = new NanoHTTPD(config.hostname(), config.port()) {
      @Override
      public Response serve(IHTTPSession session) {
        return JanoServer.this.serve(session);
      }
    };

    //consider to use executor service rather than default new Thread().start()
    httpd.setAsyncRunner(new NanoHTTPD.AsyncRunner() {
      @Override
      public void exec(Runnable code) {
        requestExecutor.submit(code);
      }
    });

    //creating virtual system based on mount points
    resourceSystem = new VirtualResourceSystem(config.mountPoints());

    plugins.add(new IndexPlugin());
    plugins.add(new ZussPlugin());
    plugins.add(new ContentPlugin());
  }

  /**
   * Non-blocking operation to start server
   */
  public JanoServer start() {
    try {
      httpd.start();
      Diagnostic.log("Server is started!");
      Diagnostic.log("--------------------------------------------------------------------------------------------");
    } catch (Exception e) {
      throw new JanoException("Unable to start Jano server", e);
    }
    return this;
  }

  /**
   * Blocking operation to await server is stopped
   */
  public JanoServer await() {
    while (httpd.isAlive()) {
      try {
        Thread.sleep(10);
      } catch (InterruptedException e) {
        break;
      }
    }
    return this;
  }

  /**
   * Stops web server. Blocked until thread is not stopped and socket is closed
   */
  public JanoServer stop() {
    httpd.stop();
    return this;
  }

  /**
   * The main entry point of server - processor of any request
   */
  protected NanoHTTPD.Response serve(NanoHTTPD.IHTTPSession session) {
    Response response = serveResource(session);
    Diagnostic.log("\tStatus." + response.getStatus() + " (" + response.getMimeType() + ")");
    return response;
  }

  protected NanoHTTPD.Response serveResource(NanoHTTPD.IHTTPSession session) {
    try {
      String uri = session.getUri();
      ResourceRef ref = resourceSystem.get(uri);

      Diagnostic.log(session.getMethod() + " " + StringUtils.pad(uri, 32) + " " + ref);

      try {
        for (JanoPlugin plugin : plugins) {
          if (plugin.canServe(uri, session.getMethod())) {
            return plugin.serve(session, resourceSystem);
          }
        }

        return Reply.with(Status.NO_CONTENT, ref);
      } catch (SecurityException e) {
        Diagnostic.log(e);
        return Reply.with(Status.FORBIDDEN, ref);
      }
    } catch (Exception e) {
      Diagnostic.log(e);
      return new NanoHTTPD.Response(Status.INTERNAL_ERROR, MimeType.TEXT, e.getMessage());
    }
  }

}
TOP

Related Classes of org.jano.JanoServer

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.