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; |
Free forum by Nabble | Edit this page |