svn commit: r570282 - in /ofbiz/trunk/framework: entity/dtd/ entityext/servicedef/ entityext/src/org/ofbiz/entityext/ entityext/src/org/ofbiz/entityext/eca/

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r570282 - in /ofbiz/trunk/framework: entity/dtd/ entityext/servicedef/ entityext/src/org/ofbiz/entityext/ entityext/src/org/ofbiz/entityext/eca/

jonesde
Author: jonesde
Date: Mon Aug 27 17:47:58 2007
New Revision: 570282

URL: http://svn.apache.org/viewvc?rev=570282&view=rev
Log:
Added set element for Entity ECA rules, and a simple service to be run as an EECA for watching entire entities or single fields on entities

Added:
    ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java   (with props)
    ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java   (with props)
Modified:
    ofbiz/trunk/framework/entity/dtd/entity-eca.xsd
    ofbiz/trunk/framework/entityext/servicedef/services.xml
    ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaAction.java
    ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaRule.java

Modified: ofbiz/trunk/framework/entity/dtd/entity-eca.xsd
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/dtd/entity-eca.xsd?rev=570282&r1=570281&r2=570282&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/dtd/entity-eca.xsd (original)
+++ ofbiz/trunk/framework/entity/dtd/entity-eca.xsd Mon Aug 27 17:47:58 2007
@@ -21,7 +21,7 @@
     <xs:element name="entity-eca">
         <xs:complexType>
             <xs:sequence>
-                <xs:element maxOccurs="unbounded" ref="eca"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" ref="eca"/>
             </xs:sequence>
         </xs:complexType>
     </xs:element>
@@ -32,7 +32,10 @@
                     <xs:element ref="condition"/>
                     <xs:element ref="condition-field"/>
                 </xs:choice>
-                <xs:element maxOccurs="unbounded" ref="action"/>
+                <xs:choice minOccurs="1" maxOccurs="unbounded">
+                    <xs:element ref="set"/>
+                    <xs:element ref="action"/>
+                </xs:choice>                
             </xs:sequence>
             <xs:attributeGroup ref="attlist.eca"/>
         </xs:complexType>
@@ -158,6 +161,32 @@
             </xs:simpleType>
         </xs:attribute>
         <xs:attribute type="xs:string" name="format"/>
+    </xs:attributeGroup>
+    <xs:element name="set">
+        <xs:complexType>
+            <xs:attributeGroup ref="attlist.set"/>
+        </xs:complexType>
+    </xs:element>
+    <xs:attributeGroup name="attlist.set">
+        <xs:attribute type="xs:string" name="field-name" use="required"/>
+        <xs:attribute type="xs:string" name="env-name"/>
+        <xs:attribute type="xs:string" name="value"/>
+        <xs:attribute name="format">
+            <xs:simpleType>
+                <xs:restriction base="xs:token">
+                    <xs:enumeration value="append"/>                    
+                    <xs:enumeration value="to-upper"/>
+                    <xs:enumeration value="to-lower"/>
+                    <xs:enumeration value="hash-code"/>
+                    <xs:enumeration value="long"/>
+                    <xs:enumeration value="double"/>
+                    <xs:enumeration value="upper-first-char"/>
+                    <xs:enumeration value="lower-first-char"/>
+                    <xs:enumeration value="db-to-java"/>
+                    <xs:enumeration value="java-to-db"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
     </xs:attributeGroup>
     <xs:element name="action">
         <xs:complexType>

Modified: ofbiz/trunk/framework/entityext/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/servicedef/services.xml?rev=570282&r1=570281&r2=570282&view=diff
==============================================================================
--- ofbiz/trunk/framework/entityext/servicedef/services.xml (original)
+++ ofbiz/trunk/framework/entityext/servicedef/services.xml Mon Aug 27 17:47:58 2007
@@ -23,6 +23,12 @@
     <description>Entity Extension Services</description>
     <vendor>OFBiz</vendor>
     <version>1.0</version>
