diff software/eXist/mpdl-modules/src/de/mpg/mpiwg/berlin/mpdl/escidoc/ESciDocRESTServlet.java @ 0:408254cf2f1d

Erstellung
author Josef Willenborg <jwillenborg@mpiwg-berlin.mpg.de>
date Wed, 24 Nov 2010 17:24:23 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/software/eXist/mpdl-modules/src/de/mpg/mpiwg/berlin/mpdl/escidoc/ESciDocRESTServlet.java	Wed Nov 24 17:24:23 2010 +0100
@@ -0,0 +1,364 @@
+package de.mpg.mpiwg.berlin.mpdl.escidoc;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.methods.GetMethod;
+
+import de.mpg.mpiwg.berlin.mpdl.exception.ApplicationException;
+import de.mpg.mpiwg.berlin.mpdl.general.MpdlConstants;
+import de.mpg.mpiwg.berlin.mpdl.util.FileUtil;
+import de.mpg.mpiwg.berlin.mpdl.util.XmlUtil;
+import de.mpg.mpiwg.berlin.mpdl.xmlrpc.MpdlXmlRpcDocHandler;
+
+public class ESciDocRESTServlet extends HttpServlet {
+  private static final long serialVersionUID = -4889427839010526185L;
+  private static int FILE_UPLOAD_MAX_MEMORY_SIZE = 100000;  // 100 KB
+  private static String FILE_UPLOAD_TEMP_DIRECTORY = MpdlConstants.MPDL_EXIST_DATA_DIR + "/tmpUploadDir";
+  
+  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    try {
+      String escidocUrl = req.getParameter("escidocUrl");
+      String query = req.getParameter("query");
+      String queryPath = req.getParameter("queryPath");
+      String parameters = req.getParameter("parameters");
+      String startRecord = req.getParameter("startRecord");
+      String maximumRecords = req.getParameter("maximumRecords");
+      Cookie[] cookies = req.getCookies();
+      String eScidDocCookie = getCookieValue(cookies, "escidocCookie");
+      int startRecordInt = -1;
+      if (startRecord != null && ! startRecord.equals(""))
+        startRecordInt = Integer.parseInt(startRecord);
+      int maximumRecordsInt = -1;
+      if (maximumRecords != null && ! maximumRecords.equals(""))
+        maximumRecordsInt = Integer.parseInt(maximumRecords);
+      resp.setContentType("text/xml;charset=\"utf-8\"");  // important: otherwise the response is sent as iso-8859-1  
+      PrintWriter out = resp.getWriter();
+      // execute xquery script on eXist server
+      if (escidocUrl != null && escidocUrl.startsWith("/exist:xquery/execute")) {
+        if (query != null && ! query.equals("")) {
+          String xqueryResult = xquery("string", query, null, startRecordInt, maximumRecordsInt);
+          out.print(xqueryResult);
+        } else if (queryPath != null && ! queryPath.equals("")) {
+          String xqueryResult = xquery("uri", queryPath, parameters, startRecordInt, maximumRecordsInt);
+          out.print(xqueryResult);
+        }
+      } else if (escidocUrl != null && escidocUrl.startsWith("/ir/item/") && escidocUrl.contains("/exist:xquery/execute")) {
+        String existDocUrl = getExistDocUrl(eScidDocCookie, escidocUrl);
+        String xQueryParamDocument = "<param name=\"document\">" + existDocUrl + "</param>";
+        String params = "";
+        if (parameters != null && ! parameters.equals("")) {
+          int index = parameters.indexOf("</params>");
+          params = parameters.substring(0, index) + xQueryParamDocument + parameters.substring(index);
+        } else {
+          params = "<params>" + xQueryParamDocument + "</params>";
+        }
+        if (query != null && ! query.equals("")) {
+          String xqueryResult = xquery("string", query, params, startRecordInt, maximumRecordsInt);
+          out.print(xqueryResult);
+        } else if (queryPath != null && ! queryPath.equals("")) {
+          String xqueryResult = xquery("uri", queryPath, params, startRecordInt, maximumRecordsInt);
+          out.print(xqueryResult);
+        }
+      } else {
+        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        out.println("<error>");
+        out.print("EsciDoc does not support your URL: " + escidocUrl);
+        out.print("</error>");
+      }
+    } catch (ApplicationException e) {
+      throw new ServletException(e);
+    }
+  }
+  
+  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    try {
+      String escidocUrl = req.getParameter("escidocUrl");
+      Cookie[] cookies = req.getCookies();
+      String eScidDocCookie = getCookieValue(cookies, "escidocCookie");
+      PrintWriter out = resp.getWriter();
+      boolean isMultipart = ServletFileUpload.isMultipartContent(req);
+      if (! isMultipart) { // if not multipartContent (e.g. set by client with setRequestBody or setRequestEntity)
+        ServletInputStream is = req.getInputStream();
+        File tmpUploadItemFile = File.createTempFile("item", ".xml", new File(FILE_UPLOAD_TEMP_DIRECTORY));
+        String tmpUploadItemFileName = tmpUploadItemFile.getPath();
+        FileUtil.getInstance().saveInputStreamToLocalFile(is, tmpUploadItemFileName);
+        String containerId = getESciDocContainerId(escidocUrl);
+        String newItemXmlStr = createItemInContainer(eScidDocCookie, containerId, tmpUploadItemFileName);  // create item and eXist document
+        out.println(newItemXmlStr);
+      } else {  // multipart content (each file item is uploaded) 
+        DiskFileItemFactory factory = new DiskFileItemFactory();
+        factory.setSizeThreshold(FILE_UPLOAD_MAX_MEMORY_SIZE);  // default is 100 KB
+        File tmpFileUplaodDir = new File(FILE_UPLOAD_TEMP_DIRECTORY);
+        factory.setRepository(tmpFileUplaodDir);  // for files which are bigger than the threshold; files are deleted, when they are garbage collected
+        ServletFileUpload upload = new ServletFileUpload(factory);
+        List<FileItem> items = upload.parseRequest(req);
+        Iterator<FileItem> iter = items.iterator();
+        while (iter.hasNext()) {
+          /* fetch an item from the iterator above */
+          FileItem item = iter.next();
+          if (!item.isFormField()) {
+            String fileName = item.getName(); 
+            long sizeInBytes = item.getSize(); 
+            File uploadedFile = new File(FILE_UPLOAD_TEMP_DIRECTORY + "/" + fileName); 
+            item.write(uploadedFile); 
+            out.println("<h1>File: " + uploadedFile.getAbsolutePath() + " (size: " + sizeInBytes + ") written</h1><br>");
+          } 
+        }
+      }
+    } catch (Exception e ) {
+      throw new ServletException(e);
+    }
+  }
+
+  protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    PrintWriter out = resp.getWriter();
+    // TODO
+    out.println("<html>");
+    out.println("<body>");
+    out.println("do put");
+    out.println("</body>");
+    out.println("</html>");
+  }
+
+  protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    try {
+      String escidocUrl = req.getParameter("escidocUrl");
+      Cookie[] cookies = req.getCookies();
+      String cookieId = getCookieValue(cookies, "escidocCookie");
+      PrintWriter out = resp.getWriter();
+      if (escidocUrl != null && escidocUrl.startsWith("/ir/item/escidoc:")) {
+        String existId = getExistDocUrl(cookieId, escidocUrl);
+        ESciDocRestSession escidocRestSession = ESciDocRestSession.getInstance(cookieId);
+        String itemId = escidocUrl;
+        escidocRestSession.deleteItem(itemId);
+        // delete eXist document
+        MpdlXmlRpcDocHandler docHandler = MpdlXmlRpcDocHandler.getInstance();
+        docHandler.deleteDocumentFile(existId);
+        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        out.println("item: ");
+        out.print(itemId);
+        out.print(" sucessfully deleted in eSciDoc and eXist");
+      } else {
+        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        out.println("<error>");
+        out.print("EsciDoc does not support your URL: " + escidocUrl);
+        out.print("</error>");
+      }
+    } catch (ApplicationException e) {
+      throw new ServletException(e);
+    }
+  }
+  
+  private void doDeleteOld(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    try {
+      String escidocUrl = req.getParameter("escidocUrl");
+      Cookie[] cookies = req.getCookies();
+      String eScidDocCookie = getCookieValue(cookies, "escidocCookie");
+      PrintWriter out = resp.getWriter();
+      if (escidocUrl != null && escidocUrl.startsWith("/ir/item")) {
+        String xQueryPath = "/mpdl/doc/rest-doc-operation.xql";
+        String existDocUrl = getExistDocUrl(eScidDocCookie, escidocUrl);
+        String strTmp = existDocUrl.substring(1);
+        int index = strTmp.indexOf("/");
+        String docBase = strTmp.substring(0, index);
+        strTmp = strTmp.substring(index + 1);
+        index = strTmp.indexOf("/");
+        String language = strTmp.substring(0, index);
+        String fileName = strTmp.substring(index + 1);
+        String xQueryParamOperation = "<param name=\"operation\">delete</param>";
+        String xQueryParamDocBase = "<param name=\"docBase\">" + docBase + "</param>";
+        String xQueryParamLanguage = "<param name=\"language\">" + language + "</param>";
+        String xQueryParamFileName = "<param name=\"fileName\">" + fileName + "</param>";
+        String xQueryParams = "<params>" + xQueryParamOperation + xQueryParamDocBase + xQueryParamLanguage + xQueryParamFileName + "</params>";
+        String xqueryResult = xqueryByPath(xQueryPath, xQueryParams, 1, 1);
+        out.print(xqueryResult);
+      } else {
+        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        out.println("<error>");
+        out.print("EsciDoc does not support your URL: " + escidocUrl);
+        out.print("</error>");
+      }
+    } catch (ApplicationException e) {
+      throw new ServletException(e);
+    }
+  }
+  
+  private String createItemInContainer(String cookieId, String containerId, String localFileName) throws ApplicationException {
+    String retItemXmlStr = null;
+    try {
+      // create item in eSciDoc
+      byte[] itemXmlBytes = FileUtil.getInstance().readBytes(localFileName);
+      String itemXmlStr = new String(itemXmlBytes, "utf-8");
+      ESciDocRestSession escidocRestSession = ESciDocRestSession.getInstance(cookieId);
+      Item retItem = escidocRestSession.createItemInContainer(containerId, itemXmlStr);
+      retItemXmlStr = retItem.toXmlString();
+      // create/update eXist document
+      MpdlXmlRpcDocHandler docHandler = MpdlXmlRpcDocHandler.getInstance();
+      String existId = escidocRestSession.getFirstEXistId(itemXmlStr);
+      String componentContentId = escidocRestSession.getFirstComponentId(retItemXmlStr);
+      File tmpUploadExistFile = File.createTempFile("exist", ".xml", new File(FILE_UPLOAD_TEMP_DIRECTORY));
+      String tmpUploadExistFileName = tmpUploadExistFile.getPath();
+      escidocRestSession.saveComponentContentToLocalFile(componentContentId, tmpUploadExistFileName); 
+      docHandler.saveDocumentFile(tmpUploadExistFileName, existId);
+      FileUtil.getInstance().deleteFile(localFileName);
+      FileUtil.getInstance().deleteFile(tmpUploadExistFileName);
+    } catch (Exception e) {
+      throw new ApplicationException(e);      
+    }
+    return retItemXmlStr;
+  }
+  
+  private String getExistDocUrl(String cookieId, String escidocUrl) throws ApplicationException {
+    ESciDocRestSession escidocRestSession = ESciDocRestSession.getInstance(cookieId);
+    String itemId = getESciDocItemId(escidocUrl);
+    String itemXmlStr = escidocRestSession.getItem(itemId);
+    String existDocUrl = getEXistDocUrl(itemXmlStr);
+    return existDocUrl;
+  }
+  
+  private String xquery(String queryType, String xQuery, String xmlParameters, int startRecord, int maximumRecords) throws ApplicationException {
+    String xQueryMethod = "/mpdl/interface/xquery.xql";
+    String xQueryPath = "";
+    String xqueryResult = null;
+    if (queryType.equals("uri")) {
+      xQueryPath = xQuery;
+      xqueryResult = xqueryByPath(xQueryPath, xmlParameters, startRecord, maximumRecords);
+    } else if (queryType.equals("string")) {
+      xQueryPath = xQueryMethod;
+      String paramXQuery = "<param name=\"xquery\">" + xQuery + "</param>";
+      String params = "<params>" + paramXQuery + "</params>";
+      if (xmlParameters != null) {
+        int index = xmlParameters.indexOf("</params>");
+        params = xmlParameters.substring(0, index) + paramXQuery + xmlParameters.substring(index);
+      }
+      xqueryResult = xqueryByPath(xQueryPath, params, startRecord, maximumRecords);
+    }
+    return xqueryResult;
+  }
+  
+  private String xqueryByPath(String xQueryPath, String xmlParameters, int startRecord, int maximumRecords) throws ApplicationException {
+    String requestName = xQueryPath;
+    String parameters = getUrlStringByXmlParams(xmlParameters);
+    if (parameters != null && ! parameters.equals("")) {
+      if (startRecord != -1)
+        parameters = parameters + "&startRecord=" + startRecord;
+      if (maximumRecords != -1)
+        parameters = parameters + "&maximumRecords=" + maximumRecords;
+      requestName = requestName + "?" + parameters;
+    } 
+    String xqueryResult = performGetRequest(requestName, null);
+    return xqueryResult;
+  }
+  
+  private String getUrlStringByXmlParams(String xmlParameters) throws ApplicationException {
+    String parameters = "";
+    if (xmlParameters != null) {
+      XmlUtil xmlUtil = XmlUtil.getInstance();
+      ArrayList<String> paramNames = xmlUtil.evaluateToStringArray(xmlParameters, "//param/@name", null);
+      ArrayList<String> paramValues = xmlUtil.evaluateToStringArray(xmlParameters, "//param", null);
+      int size = paramValues.size();
+      for (int i=0; i<size; i++) {
+        String paramName = paramNames.get(i);
+        String paramValue = paramValues.get(i);
+        String paramValueEncoded = encode(paramValue);
+        parameters = parameters + paramName + "=" + paramValueEncoded + "&";
+      }
+      parameters = parameters.substring(0, parameters.length() - 1); // without last "&"
+    }
+    return parameters;    
+  }
+  
+  private String getEXistDocUrl(String itemXmlStr) throws ApplicationException {
+    String retStr = null;
+    if (itemXmlStr != null) {
+      ESciDocRestSession escidocRestSession = ESciDocRestSession.getInstance(null);
+      retStr = escidocRestSession.getFirstEXistId(itemXmlStr);
+    }
+    return retStr;    
+  }
+  
+  private String getESciDocContainerId(String escidocUrl) {
+    String retStr = null;
+    int index = escidocUrl.indexOf("/ir/container/escidoc:");
+    int indexNum = index + 22;
+    int indexNext = escidocUrl.indexOf("/", indexNum);
+    if (indexNext == -1)
+      indexNext = escidocUrl.length();
+    retStr = escidocUrl.substring(index, indexNext);
+    return retStr;
+  }
+  
+  private String getESciDocItemId(String escidocUrl) {
+    String retStr = null;
+    int index = escidocUrl.indexOf("/ir/item/escidoc:");
+    int indexNum = index + 17;
+    int indexNext = escidocUrl.indexOf("/", indexNum);
+    if (indexNext == -1)
+      indexNext = escidocUrl.length();
+    retStr = escidocUrl.substring(index, indexNext);
+    return retStr;
+  }
+  
+  private String encode(String str) throws ApplicationException {
+    String retStr = null;
+    try {
+      retStr = URLEncoder.encode(str, "utf-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new ApplicationException(e);      
+    }
+    return retStr;    
+  }
+
+  private String getCookieValue(Cookie[] cookies, String name) {
+    String value = null;
+    for (int i=0; i<cookies.length; i++) {
+      Cookie c = cookies[i];
+      String n = c.getName();
+      if (n.equals(name)) {
+        value = c.getValue();
+        break;
+      }
+    }
+    return value;
+  }
+  
+  private String performGetRequest(String requestName, String cookieId) throws ApplicationException {
+    String resultStr = "";
+    try {
+      String urlStr = "http://" + MpdlConstants.MPDL_EXIST_HOST_NAME + ":" + MpdlConstants.MPDL_EXIST_PORT + requestName;
+      GetMethod method = new GetMethod(urlStr);
+      if (cookieId != null)
+        method.setRequestHeader("Cookie", cookieId);
+      HttpClient httpClient = new HttpClient();
+      httpClient.executeMethod(method);
+      byte[] responseBody = method.getResponseBody();
+      resultStr = new String(responseBody, "utf-8");
+      method.releaseConnection();
+    } catch (HttpException e) {
+      throw new ApplicationException(e);      
+    } catch (IOException e) {
+      throw new ApplicationException(e);      
+    }
+    return resultStr;
+  } 
+  
+}
\ No newline at end of file