From 1ad2d20761586b5bec49a442c89f45c8502da344 Mon Sep 17 00:00:00 2001 From: vpj-cd Date: Thu, 24 Jan 2008 21:33:37 +0000 Subject: [PATCH] [ 1877902 ] Implement JSR 223: Scripting callout http://sourceforge.net/tracker/?func=detail&atid=879335&aid=1877902&group_id=176962 --- .classpath | 166 +++++++++--------- base/src/org/compiere/model/GridField.java | 14 +- base/src/org/compiere/model/GridFieldVO.java | 46 +++-- base/src/org/compiere/model/GridTab.java | 77 ++++++-- base/src/org/compiere/model/X_AD_Rule.java | 12 +- .../331b-trunk/076_FR1877902_EngineScript.sql | 30 ++++ .../postgresql/076_FR1877902_EngineScript.sql | 29 +++ tools/build.xml | 28 ++- 8 files changed, 277 insertions(+), 125 deletions(-) create mode 100644 migration/331b-trunk/076_FR1877902_EngineScript.sql create mode 100644 migration/331b-trunk/postgresql/076_FR1877902_EngineScript.sql diff --git a/.classpath b/.classpath index 0baf07a07f..9e3faa877f 100644 --- a/.classpath +++ b/.classpath @@ -1,80 +1,86 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/base/src/org/compiere/model/GridField.java b/base/src/org/compiere/model/GridField.java index 902fa4d526..05ffaf830a 100644 --- a/base/src/org/compiere/model/GridField.java +++ b/base/src/org/compiere/model/GridField.java @@ -38,7 +38,9 @@ import org.compiere.util.*; * Usually editors listen to their fields. * * @author Jorg Janke - * @contributor Victor Perez , e-Evolution.SC FR [ 1757088 ] + * @author Victor Perez , e-Evolution.SC FR [ 1757088 ], [1877902] Implement JSR 223 Scripting APIs to Callout + * @author Carlos Ruiz, qss FR [1877902] + * @see http://sourceforge.net/tracker/?func=detail&atid=879335&aid=1877902&group_id=176962 to FR [1877902] * @version $Id: GridField.java,v 1.5 2006/07/30 00:51:02 jjanke Exp $ */ public class GridField @@ -1083,13 +1085,15 @@ public class GridField { return m_vo.Callout; } + + //FR [1877902] /** - * Get bsh Callout Code - * @return bsh callout code + * Get Script Code + * @return Script Code */ - public String getBshCalloutCode() + public String getScriptCode() { - return m_vo.bshCalloutCode; + return m_vo.scriptCode; } /** * Get AD_Process_ID diff --git a/base/src/org/compiere/model/GridFieldVO.java b/base/src/org/compiere/model/GridFieldVO.java index 9897c57d04..f3b1f0866d 100644 --- a/base/src/org/compiere/model/GridFieldVO.java +++ b/base/src/org/compiere/model/GridFieldVO.java @@ -28,7 +28,9 @@ import org.compiere.util.*; * Field Model Value Object * * @author Jorg Janke - * @contributor Victor Perez , e-Evolution.SC FR [ 1757088 ] + * @author Victor Perez , e-Evolution.SC FR [ 1757088 ] , [1877902] Implement JSR 223 Scripting APIs to Callout + * @author Carlos Ruiz, qss FR [1877902] + * @see http://sourceforge.net/tracker/?func=detail&atid=879335&aid=1877902&group_id=176962 to FR [1877902] * @version $Id: GridFieldVO.java,v 1.3 2006/07/30 00:58:04 jjanke Exp $ */ public class GridFieldVO implements Serializable @@ -141,20 +143,42 @@ public class GridFieldVO implements Serializable else if (columnName.equalsIgnoreCase("Callout")) { vo.Callout = rs.getString (i); // CarlosRuiz - globalqss - FR [ 1877902 ] Implement beanshell callout - if (vo.Callout != null && vo.Callout.toLowerCase().startsWith("@bsh:")) { - String bshcmd = vo.Callout.substring(5).trim(); + // Vitor Perez - vpj-cd - FR [ 1877902 ] Implement JSR 223 Scripting APIs to Callout + String callout = vo.Callout; + int script_end = 8; + int engine_end = 0; + if (callout != null && callout.toLowerCase().startsWith("@script:")) { + engine_end = callout.indexOf(":", script_end); + if (engine_end <= 0) + { + CLogger.get().log(Level.SEVERE, "ColumnName=" + columnName, " Call Invalid "+ callout +" error in syntax please use something like @script:groovy:mycallout"); + continue; + } + String engine = callout.substring(script_end,engine_end); + if (engine== null) + { + CLogger.get().log(Level.SEVERE, "ColumnName=" + columnName, " Call Invalid "+ callout +" error in syntax please use something like @script:groovy:mycallout"); + continue; + } + String calloutname = callout.substring(engine_end); + if (calloutname== null) + { + CLogger.get().log(Level.SEVERE, "ColumnName=" + columnName, " Call Invalid "+ callout +" error in syntax please use something like @script:groovy:mycallout"); + continue; + } + String rule_value =engine + calloutname.trim(); // TODO: Write MRule and create accessor by Value, EventType and RuleType - int bsh_id = DB.getSQLValue( + int script_id = DB.getSQLValue( null, - "SELECT AD_Rule_ID FROM AD_Rule WHERE Value=? AND EventType='C' AND RuleType='B' AND IsActive='Y'", - bshcmd); - if (bsh_id > 0) { - X_AD_Rule bsh = new X_AD_Rule(ctx, bsh_id, null); - vo.bshCalloutCode = bsh.getScript(); + "SELECT AD_Rule_ID FROM AD_Rule WHERE TRIM(Value)=? AND EventType='C' AND RuleType='B' AND IsActive='Y'", + rule_value); + if (script_id > 0) { + X_AD_Rule rule = new X_AD_Rule(ctx, script_id, null); + vo.scriptCode = rule.getScript(); // TODO: pre-parse for better performance // http://beanshell.org/manual/parser.html#Parsing_and_Performance } else { - CLogger.get().log(Level.SEVERE, "ColumnName=" + columnName, "Wrong callout " + vo.Callout); + CLogger.get().log(Level.SEVERE, "ColumnName=" + columnName, " Rule not found:" + rule_value); } } } @@ -469,7 +493,7 @@ public class GridFieldVO implements Serializable /** Callout */ public String Callout = ""; /** Callout */ - public String bshCalloutCode = null; + public String scriptCode = null; /** Process */ public int AD_Process_ID = 0; /** Description */ diff --git a/base/src/org/compiere/model/GridTab.java b/base/src/org/compiere/model/GridTab.java index 752266a7d2..cf81005582 100644 --- a/base/src/org/compiere/model/GridTab.java +++ b/base/src/org/compiere/model/GridTab.java @@ -25,11 +25,19 @@ import java.text.*; import java.util.*; import java.util.logging.*; + import javax.swing.event.*; //import org.compiere.apps.ADialog; import org.compiere.util.*; +import bsh.EvalError; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.Invocable; +import javax.script.ScriptException; + /** * Tab Model. * - a combination of AD_Tab (the display attributes) and AD_Table information. @@ -54,7 +62,9 @@ import org.compiere.util.*; * @version $Id: GridTab.java,v 1.10 2006/10/02 05:18:39 jjanke Exp $ * * @author Teo Sarca - BF [ 1742159 ] - * @contributor Victor Perez , e-Evolution.SC FR [ 1757088 ] + * @author Victor Perez , e-Evolution.SC [1877902] Implement JSR 223 Scripting APIs to Callout + * @author Carlos Ruiz, qss FR [1877902] + * @see http://sourceforge.net/tracker/?func=detail&atid=879335&aid=1877902&group_id=176962 to FR [1877902] */ public class GridTab implements DataStatusListener, Evaluatee, Serializable { @@ -2440,20 +2450,30 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable if (activeCallouts.contains(cmd)) continue; String retValue = ""; - + // FR [1877902] // CarlosRuiz - globalqss - implement beanshell callout - if (cmd.toLowerCase().startsWith("@bsh:")) { + // Victor Perez - vpj-cd implement JSR 223 Scripting + if (cmd.toLowerCase().startsWith("@script:")) { - if (field.getBshCalloutCode() == null || field.getBshCalloutCode().length() == 0) { - retValue = "Callout Invalid: " + cmd + " (no code found for beanshell)"; + if (field.getScriptCode() == null || field.getScriptCode().length() == 0) { + retValue = "Callout invalid error in syntax: " + cmd + " error in syntax please use something like @script:groovy:mycallout"; log.log(Level.SEVERE, retValue); return retValue; } - String code = field.getBshCalloutCode(); - - /** The Script */ - Scriptlet m_script; + int engine_end = 0; + engine_end = callout.indexOf(":", 8); + if (engine_end <= 0) + { + CLogger.get().log(Level.SEVERE, "Callout Invalid: " + cmd , " error in syntax please use something like @script:groovy:mycallout"); + return retValue; + } + String engine_name = callout.substring(8,engine_end); + if (engine_name== null) + { + CLogger.get().log(Level.SEVERE, "Callout Invalid: " + cmd , " error in syntax please use something like @script:groovy:mycallout"); + return retValue; + } // Convert from ctx to hashmap HashMap script_ctx = new HashMap(); @@ -2472,7 +2492,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable Object obj = m_vo.ctx.get(key); if (key != null && key.length() > 0) { - // log.fine( "Scriptlet.setEnvironment " + key, value); + //log.fine( "Script.setEnvironment " + key, value); if (value == null) script_ctx.remove(key); else @@ -2489,18 +2509,37 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable script_ctx.put("___Value", value); script_ctx.put("___OldValue", oldValue); - m_script = new Scriptlet (Scriptlet.VARIABLE, code, script_ctx); - - activeCallouts.add(cmd); - Exception e = m_script.execute(); - activeCallouts.remove(cmd); - if (e != null) { - log.log(Level.SEVERE, "execute", e); + ScriptEngineManager factory = new ScriptEngineManager(); + ScriptEngine engine = factory.getEngineByName(engine_name); + + try + { + Iterator it = script_ctx.keySet().iterator(); + while (it.hasNext()) + { + String key = (String)it.next(); + Object script_value = script_ctx.get(key); + if (script_value instanceof Boolean) + engine.put(key, ((Boolean)script_value).booleanValue()); + else if (script_value instanceof Integer) + engine.put(key,((Integer)script_value).intValue()); + else if (script_value instanceof Double) + engine.put(key,((Integer)script_value).intValue()); + else + engine.put(key,script_value); + } + + activeCallouts.add(cmd); + retValue = engine.eval(field.getScriptCode()).toString(); + activeCallouts.remove(cmd); + + } + catch (ScriptException e) + { + log.log(Level.SEVERE, "", e); retValue = "Callout Invalid: " + e.toString(); return retValue; } - Object result = m_script.getResult(false); - retValue = result.toString(); } else { diff --git a/base/src/org/compiere/model/X_AD_Rule.java b/base/src/org/compiere/model/X_AD_Rule.java index dc18c3d821..8ac5f96d85 100644 --- a/base/src/org/compiere/model/X_AD_Rule.java +++ b/base/src/org/compiere/model/X_AD_Rule.java @@ -273,20 +273,18 @@ public class X_AD_Rule extends PO implements I_AD_Rule, I_Persistent public static final int RULETYPE_AD_Reference_ID=53235; /** Aspect Orient Program = A */ public static final String RULETYPE_AspectOrientProgram = "A"; - /** BeanShell = B */ - public static final String RULETYPE_BeanShell = "B"; + /** JSR 223 Scripting APIs = S */ + public static final String RULETYPE_JSR223ScriptingAPIs = "S"; /** JSR 94 Rule Engine API = R */ public static final String RULETYPE_JSR94RuleEngineAPI = "R"; - /** SQL = S */ - public static final String RULETYPE_SQL = "S"; - /** Groovy = G */ - public static final String RULETYPE_Groovy = "G"; + /** SQL = Q */ + public static final String RULETYPE_SQL = "Q"; /** Set Rule Type. @param RuleType Rule Type */ public void setRuleType (String RuleType) { - if (RuleType == null || RuleType.equals("A") || RuleType.equals("B") || RuleType.equals("R") || RuleType.equals("S") || RuleType.equals("G")); else throw new IllegalArgumentException ("RuleType Invalid value - " + RuleType + " - Reference_ID=53235 - A - B - R - S - G"); + if (RuleType == null || RuleType.equals("A") || RuleType.equals("S") || RuleType.equals("R") || RuleType.equals("Q")); else throw new IllegalArgumentException ("RuleType Invalid value - " + RuleType + " - Reference_ID=53235 - A - S - R - Q"); if (RuleType != null && RuleType.length() > 1) { log.warning("Length > 1 - truncated"); diff --git a/migration/331b-trunk/076_FR1877902_EngineScript.sql b/migration/331b-trunk/076_FR1877902_EngineScript.sql new file mode 100644 index 0000000000..c203cd10f9 --- /dev/null +++ b/migration/331b-trunk/076_FR1877902_EngineScript.sql @@ -0,0 +1,30 @@ +-- Jan 24, 2008 2:25:48 PM CST +-- 1877902 - Implement JSR 223: Scripting +UPDATE AD_Column SET Callout='@script:beanshell:FillDescriptionWithName',Updated=TO_DATE('2008-01-24 14:25:48','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Column_ID=54249 +; + +UPDATE AD_Ref_List SET Value='S', Name='JSR 223 Scripting APIs',Updated=TO_DATE('2008-01-24 14:26:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53290 +; + +UPDATE AD_Ref_List SET Value='Q',Updated=TO_DATE('2008-01-24 14:27:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53292 +; + +UPDATE AD_Ref_List SET Value='S', Name='JSR 223 Scripting APIs',Updated=TO_DATE('2008-01-24 14:27:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53290 +; + +UPDATE AD_Ref_List_Trl SET IsTranslated='N' WHERE AD_Ref_List_ID=53290 +; + +DELETE FROM AD_Ref_List_Trl WHERE AD_Ref_List_ID=53298 +; + + +DELETE FROM AD_Ref_List WHERE AD_Ref_List_ID=53298 +; + +UPDATE AD_Field SET DisplayLogic='@RuleType@=Q',Updated=TO_DATE('2008-01-24 14:28:14','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Field_ID=54338 +; + +UPDATE AD_Rule SET RuleType='S',Updated=TO_DATE('2008-01-24 14:28:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Rule_ID=50000 +; + diff --git a/migration/331b-trunk/postgresql/076_FR1877902_EngineScript.sql b/migration/331b-trunk/postgresql/076_FR1877902_EngineScript.sql new file mode 100644 index 0000000000..246b639ac1 --- /dev/null +++ b/migration/331b-trunk/postgresql/076_FR1877902_EngineScript.sql @@ -0,0 +1,29 @@ +-- Jan 24, 2008 2:25:48 PM CST +-- 1877902 - Implement JSR 223: Scripting +UPDATE AD_Column SET Callout='@script:beanshell:FillDescriptionWithName',Updated=TO_TIMESTAMP('2008-01-24 14:25:48','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Column_ID=54249 +; + +UPDATE AD_Ref_List SET Value='S', Name='JSR 223 Scripting APIs',Updated=TO_TIMESTAMP('2008-01-24 14:26:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53290 +; + +UPDATE AD_Ref_List SET Value='Q',Updated=TO_TIMESTAMP('2008-01-24 14:27:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53292 +; + +UPDATE AD_Ref_List SET Value='S', Name='JSR 223 Scripting APIs',Updated=TO_TIMESTAMP('2008-01-24 14:27:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Ref_List_ID=53290 +; + +UPDATE AD_Ref_List_Trl SET IsTranslated='N' WHERE AD_Ref_List_ID=53290 +; + +DELETE FROM AD_Ref_List_Trl WHERE AD_Ref_List_ID=53298 +; + +DELETE FROM AD_Ref_List WHERE AD_Ref_List_ID=53298 +; + +UPDATE AD_Field SET DisplayLogic='@RuleType@=Q',Updated=TO_TIMESTAMP('2008-01-24 14:28:14','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Field_ID=54338 +; + +UPDATE AD_Rule SET RuleType='S',Updated=TO_TIMESTAMP('2008-01-24 14:28:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Rule_ID=50000 +; + diff --git a/tools/build.xml b/tools/build.xml index e1689612d9..587fab28e0 100644 --- a/tools/build.xml +++ b/tools/build.xml @@ -264,10 +264,32 @@ - - + + + + + + - + + + + + + + + + + + + + + + + + + +