Advertisement
tko_pb

JsonRestServlet.java

Nov 16th, 2018
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.37 KB | None | 0 0
  1. /*
  2.  *************************************************************************
  3.  * The contents of this file are subject to the Openbravo  Public  License
  4.  * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
  5.  * Version 1.1  with a permitted attribution clause; you may not  use this
  6.  * file except in compliance with the License. You  may  obtain  a copy of
  7.  * the License at http://www.openbravo.com/legal/license.html
  8.  * Software distributed under the License  is  distributed  on  an "AS IS"
  9.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  10.  * License for the specific  language  governing  rights  and  limitations
  11.  * under the License.
  12.  * The Original Code is Openbravo ERP.
  13.  * The Initial Developer of the Original Code is Openbravo SLU
  14.  * All portions are Copyright (C) 2009-2015 Openbravo SLU
  15.  * All Rights Reserved.
  16.  * Contributor(s):  ______________________________________.
  17.  ************************************************************************
  18.  */
  19. package org.openbravo.service.json;
  20.  
  21. import java.io.BufferedReader;
  22. import java.io.IOException;
  23. import java.io.PrintWriter;
  24. import java.io.Writer;
  25. import java.util.Enumeration;
  26. import java.util.HashMap;
  27. import java.util.Map;
  28.  
  29. import javax.servlet.ServletConfig;
  30. import javax.servlet.ServletException;
  31. import javax.servlet.http.HttpServletRequest;
  32. import javax.servlet.http.HttpServletResponse;
  33.  
  34. import org.apache.log4j.Logger;
  35. import org.codehaus.jettison.json.JSONArray;
  36. import org.codehaus.jettison.json.JSONException;
  37. import org.codehaus.jettison.json.JSONObject;
  38. import org.openbravo.base.exception.OBSecurityException;
  39. import org.openbravo.base.model.ModelProvider;
  40. import org.openbravo.base.secureApp.ClassInfoData;
  41. import org.openbravo.base.secureApp.HttpSecureAppServlet;
  42. import org.openbravo.base.secureApp.VariablesSecureApp;
  43. import org.openbravo.base.structure.BaseOBObject;
  44. import org.openbravo.base.util.CheckException;
  45. import org.openbravo.dal.core.OBContext;
  46. import org.openbravo.dal.core.SessionHandler;
  47. import org.openbravo.dal.service.OBDal;
  48. import org.openbravo.database.SessionInfo;
  49. import org.openbravo.service.web.BaseWebServiceServlet;
  50. import org.openbravo.service.web.InvalidContentException;
  51. import org.openbravo.service.web.InvalidRequestException;
  52. import org.openbravo.service.web.ResourceNotFoundException;
  53. import org.openbravo.service.web.WebServiceUtil;
  54.  
  55. /**
  56.  * A web service which provides a JSON REST service. Makes extensive use of the
  57.  * {@link DefaultJsonDataService}.
  58.  *
  59.  * @author mtaal
  60.  */
  61.  
  62. public class JsonRestServlet extends BaseWebServiceServlet {
  63.   private static final Logger log = Logger.getLogger(JsonRestServlet.class);
  64.  
  65.   private static final long serialVersionUID = 1L;
  66.  
  67.   protected ClassInfoData classInfo;
  68.  
  69.   private static String servletPathPart = "org.openbravo.service.json.jsonrest";
  70.  
  71.   public static String getServletPathPart() {
  72.     return servletPathPart;
  73.   }
  74.  
  75.   @Override
  76.   public void init(ServletConfig config) throws ServletException {
  77.     if (config.getInitParameter(JsonConstants.JSON_REST_URL_NAME_PARAM) != null) {
  78.       servletPathPart = config.getInitParameter(JsonConstants.JSON_REST_URL_NAME_PARAM);
  79.     }
  80.     super.init(config);
  81.   }
  82.  
  83.  
  84.   protected void doService(HttpServletRequest request, HttpServletResponse response)
  85.       throws ServletException, IOException {
  86.     try {
  87.       if (OBContext.getOBContext() != null) {
  88.         if (OBContext.getOBContext().isPortalRole()) {
  89.           // Portal users are not granted to direct web services
  90.           log.error("Portal user " + OBContext.getOBContext().getUser() + " with role "
  91.               + OBContext.getOBContext().getRole()
  92.               + " is trying to access to non granted web service " + request.getRequestURL());
  93.           throw new OBSecurityException("Web Services are not granted to Portal roles");
  94.         } else if (!OBContext.getOBContext().isWebServiceEnabled()) {
  95.           log.error("User " + OBContext.getOBContext().getUser() + " with role "
  96.               + OBContext.getOBContext().getRole()
  97.               + " is trying to access to non granted web service " + request.getRequestURL());
  98.           throw new OBSecurityException("Web Services are not granted to "
  99.               + OBContext.getOBContext().getRole() + " role");
  100.         }
  101.       }
  102.       callServiceInSuper(request, response);
  103.       response.setStatus(200);
  104.     } catch (final InvalidRequestException e) {
  105.       SessionHandler.getInstance().setDoRollback(true);
  106.       response.setStatus(400);
  107.       log.error(e.getMessage(), e);
  108.       writeResult(response, JsonUtils.convertExceptionToJson(e));
  109.     } catch (final InvalidContentException e) {
  110.       SessionHandler.getInstance().setDoRollback(true);
  111.       response.setStatus(409);
  112.       log.error(e.getMessage(), e);
  113.       writeResult(response, JsonUtils.convertExceptionToJson(e));
  114.     } catch (final ResourceNotFoundException e) {
  115.       SessionHandler.getInstance().setDoRollback(true);
  116.       response.setStatus(404);
  117.       log.error(e.getMessage(), e);
  118.       writeResult(response, JsonUtils.convertExceptionToJson(e));
  119.     } catch (final OBSecurityException e) {
  120.       SessionHandler.getInstance().setDoRollback(true);
  121.       response.setStatus(401);
  122.       log.error(e.getMessage(), e);
  123.       writeResult(response, JsonUtils.convertExceptionToJson(e));
  124.     } catch (final Throwable t) {
  125.       SessionHandler.getInstance().setDoRollback(true);
  126.       response.setStatus(500);
  127.       log.error(t.getMessage(), t);
  128.       writeResult(response, JsonUtils.convertExceptionToJson(t));
  129.     }
  130.   }
  131.  
  132.  
  133.   @Override
  134.   public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException,
  135.       ServletException {
  136.  
  137.     try {
  138.       final Map<String, String> parameters = getParameterMap(request);
  139.       // checks and set parameters, if not valid then go away
  140.       if (!checkSetParameters(request, response, parameters)) {
  141.         return;
  142.       }
  143.       SessionInfo.setQueryProfile("jsonWebService");
  144.       // now do the action
  145.  
  146.       // a special case if the id is asked directly then only return the single record.
  147.       if (parameters.containsKey(JsonConstants.ID)) {
  148.         String result = DefaultJsonDataService.getInstance().fetch(parameters);
  149.         final JSONObject jsonObject = new JSONObject(result);
  150.         final JSONObject responseObject = jsonObject.getJSONObject(JsonConstants.RESPONSE_RESPONSE);
  151.         if (responseObject.get(JsonConstants.DATA) instanceof JSONArray) {
  152.           final JSONArray jsonArray = responseObject.getJSONArray(JsonConstants.DATA);
  153.           if (jsonArray.length() == 0) {
  154.             throw new ResourceNotFoundException("Object (" + parameters.get(JsonConstants.ID) + "/"
  155.                 + parameters.get(JsonConstants.ENTITYNAME) + ") not found");
  156.           } else if (jsonArray.length() == 1) {
  157.             result = jsonArray.getJSONObject(0).toString();
  158.           }
  159.         } else {
  160.           final JSONObject jsonDataObject = responseObject.getJSONObject(JsonConstants.DATA);
  161.           result = jsonDataObject.toString();
  162.         }
  163.         writeResult(response, result);
  164.       } else {
  165.         JSONStreamWriter writer = new JSONStreamWriter(response, parameters);
  166.         parameters.put(JsonConstants.USE_ALIAS, "true");
  167.         parameters.put(JsonConstants.IS_WS_CALL, "true");
  168.         parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE,
  169.             parameters.get(JsonConstants.WHERE_PARAMETER));
  170.         DefaultJsonDataService.getInstance().fetch(parameters, writer);
  171.         writer.close();
  172.       }
  173.  
  174.     } catch (final JSONException e) {
  175.       throw new InvalidContentException(e);
  176.     }
  177.   }
  178.  
  179.   @Override
  180.   public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException,
  181.       ServletException {
  182.     final Map<String, String> parameters = getParameterMap(request);
  183.    
  184.     //write session for audit trial
  185.     final VariablesSecureApp vars1 = new VariablesSecureApp(request, false);
  186.     SessionInfo.setUserId(OBContext.getOBContext().getUser().getId());
  187.     SessionInfo.setSessionId(vars1.getSessionValue("#AD_Session_Track"));
  188.    
  189.   //set process id ant process type
  190.     SessionInfo.setProcessType("oez_API");
  191.     SessionInfo.setProcessId("oez_API");
  192.    
  193.     // note if clause updates parameter map
  194.     if (checkSetIDEntityName(request, response, parameters)) {
  195.       final String result = DefaultJsonDataService.getInstance().add(parameters,
  196.           getRequestContent(request));
  197.       writeResult(response, result);
  198.     }
  199.   }
  200.  
  201.   @Override
  202.   public void doDelete(HttpServletRequest request, HttpServletResponse response)
  203.       throws IOException, ServletException {
  204.     final Map<String, String> parameters = getParameterMap(request);
  205.     // checks and set parameters, if not valid then go away
  206.     if (!checkSetParameters(request, response, parameters)) {
  207.       return;
  208.     }
  209.     final String id = parameters.get(JsonConstants.ID);
  210.     if (id == null) {
  211.       throw new InvalidRequestException("No id parameter");
  212.     }
  213.     final String entityName = parameters.get(JsonConstants.ENTITYNAME);
  214.     if (entityName == null) {
  215.       throw new InvalidRequestException("No entityName parameter");
  216.     }
  217.     final BaseOBObject bob = OBDal.getInstance().get(entityName, id);
  218.     if (bob == null) {
  219.       throw new ResourceNotFoundException("Object (" + id + "/" + entityName + ") not found");
  220.     }
  221.  
  222.     // now do the action
  223.     final String result = DefaultJsonDataService.getInstance().remove(parameters);
  224.     writeResult(response, result);
  225.   }
  226.  
  227.   @Override
  228.   public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException,
  229.       ServletException {
  230.     final Map<String, String> parameters = getParameterMap(request);
  231.     // note if clause updates parameter map
  232.     if (checkSetIDEntityName(request, response, parameters)) {
  233.       final String result = DefaultJsonDataService.getInstance().update(parameters,
  234.           getRequestContent(request));
  235.       writeResult(response, result);
  236.     }
  237.   }
  238.  
  239.   private boolean checkSetParameters(HttpServletRequest request, HttpServletResponse response,
  240.       Map<String, String> parameters) throws IOException {
  241.     if (!request.getRequestURI().contains("/" + servletPathPart)) {
  242.       writeResult(response, JsonUtils.convertExceptionToJson(new InvalidRequestException(
  243.           "Invalid url, the path should contain the service name: " + servletPathPart)));
  244.       return false;
  245.     }
  246.     final int nameIndex = request.getRequestURI().indexOf(servletPathPart);
  247.     final String servicePart = request.getRequestURI().substring(nameIndex);
  248.     final String[] pathParts = WebServiceUtil.getInstance().getSegments(servicePart);
  249.     if (pathParts.length == 0 || !pathParts[0].equals(servletPathPart)) {
  250.       writeResult(
  251.           response,
  252.           JsonUtils.convertExceptionToJson(new InvalidRequestException("Invalid url: "
  253.               + request.getRequestURI())));
  254.       return false;
  255.     }
  256.     if (pathParts.length == 1) {
  257.       writeResult(response, JsonUtils.convertExceptionToJson(new InvalidRequestException(
  258.           "Invalid url, no entityName: " + request.getRequestURI())));
  259.       return false;
  260.     }
  261.     final String entityName = pathParts[1];
  262.     // check it the entity
  263.     try {
  264.       ModelProvider.getInstance().getEntity(entityName);
  265.     } catch (CheckException e) {
  266.       writeResult(response, JsonUtils.convertExceptionToJson(new InvalidRequestException(
  267.           "Invalid url, no entity found with entityName: " + request.getRequestURI())));
  268.       return false;
  269.     }
  270.     parameters.put(JsonConstants.ENTITYNAME, entityName);
  271.     if (pathParts.length > 2) {
  272.       // search on the exact id
  273.       parameters.put(JsonConstants.ID, pathParts[2]);
  274.       if (!parameters.containsKey(JsonConstants.TEXTMATCH_PARAMETER)) {
  275.         parameters.put(JsonConstants.TEXTMATCH_PARAMETER, JsonConstants.TEXTMATCH_EXACT);
  276.         parameters.put(JsonConstants.TEXTMATCH_PARAMETER_OVERRIDE, JsonConstants.TEXTMATCH_EXACT);
  277.       }
  278.     }
  279.     return true;
  280.   }
  281.  
  282.   private Map<String, String> getParameterMap(HttpServletRequest request) {
  283.     final Map<String, String> parameterMap = new HashMap<String, String>();
  284.     for (@SuppressWarnings("rawtypes")
  285.     Enumeration keys = request.getParameterNames(); keys.hasMoreElements();) {
  286.       final String key = (String) keys.nextElement();
  287.       parameterMap.put(key, request.getParameter(key));
  288.     }
  289.     return parameterMap;
  290.   }
  291.  
  292.   // NOTE: parameters parameter is updated inside this method
  293.   private boolean checkSetIDEntityName(HttpServletRequest request, HttpServletResponse response,
  294.       Map<String, String> parameters) throws IOException {
  295.     if (!request.getRequestURI().contains("/" + servletPathPart)) {
  296.       writeResult(response, JsonUtils.convertExceptionToJson(new InvalidRequestException(
  297.           "Invalid url, the path should contain the service name: " + servletPathPart)));
  298.       return false;
  299.     }
  300.     final int nameIndex = request.getRequestURI().indexOf(servletPathPart);
  301.     final String servicePart = request.getRequestURI().substring(nameIndex);
  302.     final String[] pathParts = WebServiceUtil.getInstance().getSegments(servicePart);
  303.     if (pathParts.length == 0 || !pathParts[0].equals(servletPathPart)) {
  304.       writeResult(
  305.           response,
  306.           JsonUtils.convertExceptionToJson(new InvalidRequestException("Invalid url: "
  307.               + request.getRequestURI())));
  308.       return false;
  309.     }
  310.     if (pathParts.length == 1) {
  311.       return true;
  312.     }
  313.     final String entityName = pathParts[1];
  314.     // check it the entity
  315.     try {
  316.       ModelProvider.getInstance().getEntity(entityName);
  317.     } catch (CheckException e) {
  318.       writeResult(response, JsonUtils.convertExceptionToJson(new InvalidRequestException(
  319.           "Invalid url, no entity found with entityName: " + request.getRequestURI())));
  320.       return false;
  321.     }
  322.     parameters.put(JsonConstants.ENTITYNAME, entityName);
  323.     if (pathParts.length > 2) {
  324.       // search on the exact id
  325.       parameters.put(JsonConstants.ID, pathParts[2]);
  326.       if (!parameters.containsKey(JsonConstants.TEXTMATCH_PARAMETER)) {
  327.         parameters.put(JsonConstants.TEXTMATCH_PARAMETER, JsonConstants.TEXTMATCH_EXACT);
  328.         parameters.put(JsonConstants.TEXTMATCH_PARAMETER_OVERRIDE, JsonConstants.TEXTMATCH_EXACT);
  329.       }
  330.     }
  331.     return true;
  332.   }
  333.  
  334.   private void writeResult(HttpServletResponse response, String result) throws IOException {
  335.     response.setContentType("application/json;charset=UTF-8");
  336.     response.setHeader("Content-Type", "application/json;charset=UTF-8");
  337.  
  338.     final Writer w = response.getWriter();
  339.     w.write(result);
  340.     w.close();
  341.   }
  342.  
  343.   private String getRequestContent(HttpServletRequest request) throws IOException {
  344.     final BufferedReader reader = request.getReader();
  345.     if (reader == null) {
  346.       return "";
  347.     }
  348.     String line;
  349.     final StringBuilder sb = new StringBuilder();
  350.     while ((line = reader.readLine()) != null) {
  351.       if (sb.length() > 0) {
  352.         sb.append("\n");
  353.       }
  354.       sb.append(line);
  355.     }
  356.     log.debug("REQUEST CONTENT>>>>");
  357.     log.debug(sb.toString());
  358.     return sb.toString();
  359.   }
  360.  
  361.   /**
  362.    * Helper class to write JSON results streaming them directly into the response PrintWriter
  363.    *
  364.    * @author alostale
  365.    *
  366.    */
  367.   private class JSONStreamWriter extends DefaultJsonDataService.QueryResultWriter {
  368.     PrintWriter writer;
  369.     int lines = 0;
  370.     int startRow = 0;
  371.     int endRow = -1;
  372.     int computedMaxResults = Integer.MAX_VALUE;
  373.     boolean limitReached = false;
  374.  
  375.     public JSONStreamWriter(HttpServletResponse response, Map<String, String> parameters)
  376.         throws IOException {
  377.  
  378.       if (parameters.containsKey(JsonConstants.ENDROW_PARAMETER)) {
  379.         endRow = Integer.valueOf(parameters.get(JsonConstants.ENDROW_PARAMETER));
  380.       }
  381.  
  382.       if (parameters.containsKey(JsonConstants.STARTROW_PARAMETER)) {
  383.         startRow = Integer.valueOf(parameters.get(JsonConstants.STARTROW_PARAMETER));
  384.         computedMaxResults = endRow - startRow + 1;
  385.       }
  386.       response.setCharacterEncoding("UTF-8");
  387.       writer = response.getWriter();
  388.  
  389.       response.setContentType("application/json;charset=UTF-8");
  390.       response.setHeader("Content-Type", "application/json;charset=UTF-8");
  391.  
  392.       writer.write("{\"" + JsonConstants.RESPONSE_RESPONSE + "\":{\"" + JsonConstants.RESPONSE_DATA
  393.           + "\":[");
  394.     }
  395.  
  396.     @Override
  397.     public void write(JSONObject json) {
  398.       try {
  399.         lines += 1;
  400.         if (lines >= computedMaxResults) {
  401.           limitReached = true;
  402.           return;
  403.         }
  404.         if (lines > 1) {
  405.           writer.write(",");
  406.         }
  407.         writer.write(json.toString());
  408.       } catch (Exception e) {
  409.         log.error("Error writing json ws response", e);
  410.       }
  411.     }
  412.  
  413.     public void close() throws IOException {
  414.       writer.write("]");
  415.       writer.write(",\"" + JsonConstants.RESPONSE_STATUS + "\":"
  416.           + JsonConstants.RPCREQUEST_STATUS_SUCCESS);
  417.       writer.write(",\"" + JsonConstants.RESPONSE_TOTALROWS + "\":"
  418.           + (lines + (limitReached ? 1 : 0)));
  419.       if (startRow != -1) {
  420.         writer.write(",\"" + JsonConstants.RESPONSE_STARTROW + "\":" + startRow);
  421.       }
  422.  
  423.       writer.write(",\"" + JsonConstants.RESPONSE_ENDROW + "\":" + (startRow + lines - 1));
  424.  
  425.       writer.write("}}");
  426.       writer.close();
  427.     }
  428.   }
  429. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement