Package dovetaildb.servlet

Source Code of dovetaildb.servlet.DovetaildbServlet

package dovetaildb.servlet;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import dovetaildb.apiservice.ApiException;
import dovetaildb.apiservice.ApiService;
import dovetaildb.dbrepository.DbRepository;
import dovetaildb.dbrepository.ParsedRequest;
import dovetaildb.dbrepository.RequestAcceptor;
import dovetaildb.scriptbridge.ScriptFunction;
import dovetaildb.scriptbridge.UniversalScriptBridge;
import dovetaildb.util.Pair;
import dovetaildb.util.Util;

public class DovetaildbServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

  private static final long serialVersionUID = -8232011496563375902L;

  protected DbRepository repo;
  public DbRepository getRepo() { return repo; }
  public void setRepo(DbRepository repo) { this.repo = repo; }

  ScriptFunction globalAcceptFn = null;
  public ScriptFunction getGlobalAcceptFn() {  return globalAcceptFn; }
  public void setGlobalAcceptFn(ScriptFunction globalAcceptFn) { this.globalAcceptFn = globalAcceptFn; }
 
  public interface Host {
    void ddbStopListening();
    void ddbShutdown();
  }
  Host host = null;
  public void setHost(Host host) {this.host = host; }
  public Host getHost() { return host; }
 
  public DovetaildbServlet() { super(); }
 
  boolean isLoggingRequests = false;
  public void setIsLoggingRequests(boolean isLoggingRequests) {
    this.isLoggingRequests = isLoggingRequests;
  }
  public boolean isLoggingRequests() { return isLoggingRequests; }

  boolean isAllowingIdParameters = false;
  public void setIsAllowingIdParameters(boolean isAllowingIdParameters) {
    this.isAllowingIdParameters = isAllowingIdParameters;
  }
  public boolean isAllowingIdParameters() { return isAllowingIdParameters; }
 
  final int MAX_RESPONSE_LOG_LENGTH = 1024;

  protected Object handle(String url, boolean insertOrUpdate, HttpServletRequest request, HttpServletResponse response) {
    ParsedRequest req = new ParsedRequest(url, insertOrUpdate, request, response);
    if (req.db == null) req.db = "_metadata";
    RequestAcceptor acceptor = repo.getRequestAcceptor("_metadata");
    if (! acceptor.accept(req) ) {
      throw new ApiException("PermissionDenied","Permission denied");
//      if (! req.response.isCommitted()) {
//        try {
//          req.response.sendError(HttpServletResponse.SC_FORBIDDEN);
//          return;
//        } catch (IOException e) {
//          throw new RuntimeException(e);
//        }
//      }
    }
    Object returnVal = null;
    ApiService api = repo.newSession(req.db);
    if (req.action == "call") { // double equals ok here (both sides are from literal strings)
      List arguments = (List)Util.jsonDecode(req.request.getParameter("arguments"));
      returnVal = repo.invokeFunction(req.db, req.methodName, arguments.toArray());
    } else if (req.action == "execute") {
      String code = req.request.getParameter("code");
      ArrayList<Pair<String,String>> codeFiles = new ArrayList<Pair<String,String>>(1);
      codeFiles.set(0, new Pair<String, String>("<execute code>", code));
      Map<String,Object> env = Util.literalMap().p("dovetaildb", api);
      returnVal = (new UniversalScriptBridge()).evaluateExpression(req.scriptLanguage+":"+codeFiles, env);
    } else if (req.action == "query") {
      String query = req.request.getParameter("query");
      returnVal = api.query(req.bagName, (List)Util.jsonDecode(query), null);
    } else if (req.action == "insert") {
      Map<String,Object> entry = (Map<String,Object>)Util.jsonDecode(req.request.getParameter("entry"));
      if (req.id != null) {
        entry.put("id", req.id);
      }
      api.insert(req.bagName, entry);
    } else if (req.action == "update") {
      Map<String,Object> entry = (Map<String,Object>)Util.jsonDecode(req.request.getParameter("entry"));
      api.update(req.bagName, req.id, entry);
    } else if (req.action == "remove") {
      api.remove(req.bagName, req.id);
    }
    return returnVal;
  }
 
  @Override
  protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    shipResponse(request, response, handle(request.getPathInfo()+"/remove", false,  request, response));
  }
 
  @Override
  protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    shipResponse(request, response, handle(request.getPathInfo()+"/update", true, request, response));
  }

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    shipResponse(request, response, handle(request.getPathInfo()+"/query", false, request, response));
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    shipResponse(request, response, handle(request.getPathInfo(), false, request, response));
  }
  /*
  {
    if (isLoggingRequests) {
      String url = request.getRequestURL().toString();
      String queryString = request.getQueryString();
      if (queryString != null) url += "?"+queryString;
      this.log("--> "+url);
    }
    doIt(request, response);
  }            
  {
    if (isLoggingRequests) {
      StringBuffer buf = new StringBuffer();
      OUTER : for(Object eObj : request.getParameterMap().entrySet()) {
        Map.Entry entry = ((Map.Entry)eObj);
        for(String v : (String[])entry.getValue()) {
              buf.append('&');
              buf.append(URLEncoder.encode((String)entry.getKey(), "UTF-8"));
              buf.append('=');
              buf.append(URLEncoder.encode(v, "UTF-8"));
              if (buf.length() > MAX_RESPONSE_LOG_LENGTH) {
                buf.delete(MAX_RESPONSE_LOG_LENGTH, buf.length());
                buf.append("...");
                break OUTER;
              }
            }
          }
      String url = request.getRequestURL().toString();
      buf.setCharAt(0, '?');
      this.log("--> " + url + buf);
    }
    doIt(request, response);
  }
  */
  public static JSONObject toJsonError(Exception e) {
    Throwable cause = e.getCause();
    if (cause == null) cause = e;
    JSONObject error = new JSONObject();
    if (e instanceof ApiException) {
      ApiException apiException = (ApiException)e;
      error.put("name", apiException.exName);
      error.put("message", apiException.getMessage());
      if (apiException.stackTrace != null)
        error.put("stacktrace", apiException.stackTrace);
    } else {
      error.put("name", e.getClass().toString());
      error.put("message", e.toString());
    }
    org.json.simple.JSONArray jsonTrace = new org.json.simple.JSONArray();
    for(StackTraceElement elem: cause.getStackTrace()) {
      jsonTrace.add(elem.toString());
    }
    error.put("traceback", jsonTrace);
    return error;
  }

  protected void shipResponse(HttpServletRequest request, HttpServletResponse response, Object results) throws ServletException, IOException {
    long t0 = System.currentTimeMillis();
    Map<String,Object> jsonResponse = new HashMap<String,Object>();
    jsonResponse.put("version","1.1");
    String txnId = request.getParameter("reqid");
    if (txnId != null)
      jsonResponse.put("id", txnId);
    try {
      jsonResponse.put("result", results);
    } catch(Exception e) {
      JSONObject error = toJsonError(e);
      jsonResponse.put("error", error);
    }
    ServletOutputStream os = response.getOutputStream();
    String jsonCallback = request.getParameter("callback");
    os.flush();
    final Writer coreWriter = new BufferedWriter(new OutputStreamWriter(os));
    Writer wtr = coreWriter;
    if (jsonCallback != null) {
      wtr.write(jsonCallback);
      wtr.write("(");
    }
    if (! isLoggingRequests) {
      Util.jsonEncode(wtr, jsonResponse);
    } else {
      final StringBuffer logBuffer = new StringBuffer();
      wtr = new Writer() {
        public void close() throws IOException {coreWriter.close();}
        public void flush() throws IOException {coreWriter.flush();}
        public void write(char[] arg0, int arg1, int arg2) throws IOException {
          coreWriter.write(arg0, arg1, arg2);
          if (logBuffer.length() < MAX_RESPONSE_LOG_LENGTH) {
            logBuffer.append(arg0, arg1, arg2);
          }
        }
      };
      Util.jsonEncode(wtr, jsonResponse);
      String ret = (logBuffer.length() > MAX_RESPONSE_LOG_LENGTH) ?
          logBuffer.substring(0,MAX_RESPONSE_LOG_LENGTH)+"..." : logBuffer.toString();
      t0 = System.currentTimeMillis() - t0;
      this.log("<-- ("+t0+" ms) "+ret);
    }
    if (jsonCallback != null) {
      wtr.write(")");
    }
    wtr.flush();
  }

 

  @Override
  public void destroy() {
    this.repo.close();
  }


}
TOP

Related Classes of dovetaildb.servlet.DovetaildbServlet

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.