Re: 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
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: 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/...

Jacopo Cappellato-3
Looks great!

Thanks,

Jacopo

On Jul 23, 2008, at 12:24 PM, [hidden email] wrote:

> 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;
>
>


smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: 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/...

Adrian Crum
Wow! This is a great idea - thanks David!

-Adrian

[hidden email] wrote:

> 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;
>
>
>