Two performance optimizations done to the FIC calls in CHANGE mode:
authorAntonio Moreno <antonio.moreno@openbravo.com>
Tue, 10 May 2011 18:10:04 +0200
changeset 12084 2c625d83f03b
parent 12083 4bd125ca1dda
child 12085 2045cb1d1e25
Two performance optimizations done to the FIC calls in CHANGE mode:
- When a callout response corresponds to a combo-type column, the combo will no longer be recalculated
- When a callout is fired more than once in the same request, its instance will be reused
modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java
modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/EnumUIDefinition.java
modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/FKComboUIDefinition.java
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java	Tue May 10 17:41:50 2011 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/FormInitializationComponent.java	Tue May 10 18:10:04 2011 +0200
@@ -53,6 +53,7 @@
 import org.openbravo.client.kernel.KernelUtils;
 import org.openbravo.client.kernel.RequestContext;
 import org.openbravo.client.kernel.reference.EnumUIDefinition;
+import org.openbravo.client.kernel.reference.FKComboUIDefinition;
 import org.openbravo.client.kernel.reference.ForeignKeyUIDefinition;
 import org.openbravo.client.kernel.reference.UIDefinition;
 import org.openbravo.client.kernel.reference.UIDefinitionController;
@@ -603,6 +604,7 @@
   }
 
   private void setValuesInRequest(String mode, Tab tab, BaseOBObject row, JSONObject jsContent) {
+
     List<Field> fields = tab.getADFieldList();
     if (mode.equals("EDIT")) {
       // In EDIT mode we initialize them from the database
@@ -610,7 +612,6 @@
         setValueOfColumnInRequest(row, field.getColumn().getDBColumnName());
       }
     }
-
     // and then overwrite with what gets passed in
     if (mode.equals("EDIT") || mode.equals("CHANGE") || mode.equals("SETSESSION")) {
       // In CHANGE and SETSESSION we get them from the request
@@ -913,6 +914,7 @@
   private List<String> runCallouts(Map<String, JSONObject> columnValues, Tab tab,
       List<String> calledCallouts, List<String> calloutsToCall, List<String> lastfieldChangedList,
       List<String> messages, List<String> dynamicCols) {
+    HashMap<String, Object> calloutInstances = new HashMap<String, Object>();
 
     // flush&commit to release lock in db which otherwise interfere with callouts which run in their
     // own jdbc connection (i.e. lock on AD_Sequence when using with Sales Invoice window)
@@ -923,7 +925,6 @@
     } catch (SQLException e1) {
       throw new OBException("Error committing before runnings callouts", e1);
     }
-
     List<Field> fields = tab.getADFieldList();
     HashMap<String, Field> inpFields = buildInpField(fields);
     String lastCalledCallout = "";
@@ -942,11 +943,9 @@
       log.debug("Calling callout " + calloutClassName + " with field changed " + lastFieldChanged);
       try {
         Class<?> calloutClass = Class.forName(calloutClassName);
-        calloutsToCall.remove(calloutClassName);
-        lastfieldChangedList.remove(lastFieldChanged);
-        Object calloutInstance = calloutClass.newInstance();
         Method init = null;
         Method service = null;
+        Method post = null;
         for (Method m : calloutClass.getMethods()) {
           if (m.getName().equals("init") && m.getParameterTypes().length == 1) {
             init = m;
@@ -954,7 +953,12 @@
           if (m.getName().equals("service")) {
             service = m;
           }
+          if (m.getName().equals("doPost")) {
+            post = m;
+          }
         }
+        calloutsToCall.remove(calloutClassName);
+        lastfieldChangedList.remove(lastFieldChanged);
 
         if (init == null || service == null) {
           log.info("Couldn't find method in Callout " + calloutClassName);
@@ -963,20 +967,26 @@
 
           RequestContext.get().setRequestParameter("inpLastFieldChanged", lastFieldChanged);
           RequestContext.get().setRequestParameter("inpOB3UIMode", "Y");
-
           // We then execute the callout
-          CalloutServletConfig config = new CalloutServletConfig(calloutClassName, RequestContext
-              .getServletContext());
-          Object[] initArgs = { config };
-          init.invoke(calloutInstance, initArgs);
+          Object calloutInstance;
           CalloutHttpServletResponse fakeResponse = new CalloutHttpServletResponse(rq.getResponse());
           Object[] arguments = { rq.getRequest(), fakeResponse };
+          if (calloutInstances.get(calloutClassName) != null) {
+            calloutInstance = calloutInstances.get(calloutClassName);
+            post.invoke(calloutInstance, arguments);
+          } else {
+            calloutInstance = calloutClass.newInstance();
+            calloutInstances.put(calloutClassName, calloutInstance);
+            CalloutServletConfig config = new CalloutServletConfig(calloutClassName, RequestContext
+                .getServletContext());
+            Object[] initArgs = { config };
+            init.invoke(calloutInstance, initArgs);
+            // We invoke the service method. This method will automatically call the doPost() method
+            // of the callout servlet
+            service.invoke(calloutInstance, arguments);
+          }
 
-          // We invoke the service method. This method will automatically call the doPost() method
-          // of the callout servlet
-          service.invoke(calloutInstance, arguments);
           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>();
@@ -1060,9 +1070,18 @@
                       } else {
                         rq.setRequestParameter(colId, uiDef.convertToClassicString(el));
                       }
-                      JSONObject jsonobj = new JSONObject(uiDef.getFieldProperties(inpFields
-                          .get(name), true));
-                      if (el == null && jsonobj.has("entries")) {
+                      String jsonStr;
+                      if (uiDef instanceof FKComboUIDefinition) {
+                        jsonStr = ((FKComboUIDefinition) uiDef).getFieldPropertiesWithoutCombo(
+                            inpFields.get(name), true);
+                      } else if (uiDef instanceof EnumUIDefinition) {
+                        jsonStr = ((EnumUIDefinition) uiDef).getFieldPropertiesWithoutCombo(
+                            inpFields.get(name), true);
+                      } else {
+                        jsonStr = uiDef.getFieldProperties(inpFields.get(name), true);
+                      }
+                      JSONObject jsonobj = new JSONObject(jsonStr);
+                      if (el == null && uiDef instanceof ForeignKeyUIDefinition) {
                         // Special case for null values for combos: we must clean the combo values
                         jsonobj.put("value", "");
                         jsonobj.put("classicValue", "");
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/EnumUIDefinition.java	Tue May 10 17:41:50 2011 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/EnumUIDefinition.java	Tue May 10 18:10:04 2011 +0200
@@ -68,6 +68,10 @@
     }
   }
 
+  public String getFieldPropertiesWithoutCombo(Field field, boolean getValueFromSession) {
+    return super.getFieldProperties(field, getValueFromSession);
+  }
+
   @Override
   public String getFilterEditorProperties(Field field) {
     return ", filterOnKeypress: true" + super.getFilterEditorProperties(field);
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/FKComboUIDefinition.java	Tue May 10 17:41:50 2011 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/FKComboUIDefinition.java	Tue May 10 18:10:04 2011 +0200
@@ -55,4 +55,8 @@
     }
   }
 
+  public String getFieldPropertiesWithoutCombo(Field field, boolean getValueFromSession) {
+    return super.getFieldProperties(field, getValueFromSession);
+  }
+
 }