Mercurial > hg > mpdl-group
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