+    
+    <!-- simple generic service to watch and entity through an EECA -->
+    <service name="watchEntity" engine="java" location="org.ofbiz.entityext.EntityWatchServices" invoke="watchEntity">
+        <attribute name="newValue" type="GenericValue" mode="IN"/>
+        <attribute name="fieldName" type="String" mode="IN"/>
+    </service>
 
     <!-- Entity Engine Extension Services -->
     <service name="distributedClearAllEntityCaches" engine="jms" location="serviceMessenger" invoke="clearAllEntityCaches" auth="true">

Added: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java?rev=570282&view=auto
==============================================================================
--- ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java (added)
+++ ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java Mon Aug 27 17:47:58 2007
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.entityext;
+
+import org.ofbiz.service.ServiceUtil;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.security.Security;
+import org.ofbiz.entity.GenericDelegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.jdbc.DatabaseUtil;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilURL;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+
+import java.util.*;
+import java.io.*;
+import java.net.URI;
+import java.net.URL;
+import java.net.URISyntaxException;
+
+public class EntityWatchServices {
+
+    public static final String module = EntityWatchServices.class.getName();
+
+    /**
+     * This service is meant to be called through an Entity ECA (EECA) to watch an entity
+     *
+     * @param dctx
+     * @param context
+     * @return
+     */
+    public static Map watchEntity(DispatchContext dctx, Map context) {
+        GenericValue newValue = (GenericValue) context.get("newValue");
+        String fieldName = (String) context.get("fieldName");
+        
+        if (newValue == null) {
+            return ServiceUtil.returnSuccess();
+        }
+        
+        GenericValue currentValue = null;
+        try {
+            currentValue = dctx.getDelegator().findByPrimaryKey(newValue.getPrimaryKey());
+        } catch (GenericEntityException e) {
+            String errMsg = "Error finding currentValue for primary key [" + newValue.getPrimaryKey() + "]: " + e.toString();
+            Debug.logError(e, errMsg, module);
+        }
+        
+        if (currentValue != null) {
+            if (UtilValidate.isNotEmpty(fieldName)) {
+                // just watch the field
+                Object currentFieldValue = currentValue.get(fieldName);
+                Object newFieldValue = newValue.get(fieldName);
+                boolean changed = false;
+                if (currentFieldValue != null) {
+                    if (!currentFieldValue.equals(newFieldValue)) {
+                        changed = true;
+                    }
+                } else {
+                    if (newFieldValue != null) {
+                        changed = true;
+                    }
+                }
+                
+                if (changed) {
+                    String errMsg = "Watching entity [" + currentValue.getEntityName() + "] field [" + fieldName + "] value changed from [" + currentFieldValue + "] to [" + newFieldValue + "]";
+                    Debug.log(new Exception(errMsg), errMsg, module);
+                }
+            } else {
+                // watch the whole entity
+                if (!currentValue.equals(newValue)) {
+                    String errMsg = "Watching entity [" + currentValue.getEntityName() + "] whole value changed from [" + currentValue + "] to [" + newValue + "]";
+                    Debug.log(new Exception(errMsg), errMsg, module);
+                }
+            }
+        }
+        
+        return ServiceUtil.returnSuccess();
+    }
+}

Propchange: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/EntityWatchServices.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaAction.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaAction.java?rev=570282&r1=570281&r2=570282&view=diff
==============================================================================
--- ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaAction.java (original)
+++ ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaAction.java Mon Aug 27 17:47:58 2007
@@ -64,15 +64,15 @@
         this.valueAttr = action.getAttribute("value-attr");
     }
 
