details: https://code.openbravo.com/erp/devel/pi/rev/4802bbc88730 changeset: 35639:4802bbc88730 user: Asier Lostalé <asier.lostale <at> openbravo.com> date: Fri Apr 05 13:40:57 2019 +0200 summary: fixes 40535: old callouts should use OBScriptEngine to evaluate response
diffstat: modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java | 61 +--- src-test/src/org/openbravo/test/AllAntTaskTests.java | 2 + src-test/src/org/openbravo/test/system/OldCallouts.java | 116 ++++++++ src/org/openbravo/erpCommon/ad_callouts/HttpServletCalloutInformationProvider.java | 132 +++++++-- 4 files changed, 229 insertions(+), 82 deletions(-) diffs (truncated from 487 to 300 lines): diff -r 51521741bf55 -r 4802bbc88730 modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java --- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java Fri Apr 05 14:35:00 2019 +0200 +++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java Fri Apr 05 13:40:57 2019 +0200 @@ -11,7 +11,7 @@ * under the License. * The Original Code is Openbravo ERP. * The Initial Developer of the Original Code is Openbravo SLU - * All portions are Copyright (C) 2010-2018 Openbravo SLU + * All portions are Copyright (C) 2010-2019 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************ @@ -35,15 +35,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.hibernate.criterion.Restrictions; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.NativeArray; -import org.mozilla.javascript.Scriptable; import org.openbravo.base.exception.OBException; import org.openbravo.base.model.Entity; import org.openbravo.base.model.ModelProvider; @@ -1481,9 +1479,9 @@ } if (!(calloutObject instanceof HttpServlet) && !(calloutObject instanceof SimpleCallout)) { - log.info("Callout " + calloutClassName - + " only allows reference instances of type SimpleCallout and HttpServlet but the callout is an instance of " - + calloutObject.getClass().getName()); + log.info( + "Callout {} only allows reference instances of type SimpleCallout and HttpServlet but the callout is an instance of {}", + calloutClassName, calloutObject.getClass().getName()); continue; } @@ -1509,7 +1507,9 @@ calloutResponseManager = new SimpleCalloutInformationProvider(result); } else { - // We then execute the callout + log.debug( + "Callout {} executed in tab {} does not implement SimpleCallout. This is deprecated, consider reimplementing it.", + calloutClassName, tab); HttpServlet calloutInstance = (HttpServlet) calloutObject; CalloutHttpServletResponse fakeResponse = new CalloutHttpServletResponse( request.getResponse()); @@ -1517,7 +1517,6 @@ if (isCalloutInitialized) { Method doPost = calloutClass.getMethod("doPost", HttpServletRequest.class, HttpServletResponse.class); - doPost.setAccessible(true); doPost.invoke(calloutInstance, request.getRequest(), fakeResponse); } else { calloutInstance.init(config); @@ -1525,18 +1524,19 @@ } String calloutResponse = fakeResponse.getOutputFromWriter(); - // Now we parse the callout response and modify the stored values of the columns modified - // by the callout - ArrayList<NativeArray> returnedArray = new ArrayList<NativeArray>(); - String calloutNameJS = parseCalloutResponse(calloutResponse, returnedArray); - if (calloutNameJS != null && calloutNameJS != "") { + + HttpServletCalloutInformationProvider httpCalloutManager = new HttpServletCalloutInformationProvider( + calloutResponse); + httpCalloutManager.parseResponse(); + String calloutNameJS = httpCalloutManager.getCalloutName(); + if (StringUtils.isNotBlank(calloutClassName)) { calledCallouts.add(calloutNameJS); } - calloutResponseManager = new HttpServletCalloutInformationProvider(returnedArray); + calloutResponseManager = httpCalloutManager; } - managesUpdatedValuesForCallout(columnValues, tab, calloutsToCall, lastfieldChangedList, + manageUpdatedValuesForCallout(columnValues, tab, calloutsToCall, lastfieldChangedList, messages, dynamicCols, jsExecuteCode, hiddenInputs, overwrittenAuxiliaryInputs, changedCols, inpFields, calloutClassName, request, calloutResponseManager); @@ -1553,7 +1553,7 @@ } - private void managesUpdatedValuesForCallout(Map<String, JSONObject> columnValues, Tab tab, + private void manageUpdatedValuesForCallout(Map<String, JSONObject> columnValues, Tab tab, List<String> calloutsToCall, List<String> lastfieldChangedList, List<JSONObject> messages, List<String> dynamicCols, List<String> jsExecuteCode, Map<String, Object> hiddenInputs, List<String> overwrittenAuxiliaryInputs, List<String> changedCols, @@ -1561,7 +1561,7 @@ CalloutInformationProvider calloutInformationProvider) throws JSONException { Object element = calloutInformationProvider.getNextElement(); while (element != null) { - String name = (String) calloutInformationProvider.getCurrentElementName(); + String name = calloutInformationProvider.getCurrentElementName(); if (name.equals("MESSAGE") || name.equals("INFO") || name.equals("WARNING") || name.equals("ERROR") || name.equals("SUCCESS")) { log.debug("Callout message: " + calloutInformationProvider.getCurrentElementValue(element)); @@ -1725,31 +1725,6 @@ } } - private String parseCalloutResponse(String calloutResponse, List<NativeArray> returnedArray) { - String initS = "id=\"paramArray\">"; - String resp = calloutResponse.substring(calloutResponse.indexOf(initS) + initS.length()); - resp = resp.substring(0, resp.indexOf("</SCRIPT")).trim(); - if (!resp.contains("new Array(") && !resp.contains("[[")) { - return null; - } - try { - Context cx = Context.enter(); - Scriptable scope = cx.initStandardObjects(); - cx.evaluateString(scope, resp, "<cmd>", 1, null); - NativeArray array = (NativeArray) scope.get("respuesta", scope); - Object calloutName = scope.get("calloutName", scope); - String calloutNameS = calloutName == null ? null : calloutName.toString(); - log.debug("Callout Name: " + calloutNameS); - for (int i = 0; i < array.getLength(); i++) { - returnedArray.add((NativeArray) array.get(i, null)); - } - return calloutNameS; - } catch (Exception e) { - log.error("Couldn't parse callout response. The parsed response was: " + resp, e); - } - return null; - } - private String pickDependantColumn(List<String> sortedColumns, List<String> columns, Map<String, List<String>> columnsInValidation) { for (String col : columns) { diff -r 51521741bf55 -r 4802bbc88730 src-test/src/org/openbravo/test/AllAntTaskTests.java --- a/src-test/src/org/openbravo/test/AllAntTaskTests.java Fri Apr 05 14:35:00 2019 +0200 +++ b/src-test/src/org/openbravo/test/AllAntTaskTests.java Fri Apr 05 13:40:57 2019 +0200 @@ -116,6 +116,7 @@ import org.openbravo.test.system.ImportEntryBuilderTest; import org.openbravo.test.system.ImportEntrySizeTest; import org.openbravo.test.system.Issue29934Test; +import org.openbravo.test.system.OldCallouts; import org.openbravo.test.system.Sessions; import org.openbravo.test.system.SystemServiceTest; import org.openbravo.test.system.SystemValidatorTest; @@ -217,6 +218,7 @@ CryptoUtilities.class, // Sessions.class, // OBContextTest.class, // + OldCallouts.class, // // xml ClientExportImportTest.class, // diff -r 51521741bf55 -r 4802bbc88730 src-test/src/org/openbravo/test/system/OldCallouts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src-test/src/org/openbravo/test/system/OldCallouts.java Fri Apr 05 13:40:57 2019 +0200 @@ -0,0 +1,116 @@ +/* + ************************************************************************* + * The contents of this file are subject to the Openbravo Public License + * Version 1.1 (the "License"), being the Mozilla Public License + * Version 1.1 with a permitted attribution clause; you may not use this + * file except in compliance with the License. You may obtain a copy of + * the License at http://www.openbravo.com/legal/license.html + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * The Original Code is Openbravo ERP. + * The Initial Developer of the Original Code is Openbravo SLU + * All portions are Copyright (C) 2019 Openbravo SLU + * All Rights Reserved. + * Contributor(s): ______________________________________. + ************************************************************************ + */ + +package org.openbravo.test.system; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.junit.Test; +import org.openbravo.dal.core.OBContext; +import org.openbravo.dal.service.OBDal; +import org.openbravo.erpCommon.ad_callouts.HttpServletCalloutInformationProvider; +import org.openbravo.erpCommon.ad_callouts.SimpleCallout; +import org.openbravo.model.ad.datamodel.Column; +import org.openbravo.test.base.OBBaseTest; + +/** + * Tests it is possible to correctly parse response of old callouts that do not extend + * {@link SimpleCallout} but implement Servlet instead. + */ +public class OldCallouts extends OBBaseTest { + + @Test + public void shouldBeCorrectlyParsed() throws JSONException { + //@formatter:off + String calloutRawResponse = "<HTML>\n" + + "<HEAD>\n" + + "<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></META>\n" + + "<TITLE></TITLE>\n" + + "<LINK rel=\"shortcut icon\" href=\"web/images/favicon.ico\" type=\"image/x-icon\"></LINK>\n" + + "<SCRIPT language=\"JavaScript\" type=\"text/javascript\" src=\"web/js/error.js\"></SCRIPT>\n" + + "<SCRIPT language=\"JavaScript\" type=\"text/javascript\" src=\"web/js/callOut.js\"></SCRIPT>\n" + + "<SCRIPT language=\"JavaScript\" type=\"text/javascript\" id=\"paramArray\">var calloutName='SL_Order_DocType';\n" + + "\n" + + "var respuesta = new Array(new Array(\"inpordertype\", \"SO\")\n" + + ", new Array(\"inpdocumentno\", \"<1000257>\")\n" + + ", new Array(\"inpinvoicerule\", new Array(new Array(\"D\", \"After Delivery\", \"true\"),\n" + + "new Array(\"O\", \"After Order Delivered\", \"false\"),\n" + + "new Array(\"S\", \"Customer Schedule After Delivery\", \"false\"),\n" + + "new Array(\"N\", \"Do Not Invoice\", \"false\"),\n" + + "new Array(\"I\", \"Immediate\", \"false\"))), new Array(\"inppaymentrule\", \"P\")\n" + + ", new Array(\"EXECUTE\", \"displayLogic();\")\n" + + ");</SCRIPT></HEAD>\n" + + "<BODY bgcolor=\"#FFFFFF\" onload=\"setgWaitingCallOut(false, '');returnResponse(respuesta, calloutName, 'appFrame');\" id=\"paramFrameName\">Call out response page</BODY></HTML>"; + //@formatter:on + + HttpServletCalloutInformationProvider calloutExecutor = new HttpServletCalloutInformationProvider( + calloutRawResponse); + calloutExecutor.parseResponse(); + assertThat("callout name", calloutExecutor.getCalloutName(), is("SL_Order_DocType")); + + Object element = calloutExecutor.getNextElement(); + String elementName = calloutExecutor.getCurrentElementName(); + assertThat("Element name", elementName, is("inpordertype")); + assertThat(elementName + " value", calloutExecutor.getCurrentElementValue(element), is("SO")); + + element = calloutExecutor.getNextElement(); + elementName = calloutExecutor.getCurrentElementName(); + assertThat("Element name", elementName, is("inpdocumentno")); + assertThat(elementName + " value", calloutExecutor.getCurrentElementValue(element), + is("<1000257>")); + + element = calloutExecutor.getNextElement(); + elementName = calloutExecutor.getCurrentElementName(); + assertThat("Element name", elementName, is("inpinvoicerule")); + + Map<String, JSONObject> columnValues = new HashMap<>(); + List<String> dynamicCols = new ArrayList<>(); + + List<String> changedCols = new ArrayList<>(); + + OBContext.setAdminMode(); + try { + Column col = OBDal.getInstance().get(Column.class, "4019"); + + calloutExecutor.manageComboData(columnValues, dynamicCols, changedCols, null, element, col, + "myColumn"); + } finally { + OBContext.restorePreviousMode(); + } + + JSONObject colValue = columnValues.get("myColumn"); + assertThat("combo value", colValue.getString("value"), is("D")); + JSONArray entries = colValue.getJSONArray("entries"); + assertThat("combo elements", entries.length(), is(5)); + + JSONObject firstComboElement = entries.getJSONObject(0); + assertThat("first combo entry value", firstComboElement.getString("id"), is("D")); + assertThat("first combo entry identifier", firstComboElement.getString("_identifier"), + is("After Delivery")); + } +} diff -r 51521741bf55 -r 4802bbc88730 src/org/openbravo/erpCommon/ad_callouts/HttpServletCalloutInformationProvider.java --- a/src/org/openbravo/erpCommon/ad_callouts/HttpServletCalloutInformationProvider.java Fri Apr 05 14:35:00 2019 +0200 +++ b/src/org/openbravo/erpCommon/ad_callouts/HttpServletCalloutInformationProvider.java Fri Apr 05 13:40:57 2019 +0200 @@ -11,7 +11,7 @@ * under the License. * The Original Code is Openbravo ERP. * The Initial Developer of the Original Code is Openbravo SLU - * All portions are Copyright (C) 2016 Openbravo SLU + * All portions are Copyright (C) 2016-2019 Openbravo SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************ @@ -27,32 +27,45 @@ import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; -import org.mozilla.javascript.NativeArray; +import org.openbravo.base.expression.OBScriptEngine; import org.openbravo.client.kernel.RequestContext; import org.openbravo.client.kernel.reference.UIDefinition; import org.openbravo.client.kernel.reference.UIDefinitionController; import org.openbravo.model.ad.datamodel.Column; import org.openbravo.service.json.JsonConstants; _______________________________________________ Openbravo-commits mailing list Openbravo-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openbravo-commits