svn commit: r679058 - in /ofbiz/trunk/framework: base/src/base/org/ofbiz/base/util/ entity/src/org/ofbiz/entity/finder/ example/script/org/ofbiz/example/example/ example/servicedef/ minilang/src/org/ofbiz/minilang/method/ifops/ service/config/ service/...

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

svn commit: r679058 - in /ofbiz/trunk/framework: base/src/base/org/ofbiz/base/util/ entity/src/org/ofbiz/entity/finder/ example/script/org/ofbiz/example/example/ example/servicedef/ minilang/src/org/ofbiz/minilang/method/ifops/ service/config/ service/...

jonesde
Author: jonesde
Date: Wed Jul 23 03:24:58 2008
New Revision: 679058

URL: http://svn.apache.org/viewvc?rev=679058&view=rev
Log:
An option I've resisted for a while due to limited flexibility when used, but we have a lot of these common cases so this may be worth it; can now define CrUD services and not have to implement them for common cases; the create, update, and delete ExampleItem services now use this entity-auto implementation instead of explicit simple-methods; those are tested and are working, and other variations on create should too but I haven't tested them yet; this also includes various refactorings to expose nderlying tools in simple method code and make it reusable

Added:
    ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java   (with props)
Modified:
    ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/UtilValidate.java
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java
    ofbiz/trunk/framework/example/script/org/ofbiz/example/example/ExampleServices.xml
    ofbiz/trunk/framework/example/servicedef/services.xml
    ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckId.java
    ofbiz/trunk/framework/service/config/serviceengine.xml
    ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelParam.java
    ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelService.java
    ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/StandardJavaEngine.java

Modified: ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/UtilValidate.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/UtilValidate.java?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/UtilValidate.java (original)
+++ ofbiz/trunk/framework/base/src/base/org/ofbiz/base/util/UtilValidate.java Wed Jul 23 03:24:58 2008
@@ -1293,4 +1293,45 @@
         if (check >= 10) check = 0;
         return Character.forDigit(check, 10);
     }
+    
+    public static boolean isValidDatabaseId(String fieldStr, StringBuffer errorDetails) {
+        boolean isValid = true;
+        if (fieldStr.indexOf(' ') >= 0) {
+            isValid = false;
+            errorDetails.append("[space found at position " + (fieldStr.indexOf(' ') + 1) + "]");
+        }
+        if (fieldStr.indexOf('"') >= 0) {
+            isValid = false;
+            errorDetails.append("[double-quote found at position " + (fieldStr.indexOf('"') + 1) + "]");
+        }
+        if (fieldStr.indexOf('\'') >= 0) {
+            isValid = false;
+            errorDetails.append("[single-quote found at position " + (fieldStr.indexOf('\'') + 1) + "]");
+        }
+        if (fieldStr.indexOf('&') >= 0) {
+            isValid = false;
+            errorDetails.append("[ampersand found at position " + (fieldStr.indexOf('&') + 1) + "]");
+        }
+        if (fieldStr.indexOf('?') >= 0) {
+            isValid = false;
+            errorDetails.append("[question mark found at position " + (fieldStr.indexOf('?') + 1) + "]");
+        }
+        if (fieldStr.indexOf('<') >= 0) {
+            isValid = false;
+            errorDetails.append("[less-than sign found at position " + (fieldStr.indexOf('<') + 1) + "]");
+        }
+        if (fieldStr.indexOf('>') >= 0) {
+            isValid = false;
+            errorDetails.append("[greater-than sign found at position " + (fieldStr.indexOf('>') + 1) + "]");
+        }
+        if (fieldStr.indexOf('\\') >= 0) {
+            isValid = false;
+            errorDetails.append("[back-slash found at position " + (fieldStr.indexOf('\\') + 1) + "]");
+        }
+        if (fieldStr.indexOf('/') >= 0) {
+            isValid = false;
+            errorDetails.append("[forward-slash found at position " + (fieldStr.indexOf('/') + 1) + "]");
+        }
+        return isValid;
+    }
 }

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/finder/PrimaryKeyFinder.java Wed Jul 23 03:24:58 2008
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*
  * 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
@@ -15,19 +15,19 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *******************************************************************************/
+ */
 package org.ofbiz.entity.finder;
 
-import java.io.Serializable;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javolution.util.FastMap;
+
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.base.util.GeneralException;
 import org.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.ofbiz.base.util.string.FlexibleStringExpander;
 import org.ofbiz.entity.GenericDelegator;
@@ -64,7 +64,6 @@
 
     public void runFind(Map<String, Object> context, GenericDelegator delegator) throws GeneralException {
         String entityName = this.entityNameExdr.expandString(context);
-        ModelEntity modelEntity = delegator.getModelEntity(entityName);
         
         String useCacheString = this.useCacheStrExdr.expandString(context);
         // default to false
@@ -74,10 +73,27 @@
         // default to true
         boolean autoFieldMapBool = !"false".equals(autoFieldMapString);
 
+        ModelEntity modelEntity = delegator.getModelEntity(entityName);
+        GenericValue valueOut = runFind(modelEntity, context, delegator, useCacheBool, autoFieldMapBool, this.fieldMap, this.selectFieldExpanderList);
+        
+        //Debug.logInfo("PrimaryKeyFinder: valueOut=" + valueOut, module);
+        //Debug.logInfo("PrimaryKeyFinder: going into=" + this.valueNameAcsr.getOriginalName(), module);
+        if (valueNameAcsr != null) {
+           this.valueNameAcsr.put(context, valueOut);
+        } else {
+           if (valueOut != null) {
+               context.putAll(valueOut);
+           }
+        }
+    }
+    
+    public static GenericValue runFind(ModelEntity modelEntity, Map<String, Object> context, GenericDelegator delegator, boolean useCache, boolean autoFieldMap,
+            Map<FlexibleMapAccessor, Object> fieldMap, List<FlexibleStringExpander> selectFieldExpanderList) throws GeneralException {
+        
         // assemble the field map
-        Map<String, Object> entityContext = new HashMap<String, Object>();
-        if (autoFieldMapBool) {
-            GenericValue tempVal = delegator.makeValue(entityName);
+        Map<String, Object> entityContext = FastMap.newInstance();
+        if (autoFieldMap) {
+            GenericValue tempVal = delegator.makeValue(modelEntity.getEntityName());
 
             // try a map called "parameters", try it first so values from here are overriden by values in the main context
             Object parametersObj = context.get("parameters");
@@ -90,7 +106,7 @@
 
             entityContext.putAll(tempVal);
         }
-        EntityFinderUtil.expandFieldMapToContext(this.fieldMap, context, entityContext);
+        EntityFinderUtil.expandFieldMapToContext(fieldMap, context, entityContext);
         //Debug.logInfo("PrimaryKeyFinder: entityContext=" + entityContext, module);
         // then convert the types...
         modelEntity.convertFieldMapInPlace(entityContext, delegator);
@@ -99,17 +115,17 @@
         Set<String> fieldsToSelect = EntityFinderUtil.makeFieldsToSelect(selectFieldExpanderList, context);
         
         //if fieldsToSelect != null and useCacheBool is true, throw an error
-        if (fieldsToSelect != null && useCacheBool) {
+        if (fieldsToSelect != null && useCache) {
             throw new IllegalArgumentException("Error in entity-one definition, cannot specify select-field elements when use-cache is set to true");
         }
         
         try {
             GenericValue valueOut = null;
-            GenericPK entityPK = delegator.makePK(entityName, entityContext);
+            GenericPK entityPK = delegator.makePK(modelEntity.getEntityName(), entityContext);
 
             // make sure we have a full primary key, if any field is null then just log a warning and return null instead of blowing up
             if (entityPK.containsPrimaryKey(true)) {
-                if (useCacheBool) {
+                if (useCache) {
                     valueOut = delegator.findOne(entityPK.getEntityName(), entityPK, true);
                 } else {
                     if (fieldsToSelect != null) {
@@ -122,19 +138,11 @@
                 if (Debug.infoOn()) Debug.logInfo("Returning null because found incomplete primary key in find: " + entityPK, module);
             }
             
-            //Debug.logInfo("PrimaryKeyFinder: valueOut=" + valueOut, module);
-            //Debug.logInfo("PrimaryKeyFinder: going into=" + this.valueNameAcsr.getOriginalName(), module);
-            if (valueNameAcsr != null) {
-               this.valueNameAcsr.put(context, valueOut);
-            } else {
-               if (valueOut != null) {
-                   context.putAll(valueOut);
-               }
-            }
+            return valueOut;
         } catch (GenericEntityException e) {
             String errMsg = "Error finding entity value by primary key with entity-one: " + e.toString();
             Debug.logError(e, errMsg, module);
-            throw new IllegalArgumentException(errMsg);
+            throw new GeneralException(errMsg, e);
         }
     }
 }

Modified: ofbiz/trunk/framework/example/script/org/ofbiz/example/example/ExampleServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/script/org/ofbiz/example/example/ExampleServices.xml?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/example/script/org/ofbiz/example/example/ExampleServices.xml (original)
+++ ofbiz/trunk/framework/example/script/org/ofbiz/example/example/ExampleServices.xml Wed Jul 23 03:24:58 2008
@@ -84,25 +84,6 @@
         <create-value value-name="newEntity"/>  
     </simple-method>  
     
-    <!-- ExampleItem methods -->
-    <simple-method method-name="createExampleItem" short-description="create a ExampleItem">
-        <make-value entity-name="ExampleItem" value-name="newEntity"/>
-        <set-pk-fields map-name="parameters" value-name="newEntity"/>
-        <make-next-seq-id value-name="newEntity" seq-field-name="exampleItemSeqId"/> <!-- this finds the next sub-sequence ID -->
-        <field-to-result field-name="newEntity.exampleItemSeqId" result-name="exampleItemSeqId"/>
-        <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
-        <create-value value-name="newEntity"/>  
-    </simple-method>  
-    <simple-method method-name="updateExampleItem" short-description="update a ExampleItem">
-        <entity-one entity-name="ExampleItem" value-name="lookedUpValue"/>
-        <set-nonpk-fields value-name="lookedUpValue" map-name="parameters"/>
-        <store-value value-name="lookedUpValue"/>
-    </simple-method>
-    <simple-method method-name="deleteExampleItem" short-description="delete a ExampleItem">        
-        <entity-one entity-name="ExampleItem" value-name="lookedUpValue"/>
-        <remove-value value-name="lookedUpValue"/>
-    </simple-method>
-
     <!-- Example ServiceTest Service -->
     <simple-method method-name="testCreateExampleService" short-description="test the create example service" login-required="false">
         <set field="createExampleMap.exampleTypeId" value="CONTRIVED"/>

Modified: ofbiz/trunk/framework/example/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/servicedef/services.xml?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/example/servicedef/services.xml (original)
+++ ofbiz/trunk/framework/example/servicedef/services.xml Wed Jul 23 03:24:58 2008
@@ -59,8 +59,7 @@
         </auto-attributes>
     </service>
     
-    <service name="createExampleItem" default-entity-name="ExampleItem" engine="simple"
-            location="component://example/script/org/ofbiz/example/example/ExampleServices.xml" invoke="createExampleItem" auth="true">
+    <service name="createExampleItem" default-entity-name="ExampleItem" engine="entity-auto" invoke="create" auth="true">
         <description>Create a ExampleItem</description>
         <permission-service service-name="exampleGenericPermission" main-action="CREATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
@@ -68,15 +67,13 @@
         <override name="exampleItemSeqId" mode="OUT"/> <!-- make this OUT rather than IN, we will automatically generate the next sub-sequence ID -->
         <override name="description" optional="false"/>
     </service>
-    <service name="updateExampleItem" default-entity-name="ExampleItem" engine="simple"
-            location="component://example/script/org/ofbiz/example/example/ExampleServices.xml" invoke="updateExampleItem" auth="true">
+    <service name="updateExampleItem" default-entity-name="ExampleItem" engine="entity-auto" invoke="update" auth="true">
         <description>Update a ExampleItem</description>
         <permission-service service-name="exampleGenericPermission" main-action="UPDATE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>
         <auto-attributes include="nonpk" mode="IN" optional="true"/>
     </service>
-    <service name="deleteExampleItem" default-entity-name="ExampleItem" engine="simple"
-        location="component://example/script/org/ofbiz/example/example/ExampleServices.xml" invoke="deleteExampleItem" auth="true">
+    <service name="deleteExampleItem" default-entity-name="ExampleItem" engine="entity-auto" invoke="delete" auth="true">
         <description>Delete a ExampleItem</description>
         <permission-service service-name="exampleGenericPermission" main-action="DELETE"/>
         <auto-attributes include="pk" mode="IN" optional="false"/>

Modified: ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckId.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckId.java?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckId.java (original)
+++ ofbiz/trunk/framework/minilang/src/org/ofbiz/minilang/method/ifops/CheckId.java Wed Jul 23 03:24:58 2008
@@ -88,42 +88,7 @@
         StringBuffer errorDetails = new StringBuffer();
         
         //check various illegal characters, etc for ids
-        if (fieldStr.indexOf(' ') >= 0) {
-            isValid = false;
-            errorDetails.append("[space found at position " + (fieldStr.indexOf(' ') + 1) + "]");
-        }
-        if (fieldStr.indexOf('"') >= 0) {
-            isValid = false;
-            errorDetails.append("[double-quote found at position " + (fieldStr.indexOf('"') + 1) + "]");
-        }
-        if (fieldStr.indexOf('\'') >= 0) {
-            isValid = false;
-            errorDetails.append("[single-quote found at position " + (fieldStr.indexOf('\'') + 1) + "]");
-        }
-        if (fieldStr.indexOf('&') >= 0) {
-            isValid = false;
-            errorDetails.append("[ampersand found at position " + (fieldStr.indexOf('&') + 1) + "]");
-        }
-        if (fieldStr.indexOf('?') >= 0) {
-            isValid = false;
-            errorDetails.append("[question mark found at position " + (fieldStr.indexOf('?') + 1) + "]");
-        }
-        if (fieldStr.indexOf('<') >= 0) {
-            isValid = false;
-            errorDetails.append("[less-than sign found at position " + (fieldStr.indexOf('<') + 1) + "]");
-        }
-        if (fieldStr.indexOf('>') >= 0) {
-            isValid = false;
-            errorDetails.append("[greater-than sign found at position " + (fieldStr.indexOf('>') + 1) + "]");
-        }
-        if (fieldStr.indexOf('\\') >= 0) {
-            isValid = false;
-            errorDetails.append("[back-slash found at position " + (fieldStr.indexOf('\\') + 1) + "]");
-        }
-        if (fieldStr.indexOf('/') >= 0) {
-            isValid = false;
-            errorDetails.append("[forward-slash found at position " + (fieldStr.indexOf('/') + 1) + "]");
-        }
+        isValid = UtilValidate.isValidDatabaseId(fieldStr, errorDetails);
 
         if (!isValid) {
             this.addMessage(messages, methodContext, "The ID value in the field [" + fieldAcsr + "] was not valid", ": " + errorDetails.toString());

Modified: ofbiz/trunk/framework/service/config/serviceengine.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/config/serviceengine.xml?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/config/serviceengine.xml (original)
+++ ofbiz/trunk/framework/service/config/serviceengine.xml Wed Jul 23 03:24:58 2008
@@ -41,6 +41,7 @@
 
         <!-- Service Engine Configuration -->
         <engine name="bsh" class="org.ofbiz.service.engine.BeanShellEngine"/>
+        <engine name="entity-auto" class="org.ofbiz.service.engine.EntityAutoEngine"/>
         <engine name="groovy" class="org.ofbiz.service.engine.GroovyEngine"/>
         <engine name="group" class="org.ofbiz.service.group.ServiceGroupEngine"/>
         <engine name="http" class="org.ofbiz.service.engine.HttpEngine"/>

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelParam.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelParam.java?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelParam.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelParam.java Wed Jul 23 03:24:58 2008
@@ -131,6 +131,14 @@
         return this.mode;
     }
     
+    public boolean isIn() {
+        return "IN".equals(this.mode) || "INOUT".equals(this.mode);
+    }
+    
+    public boolean isOut() {
+        return "OUT".equals(this.mode) || "INOUT".equals(this.mode);
+    }
+    
     public boolean isOptional() {
         return this.optional;
     }

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelService.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelService.java?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelService.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/ModelService.java Wed Jul 23 03:24:58 2008
@@ -337,8 +337,7 @@
         Set<String> nameList = new TreeSet<String>();
         for (ModelParam p: this.contextParamList) {
             // don't include OUT parameters in this list, only IN and INOUT
-            if ("OUT".equals(p.mode)) continue;
-            nameList.add(p.name);
+            if (p.isIn()) nameList.add(p.name);
         }
         return nameList;
     }
@@ -349,8 +348,7 @@
 
         for (ModelParam p: this.contextParamList) {
             // don't include OUT parameters in this list, only IN and INOUT
-            if ("OUT".equals(p.mode) || p.internal) continue;
-            count++;
+            if (p.isIn() && !p.internal) count++;
         }
 
         return count;
@@ -360,8 +358,7 @@
         Set<String> nameList = new TreeSet<String>();
         for (ModelParam p: this.contextParamList) {
             // don't include IN parameters in this list, only OUT and INOUT
-            if ("IN".equals(p.mode)) continue;
-            nameList.add(p.name);
+            if (p.isOut()) nameList.add(p.name);
         }
         return nameList;
     }
@@ -372,8 +369,7 @@
 
         for (ModelParam p: this.contextParamList) {
             // don't include IN parameters in this list, only OUT and INOUT
-            if ("IN".equals(p.mode) || p.internal) continue;
-            count++;
+            if (p.isOut() && !p.internal) count++;
         }
 
         return count;

Added: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java?rev=679058&view=auto
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java (added)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java Wed Jul 23 03:24:58 2008
@@ -0,0 +1,260 @@
+/*
+ * 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.service.engine;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.finder.PrimaryKeyFinder;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.ModelParam;
+import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceDispatcher;
+import org.ofbiz.service.ServiceUtil;
+
+/**
+ * Standard Java Static Method Service Engine
+ */
+public final class EntityAutoEngine extends GenericAsyncEngine {
+
+    public static final String module = EntityAutoEngine.class.getName();
+
+    public EntityAutoEngine(ServiceDispatcher dispatcher) {
+        super(dispatcher);
+    }
+
+    /**
+     * @see org.ofbiz.service.engine.GenericEngine#runSyncIgnore(java.lang.String, org.ofbiz.service.ModelService, java.util.Map)
+     */
+    public void runSyncIgnore(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
+        runSync(localName, modelService, context);
+    }
+
+    /**
+     * @see org.ofbiz.service.engine.GenericEngine#runSync(java.lang.String, org.ofbiz.service.ModelService, java.util.Map)
+     */
+    public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
+        // static java service methods should be: public Map<String, Object> methodName(DispatchContext dctx, Map<String, Object> context)
+        DispatchContext dctx = dispatcher.getLocalContext(localName);
+
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+
+        // check the package and method names
+        if (modelService.invoke == null || (!"create".equals(modelService.invoke) && !"update".equals(modelService.invoke) && !"delete".equals(modelService.invoke))) {
+            throw new GenericServiceException("In Service [" + modelService.name + "] the invoke value must be create, update, or delete for entity-auto engine");
+        }
+        
+        if (UtilValidate.isEmpty(modelService.defaultEntityName)) {
+            throw new GenericServiceException("In Service [" + modelService.name + "] you must specify a default-entity-name for entity-auto engine");
+        }
+        
+        ModelEntity modelEntity = dctx.getDelegator().getModelEntity(modelService.defaultEntityName);
+        if (modelEntity == null) {
+            throw new GenericServiceException("In Service [" + modelService.name + "] the specified default-entity-name [" + modelService.defaultEntityName + "] is not valid");
+        }
+        
+        try {
+            boolean allPksInOnly = true;
+            for (ModelField pkField: modelEntity.getPkFieldsUnmodifiable()) {
+                ModelParam pkParam = modelService.getParam(pkField.getName());
+                if (pkParam.isOut()) {
+                    allPksInOnly = false;
+                }
+            }
+            
+            if ("create".equals(modelService.invoke)) {
+                GenericValue newEntity = dctx.getDelegator().makeValue(modelEntity.getEntityName());
+                
+                boolean isSinglePk = modelEntity.getPksSize() == 1;
+                boolean isDoublePk = modelEntity.getPksSize() == 2;
+                Iterator<ModelField> pksIter = modelEntity.getPksIterator();
+                
+                ModelField singlePkModeField = isSinglePk ? pksIter.next() : null;
+                ModelParam singlePkModelParam = isSinglePk ? modelService.getParam(singlePkModeField.getName()) : null;
+                boolean isSinglePkIn = isSinglePk ? singlePkModelParam.isIn() : false;
+                boolean isSinglePkOut = isSinglePk ? singlePkModelParam.isOut() : false;
+                
+                ModelParam doublePkPrimaryInParam = null;
+                ModelParam doublePkSecondaryOutParam = null;
+                ModelField doublePkSecondaryOutField = null;
+                if (isDoublePk) {
+                    ModelField firstPkField = pksIter.next();
+                    ModelParam firstPkParam = modelService.getParam(firstPkField.getName());
+                    ModelField secondPkField = pksIter.next();
+                    ModelParam secondPkParam = modelService.getParam(secondPkField.getName());
+                    if (firstPkParam.isIn() && secondPkParam.isOut()) {
+                        doublePkPrimaryInParam = firstPkParam;
+                        doublePkSecondaryOutParam = secondPkParam;
+                        doublePkSecondaryOutField = secondPkField;
+                    } else if (firstPkParam.isOut() && secondPkParam.isIn()) {
+                        doublePkPrimaryInParam = secondPkParam;
+                        doublePkSecondaryOutParam = firstPkParam;
+                        doublePkSecondaryOutField = firstPkField;
+                    } else {
+                        // we don't have an IN and an OUT... so do nothing and leave them null
+                    }
+                }
+                
+                
+                if (isSinglePk && isSinglePkOut && !isSinglePkIn) {
+                    /*
+                     **** primary sequenced primary key ****
+                     *
+                    <auto-attributes include="pk" mode="OUT" optional="false"/>
+                     *
+                    <make-value entity-name="Example" value-name="newEntity"/>
+                    <sequenced-id-to-env sequence-name="Example" env-name="newEntity.exampleId"/> <!-- get the next sequenced ID -->
+                    <field-to-result field-name="newEntity.exampleId" result-name="exampleId"/>
+                    <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
+                    <create-value value-name="newEntity"/>
+                     *
+                     */
+                    
+                    String sequencedId = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
+                    newEntity.set(singlePkModeField.getName(), sequencedId);
+                    result.put(singlePkModelParam.name, sequencedId);
+                } else if (isSinglePk && isSinglePkOut && isSinglePkIn) {
+                    /*
+                     **** primary sequenced key with optional override passed in ****
+                     *
+                    <auto-attributes include="pk" mode="INOUT" optional="true"/>
+                     *
+                    <make-value value-name="newEntity" entity-name="Product"/>
+                    <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
+                    <set from-field="parameters.productId" field="newEntity.productId"/>
+                    <if-empty field="newEntity.productId">
+                        <sequenced-id-to-env sequence-name="Product" env-name="newEntity.productId"/>
+                    <else>
+                        <check-id field-name="productId" map-name="newEntity"/>
+                        <check-errors/>
+                    </else>
+                    </if-empty>
+                    <field-to-result field-name="productId" map-name="newEntity" result-name="productId"/>
+                    <create-value value-name="newEntity"/>
+                     *
+                     */
+
+                    Object pkValue = context.get(singlePkModelParam.name);
+                    if (UtilValidate.isEmpty(pkValue)) {
+                        pkValue = dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
+                    } else {
+                        // pkValue passed in, check and if there are problems return an error
+                        
+                        if (pkValue instanceof String) {
+                            StringBuffer errorDetails = new StringBuffer();
+                            if (!UtilValidate.isValidDatabaseId((String) pkValue, errorDetails)) {
+                                return ServiceUtil.returnError("The ID value in the parameter [" + singlePkModelParam.name + "] was not valid: " + errorDetails);
+                            }
+                        }
+                    }
+                    newEntity.set(singlePkModeField.getName(), pkValue);
+                    result.put(singlePkModelParam.name, pkValue);
+                } else if (isDoublePk && doublePkPrimaryInParam != null && doublePkSecondaryOutParam != null) {
+                    /*
+                     **** secondary sequenced primary key ****
+                     *
+                    <auto-attributes include="pk" mode="IN" optional="false"/>
+                    <override name="exampleItemSeqId" mode="OUT"/> <!-- make this OUT rather than IN, we will automatically generate the next sub-sequence ID -->
+                     *
+                    <make-value entity-name="ExampleItem" value-name="newEntity"/>
+                    <set-pk-fields map-name="parameters" value-name="newEntity"/>
+                    <make-next-seq-id value-name="newEntity" seq-field-name="exampleItemSeqId"/> <!-- this finds the next sub-sequence ID -->
+                    <field-to-result field-name="newEntity.exampleItemSeqId" result-name="exampleItemSeqId"/>
+                    <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
+                    <create-value value-name="newEntity"/>  
+                     */
+                    
+                    newEntity.setPKFields(context, true);
+                    dctx.getDelegator().setNextSubSeqId(newEntity, doublePkSecondaryOutField.getName(), 5, 1);
+                    result.put(doublePkSecondaryOutParam.name, newEntity.get(doublePkSecondaryOutField.getName()));
+                } else if (allPksInOnly) {
+                    /*
+                     **** plain specified primary key ****
+                     *
+                    <auto-attributes include="pk" mode="IN" optional="false"/>
+                     *
+                    <make-value entity-name="Example" value-name="newEntity"/>
+                    <set-pk-fields map-name="parameters" value-name="newEntity"/>
+                    <set-nonpk-fields map-name="parameters" value-name="newEntity"/>
+                    <create-value value-name="newEntity"/>
+                     *
+                     */
+                    newEntity.setPKFields(context, true);
+                } else {
+                    throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the create invoke option: " +
+                     "could not find a valid combination of primary key settings to do a known create operation; options include: " +
+                     "1. a single OUT pk for primary auto-sequencing, " +
+                     "2. a single INOUT pk for primary auto-sequencing with optional override, " +
+                     "3. a 2-part pk with one part IN (existing primary pk) and one part OUT (the secdonary pk to sub-sequence, " +
+                     "4. all pk fields are IN for a manually specified primary key");
+                }
+                
+                newEntity.setNonPKFields(context, true);
+                newEntity.create();
+            } else if ("update".equals(modelService.invoke)) {
+                /*
+                <auto-attributes include="pk" mode="IN" optional="false"/>
+                 *
+                <entity-one entity-name="ExampleItem" value-name="lookedUpValue"/>
+                <set-nonpk-fields value-name="lookedUpValue" map-name="parameters"/>
+                <store-value value-name="lookedUpValue"/>
+                 */
+                
+                // check to make sure that all primary key fields are defined as IN attributes
+                if (!allPksInOnly) {
+                    throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the update invoke option not all pk fields have the mode IN");
+                }
+
+                GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, context, dctx.getDelegator(), false, true, null, null);
+                lookedUpValue.setNonPKFields(context, true);
+                lookedUpValue.store();
+            } else if ("delete".equals(modelService.invoke)) {
+                /*
+                <auto-attributes include="pk" mode="IN" optional="false"/>
+                 *
+                <entity-one entity-name="ExampleItem" value-name="lookedUpValue"/>
+                <remove-value value-name="lookedUpValue"/>
+                 */
+                
+                // check to make sure that all primary key fields are defined as IN attributes
+                if (!allPksInOnly) {
+                    throw new GenericServiceException("In Service [" + modelService.name + "] which uses the entity-auto engine with the delete invoke option not all pk fields have the mode IN");
+                }
+                
+                GenericValue lookedUpValue = PrimaryKeyFinder.runFind(modelEntity, context, dctx.getDelegator(), false, true, null, null);
+                if (lookedUpValue != null) {
+                    lookedUpValue.remove();
+                }
+            }
+        } catch (GeneralException e) {
+            String errMsg = "Error doing entity-auto operation for entity [" + modelEntity.getEntityName() + "] in service [" + modelService.name + "]: " + e.toString();
+            Debug.logError(e, errMsg, module);
+            return ServiceUtil.returnError(errMsg);
+        }
+
+        return result;
+    }
+}