-    public void runAction(DispatchContext dctx, GenericEntity value) throws GenericEntityException {
+    public void runAction(DispatchContext dctx, Map context, GenericEntity newValue) throws GenericEntityException {
         Map actionResult = null;
         
         try {
             // pull out context parameters needed for this service.
-            Map actionContext = dctx.getModelService(serviceName).makeValid(value, ModelService.IN_PARAM);
+            Map actionContext = dctx.getModelService(serviceName).makeValid(context, ModelService.IN_PARAM);
             // if value-attr is specified, insert the value object in that attr name
             if (valueAttr != null && valueAttr.length() > 0) {
-                actionContext.put(valueAttr, value);
+                actionContext.put(valueAttr, newValue);
             }
             
             //Debug.logInfo("Running Entity ECA action service " + this.serviceName + " triggered by entity: " + value.getEntityName(), module);
@@ -113,7 +113,7 @@
 
         // use the result to update the context fields.
         if (resultToValue) {
-            value.setNonPKFields(actionResult);
+            newValue.setNonPKFields(actionResult);
         }
     }
 }

Modified: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaRule.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaRule.java?rev=570282&r1=570281&r2=570282&view=diff
==============================================================================
--- ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaRule.java (original)
+++ ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaRule.java Mon Aug 27 17:47:58 2007
@@ -19,10 +19,14 @@
 package org.ofbiz.entityext.eca;
 
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
+import javolution.util.FastList;
+import javolution.util.FastMap;
+import javolution.util.FastSet;
+
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.entity.GenericEntity;
@@ -41,8 +45,8 @@
     protected String operationName = null;
     protected String eventName = null;
     protected boolean runOnError = false;
-    protected List conditions = new LinkedList();
-    protected List actions = new LinkedList();
+    protected List conditions = FastList.newInstance();
+    protected List actionsAndSets = FastList.newInstance();
     protected boolean enabled = true;
 
     protected EntityEcaRule() {}
@@ -67,13 +71,21 @@
 
         if (Debug.verboseOn()) Debug.logVerbose("Conditions: " + conditions, module);
 
-        List actList = UtilXml.childElementList(eca, "action");
-        Iterator ai = actList.iterator();
-        while (ai.hasNext()) {
-            actions.add(new EntityEcaAction((Element) ai.next()));
+        Set nameSet = FastSet.newInstance();
+        nameSet.add("set");
+        nameSet.add("action");
+        List actionAndSetList = UtilXml.childElementList(eca, nameSet);
+        Iterator si = actionAndSetList.iterator();
+        while (si.hasNext()) {
+            Element actionOrSetElement = (Element) si.next();
+            if ("action".equals(actionOrSetElement.getNodeName())) {
+                this.actionsAndSets.add(new EntityEcaAction(actionOrSetElement));
+            } else {
+                this.actionsAndSets.add(new EntityEcaSetField(actionOrSetElement));
+            }
         }
 
-        if (Debug.verboseOn()) Debug.logVerbose("Actions: " + actions, module);
+        if (Debug.verboseOn()) Debug.logVerbose("actions and sets (intermixed): " + actionsAndSets, module);
     }
 
     public void eval(String currentOperation, DispatchContext dctx, GenericEntity value, boolean isError, Set actionsRun) throws GenericEntityException {
@@ -90,6 +102,9 @@
         if (!"any".equals(this.operationName) && this.operationName.indexOf(currentOperation) == -1) {
             return;
         }
+        
+        Map context = FastMap.newInstance();
+        context.putAll(value);
 
         boolean allCondTrue = true;
         Iterator c = conditions.iterator();
@@ -102,15 +117,21 @@
         }
 
         if (allCondTrue) {
-            Iterator a = actions.iterator();
-            while (a.hasNext()) {
-                EntityEcaAction ea = (EntityEcaAction) a.next();
-                // in order to enable OR logic without multiple calls to the given service,
-                //only execute a given service name once per service call phase
-                if (!actionsRun.contains(ea.serviceName)) {
-                    if (Debug.infoOn()) Debug.logInfo("Running Entity ECA Service: " + ea.serviceName + ", triggered by rule on Entity: " + value.getEntityName(), module);
-                    ea.runAction(dctx, value);
-                    actionsRun.add(ea.serviceName);
+            Iterator actionsAndSetIter = actionsAndSets.iterator();
+            while (actionsAndSetIter.hasNext()) {
+                Object actionOrSet = actionsAndSetIter.next();
+                if (actionOrSet instanceof EntityEcaAction) {
+                    EntityEcaAction ea = (EntityEcaAction) actionOrSet;
+                    // in order to enable OR logic without multiple calls to the given service,
+                    //only execute a given service name once per service call phase
+                    if (!actionsRun.contains(ea.serviceName)) {
+                        if (Debug.infoOn()) Debug.logInfo("Running Entity ECA Service: " + ea.serviceName + ", triggered by rule on Entity: " + value.getEntityName(), module);
+                        ea.runAction(dctx, context, value);
+                        actionsRun.add(ea.serviceName);
+                    }
+                } else {
+                    EntityEcaSetField sf = (EntityEcaSetField) actionOrSet;
+                    sf.eval(context);
                 }
             }
         }

Added: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java?rev=570282&view=auto
==============================================================================
--- ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java (added)
+++ ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java Mon Aug 27 17:47:58 2007
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+
+package org.ofbiz.entityext.eca;
+
+import org.w3c.dom.Element;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.string.FlexibleStringExpander;
+import org.ofbiz.entity.model.ModelUtil;
+
+import java.util.Map;
+
+/**
+ * ServiceEcaSetField
+ */
+public class EntityEcaSetField {
+
+    public static final String module = EntityEcaSetField.class.getName();
+
+    protected String fieldName = null;
+    protected String envName = null;
+    protected String value = null;
+    protected String format = null;
+
+    public EntityEcaSetField(Element set) {
+        this.fieldName = set.getAttribute("field-name");
+        this.envName = set.getAttribute("env-name");
+        this.value = set.getAttribute("value");
+        this.format = set.getAttribute("format");
+    }
+
+    public void eval(Map context) {
+        if (fieldName != null) {
+            // try to expand the envName
+            if (UtilValidate.isEmpty(value)) {
+                if (UtilValidate.isNotEmpty(envName) && envName.startsWith("${")) {
+                    FlexibleStringExpander exp = new FlexibleStringExpander(envName);
+                    String s = exp.expandString(context);
+                    if (UtilValidate.isNotEmpty(s)) {
+                        value = s;
+                    }
+                    Debug.log("Expanded String: " + s, module);
+                }
+            }
+
+            // process the context changes
+            if (UtilValidate.isNotEmpty(value)) {
+                context.put(fieldName, this.format(value, context));            
+            } else if (UtilValidate.isNotEmpty(envName) && context.get(envName) != null) {
+                context.put(fieldName, this.format((String) context.get(envName), context));
+            }
+        }
+    }
+
+    protected Object format(String s, Map c) {
+        if (UtilValidate.isEmpty(s) || UtilValidate.isEmpty(format)) {            
+            return s;
+        }
+
+        // string formats
+        if ("append".equalsIgnoreCase(format) && envName != null) {
+            String newStr = "";
+            if (c.get(envName) != null) {
+                newStr = newStr + c.get(envName);
+            }
+            newStr = newStr + s;
+            return newStr;
+        }
+        if ("to-upper".equalsIgnoreCase(format)) {
+            return s.toUpperCase();
+        }
+        if ("to-lower".equalsIgnoreCase(format)) {
+            return s.toLowerCase();
+        }
+        if ("hash-code".equalsIgnoreCase(format)) {
+            return new Integer(s.hashCode());
+        }
+        if ("long".equalsIgnoreCase(format)) {
+            return new Long(s);
+        }
+        if ("double".equalsIgnoreCase(format)) {
+            return new Double(s);
+        }
+
+        // entity formats
+        if ("upper-first-char".equalsIgnoreCase(format)) {
+            return ModelUtil.upperFirstChar(s);
+        }
+        if ("lower-first-char".equalsIgnoreCase(format)) {
+            return ModelUtil.lowerFirstChar(s);
+        }
+        if ("db-to-java".equalsIgnoreCase(format)) {
+            return ModelUtil.dbNameToVarName(s);
+        }
+        if ("java-to-db".equalsIgnoreCase(format)) {
+            return ModelUtil.javaNameToDbName(s);
+        }
+
+        Debug.logWarning("Format function not found [" + format + "] return string unchanged - " + s, module);
+        return s;
+    }
+}

Propchange: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaSetField.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain