+1

David this is very good enhancement.
Thanks !!!

On Wed, Jul 23, 2008 at 4:09 PM, Jacopo Cappellato <
[EMAIL PROTECTED]> wrote:

> Looks great!
>
> Thanks,
>
> Jacopo
>
>
> On Jul 23, 2008, at 12:24 PM, [EMAIL PROTECTED] 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;
>>
>>
>>
>


-- 
Ashish Vijaywargiya
Indore, India
http://en.wikipedia.org/wiki/Indore

Reply via email to