Propchange: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Propchange: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/StandardJavaEngine.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/StandardJavaEngine.java?rev=679058&r1=679057&r2=679058&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/StandardJavaEngine.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/StandardJavaEngine.java Wed Jul 23 03:24:58 2008
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*
  * 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
@@ -15,7 +15,7 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *******************************************************************************/
+ */
 package org.ofbiz.service.engine;
 
 import java.lang.reflect.InvocationTargetException;
@@ -54,7 +54,7 @@
         Object result = serviceInvoker(localName, modelService, context);
 
         if (result == null || !(result instanceof Map)) {
-            throw new GenericServiceException("Service did not return expected result");
+            throw new GenericServiceException("Service [" + modelService.name + "] did not return a Map object");
         }
         return UtilGenerics.checkMap(result);
     }
@@ -78,7 +78,7 @@
 
         // check the package and method names
         if (modelService.location == null || modelService.invoke == null) {
-            throw new GenericServiceException("Cannot locate service to invoke (location or invoke name missing)");
+            throw new GenericServiceException("Service [" + modelService.name + "] is missing location and/or invoke values which are required for execution.");
         }
 
         // get the classloader to use
@@ -95,23 +95,23 @@
             Method m = c.getMethod(modelService.invoke, DispatchContext.class, Map.class);
             result = m.invoke(null, dctx, context);
         } catch (ClassNotFoundException cnfe) {
-            throw new GenericServiceException("Cannot find service location", cnfe);
+            throw new GenericServiceException("Cannot find service [" + modelService.name + "] location class", cnfe);
         } catch (NoSuchMethodException nsme) {
-            throw new GenericServiceException("Service method does not exist", nsme);
+            throw new GenericServiceException("Service [" + modelService.name + "] specified Java method (invoke attribute) does not exist", nsme);
         } catch (SecurityException se) {
-            throw new GenericServiceException("Access denied", se);
+            throw new GenericServiceException("Service [" + modelService.name + "] Access denied", se);
         } catch (IllegalAccessException iae) {
-            throw new GenericServiceException("Method not accessible", iae);
+            throw new GenericServiceException("Service [" + modelService.name + "] Method not accessible", iae);
         } catch (IllegalArgumentException iarge) {
-            throw new GenericServiceException("Invalid parameter match", iarge);
+            throw new GenericServiceException("Service [" + modelService.name + "] Invalid parameter match", iarge);
         } catch (InvocationTargetException ite) {
-            throw new GenericServiceException("Service target threw an unexpected exception", ite.getTargetException());
+            throw new GenericServiceException("Service [" + modelService.name + "] target threw an unexpected exception", ite.getTargetException());
         } catch (NullPointerException npe) {
-            throw new GenericServiceException("Specified object is null", npe);
+            throw new GenericServiceException("Service [" + modelService.name + "] ran into an unexpected null object", npe);
         } catch (ExceptionInInitializerError eie) {
-            throw new GenericServiceException("Initialization failed", eie);
+            throw new GenericServiceException("Service [" + modelService.name + "] Initialization failed", eie);
         } catch (Throwable th) {
-            throw new GenericServiceException("Error or nknown exception", th);
+            throw new GenericServiceException("Service [" + modelService.name + "] Error or unknown exception", th);
         }
 
         return result;