You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2009/08/09 20:04:27 UTC
svn commit: r802567 [2/5] - in /ofbiz/trunk:
applications/order/src/org/ofbiz/order/shoppingcart/
applications/product/src/org/ofbiz/shipment/packing/
applications/product/src/org/ofbiz/shipment/verify/
applications/product/src/org/ofbiz/shipment/weigh...
Added: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java?rev=802567&view=auto
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java (added)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java Sun Aug 9 18:04:26 2009
@@ -0,0 +1,2726 @@
+/*
+ * 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.entity;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.GeneralRuntimeException;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.base.util.UtilFormatOut;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilXml;
+import org.ofbiz.base.util.cache.CacheLine;
+import org.ofbiz.base.util.cache.UtilCache;
+import org.ofbiz.entity.cache.Cache;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.condition.EntityConditionList;
+import org.ofbiz.entity.condition.EntityExpr;
+import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.config.DatasourceInfo;
+import org.ofbiz.entity.config.DelegatorInfo;
+import org.ofbiz.entity.config.EntityConfigUtil;
+import org.ofbiz.entity.datasource.GenericHelper;
+import org.ofbiz.entity.datasource.GenericHelperFactory;
+import org.ofbiz.entity.eca.EntityEcaHandler;
+import org.ofbiz.entity.model.DynamicViewEntity;
+import org.ofbiz.entity.model.ModelEntity;
+import org.ofbiz.entity.model.ModelEntityChecker;
+import org.ofbiz.entity.model.ModelField;
+import org.ofbiz.entity.model.ModelFieldType;
+import org.ofbiz.entity.model.ModelFieldTypeReader;
+import org.ofbiz.entity.model.ModelGroupReader;
+import org.ofbiz.entity.model.ModelKeyMap;
+import org.ofbiz.entity.model.ModelReader;
+import org.ofbiz.entity.model.ModelRelation;
+import org.ofbiz.entity.model.ModelViewEntity;
+import org.ofbiz.entity.serialize.SerializeException;
+import org.ofbiz.entity.serialize.XmlSerializer;
+import org.ofbiz.entity.transaction.GenericTransactionException;
+import org.ofbiz.entity.transaction.TransactionUtil;
+import org.ofbiz.entity.util.DistributedCacheClear;
+import org.ofbiz.entity.util.EntityCrypto;
+import org.ofbiz.entity.util.EntityFindOptions;
+import org.ofbiz.entity.util.EntityListIterator;
+import org.ofbiz.entity.util.SequenceUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+/**
+ * Implementation of the <code>GenericDelegator</code> interface. The class
+ * contains a reference to a shared instance of <code>DelegatorData</code> -
+ * making it possible to have per-thread instances of this class while
+ * sharing common delegator data.
+ */
+public class DelegatorImpl implements Cloneable, GenericDelegator {
+
+ protected static class EntityEcaRuleRunner<T> {
+ protected EntityEcaHandler<T> entityEcaHandler;
+ protected Map<String, List<T>> eventMap;
+
+ protected EntityEcaRuleRunner(EntityEcaHandler<T> entityEcaHandler, Map<String, List<T>> eventMap) {
+ this.entityEcaHandler = entityEcaHandler;
+ this.eventMap = eventMap;
+ }
+
+ protected void evalRules(String event, String currentOperation, GenericEntity value, boolean isError) throws GenericEntityException {
+ if (entityEcaHandler == null) {
+ return;
+ }
+ entityEcaHandler.evalRules(currentOperation, eventMap, event, value, isError);
+ }
+ }
+
+ private enum OperationType {
+ DELETE, INSERT, UPDATE
+ }
+
+ public class TestOperation {
+ private final OperationType operation;
+ private final GenericValue value;
+
+ public TestOperation(OperationType operation, GenericValue value) {
+ this.operation = operation;
+ this.value = value;
+ }
+
+ public OperationType getOperation() {
+ return operation;
+ }
+
+ public GenericValue getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * This flag is only here for lower level technical testing, it shouldn't be
+ * user configurable (or at least I don't think so yet); when true all
+ * operations without a transaction will be wrapped in one; seems to be
+ * necessary for some (all?) XA aware connection pools, and should improve
+ * overall stability and consistency
+ */
+ public static final boolean alwaysUseTransaction = true;
+
+ public static final String module = DelegatorImpl.class.getName();
+
+ protected static <T> EntityEcaRuleRunner<T> createEntityEcaRuleRunner(EntityEcaHandler<T> entityEcaHandler, String entityName) {
+ return new EntityEcaRuleRunner<T>(entityEcaHandler, entityEcaHandler != null ? entityEcaHandler.getEntityEventMap(entityName) : null);
+ }
+
+ protected final DelegatorData delegatorData;
+
+ protected Locale locale = Locale.getDefault();
+
+ private boolean testMode = false;
+
+ private List<TestOperation> testOperations = null;
+
+ private boolean testRollbackInProgress = false;
+
+ protected String sessionIdentifier = "";
+
+ protected String userIdentifier = "";
+
+ protected DelegatorImpl(DelegatorData delegatorData) {
+ this.delegatorData = delegatorData;
+ if (!delegatorData.initialized) {
+ synchronized (delegatorData) {
+ if (delegatorData.initialized) {
+ return;
+ }
+ // do the entity model check
+ List<String> warningList = FastList.newInstance();
+ Debug.logImportant("Doing entity definition check...", module);
+ try {
+ ModelEntityChecker.checkEntities(this, warningList);
+ } catch (GenericEntityException e) {
+ Debug.logError(e, "Error while checking entities: ", module);
+ }
+ if (warningList.size() > 0) {
+ Debug.logWarning("=-=-=-=-= Found " + warningList.size() + " warnings when checking the entity definitions:", module);
+ for (String warning : warningList) {
+ Debug.logWarning(warning, module);
+ }
+ }
+
+ // initialize helpers by group
+ Set<String> groupNames = getModelGroupReader().getGroupNames(this.delegatorData.delegatorName);
+ Iterator<String> groups = UtilMisc.toIterator(groupNames);
+ while (groups != null && groups.hasNext()) {
+ String groupName = groups.next();
+ String helperName = this.getGroupHelperName(groupName);
+
+ if (Debug.infoOn())
+ Debug.logInfo("Delegator \"" + this.delegatorData.delegatorName + "\" initializing helper \"" + helperName + "\" for entity group \"" + groupName + "\".", module);
+ TreeSet<String> helpersDone = new TreeSet<String>();
+ if (helperName != null && helperName.length() > 0) {
+ // make sure each helper is only loaded once
+ if (helpersDone.contains(helperName)) {
+ if (Debug.infoOn())
+ Debug.logInfo("Helper \"" + helperName + "\" already initialized, not re-initializing.", module);
+ continue;
+ }
+ helpersDone.add(helperName);
+ // pre-load field type defs, the return value is ignored
+ ModelFieldTypeReader.getModelFieldTypeReader(helperName);
+ // get the helper and if configured, do the datasource check
+ GenericHelper helper = GenericHelperFactory.getHelper(helperName);
+
+ DatasourceInfo datasourceInfo = EntityConfigUtil.getDatasourceInfo(helperName);
+ if (datasourceInfo.checkOnStart) {
+ if (Debug.infoOn())
+ Debug.logInfo("Doing database check as requested in entityengine.xml with addMissing=" + datasourceInfo.addMissingOnStart, module);
+ try {
+ helper.checkDataSource(this.getModelEntityMapByGroup(groupName), null, datasourceInfo.addMissingOnStart);
+ } catch (GenericEntityException e) {
+ Debug.logWarning(e, e.getMessage(), module);
+ }
+ }
+ }
+ }
+ // Let other instances know the shared data is ready to use
+ this.delegatorData.initialized = true;
+ // setup the crypto class
+ this.delegatorData.crypto = new EntityCrypto(this);
+
+ // time to do some tricks with manual class loading that resolves
+ // circular dependencies, like calling services...
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+ // if useDistributedCacheClear is false do nothing since the
+ // distributedCacheClear member field with a null value will cause the
+ // dcc code to do nothing
+ if (this.delegatorData.delegatorInfo.useDistributedCacheClear) {
+ // initialize the distributedCacheClear mechanism
+ String distributedCacheClearClassName = this.delegatorData.delegatorInfo.distributedCacheClearClassName;
+
+ try {
+ Class<?> dccClass = loader.loadClass(distributedCacheClearClassName);
+ this.delegatorData.distributedCacheClear = (DistributedCacheClear) dccClass.newInstance();
+ this.delegatorData.distributedCacheClear.setDelegator(this, this.delegatorData.delegatorInfo.distributedCacheClearUserLoginId);
+ } catch (ClassNotFoundException e) {
+ Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " was not found, distributed cache clearing will be disabled", module);
+ } catch (InstantiationException e) {
+ Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " could not be instantiated, distributed cache clearing will be disabled", module);
+ } catch (IllegalAccessException e) {
+ Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " could not be accessed (illegal), distributed cache clearing will be disabled", module);
+ } catch (ClassCastException e) {
+ Debug.logWarning(e, "DistributedCacheClear class with name " + distributedCacheClearClassName + " does not implement the DistributedCacheClear interface, distributed cache clearing will be disabled", module);
+ }
+ } else {
+ Debug.logInfo("Distributed Cache Clear System disabled for delegator [" + this.delegatorData.delegatorName + "]", module);
+ }
+
+ // setup the Entity ECA Handler
+ initEntityEcaHandler();
+ }
+ }
+ }
+
+ protected void absorbList(List<GenericValue> lst) {
+ if (lst == null)
+ return;
+ for (GenericValue value : lst) {
+ value.setDelegator(this);
+ }
+ }
+
+ public void clearAllCacheLinesByDummyPK(Collection<GenericPK> dummyPKs) {
+ if (dummyPKs == null)
+ return;
+ for (GenericEntity entity : dummyPKs) {
+ this.clearCacheLineFlexible(entity);
+ }
+ }
+
+ public void clearAllCacheLinesByValue(Collection<GenericValue> values) {
+ if (values == null)
+ return;
+ for (GenericValue value : values) {
+ this.clearCacheLine(value);
+ }
+ }
+
+ public void clearAllCaches() {
+ this.clearAllCaches(true);
+ }
+
+ public void clearAllCaches(boolean distribute) {
+ this.delegatorData.cache.clear();
+ if (distribute && this.delegatorData.distributedCacheClear != null) {
+ this.delegatorData.distributedCacheClear.clearAllCaches();
+ }
+ }
+
+ public void clearCacheLine(GenericPK primaryKey) {
+ this.clearCacheLine(primaryKey, true);
+ }
+
+ public void clearCacheLine(GenericPK primaryKey, boolean distribute) {
+ if (primaryKey == null)
+ return;
+
+ // if never cached, then don't bother clearing
+ if (primaryKey.getModelEntity().getNeverCache())
+ return;
+
+ this.delegatorData.cache.remove(primaryKey);
+
+ if (distribute && this.delegatorData.distributedCacheClear != null) {
+ this.delegatorData.distributedCacheClear.distributedClearCacheLine(primaryKey);
+ }
+ }
+
+ public void clearCacheLine(GenericValue value) {
+ this.clearCacheLine(value, true);
+ }
+
+ public void clearCacheLine(GenericValue value, boolean distribute) {
+ // TODO: make this a bit more intelligent by passing in the operation
+ // being done (create, update, remove) so we can not do unnecessary
+ // cache clears...
+ // for instance:
+ // on create don't clear by primary cache (and won't clear original
+ // values because there won't be any)
+ // on remove don't clear by and for new values, but do for original
+ // values
+
+ // Debug.logInfo("running clearCacheLine for value: " + value + ",
+ // distribute: " + distribute, module);
+ if (value == null)
+ return;
+
+ // if never cached, then don't bother clearing
+ if (value.getModelEntity().getNeverCache())
+ return;
+
+ this.delegatorData.cache.remove(value);
+
+ if (distribute && this.delegatorData.distributedCacheClear != null) {
+ this.delegatorData.distributedCacheClear.distributedClearCacheLine(value);
+ }
+ }
+
+ public void clearCacheLine(String entityName) {
+ this.delegatorData.cache.remove(entityName);
+ }
+
+ public void clearCacheLine(String entityName, Map<String, ? extends Object> fields) {
+ // if no fields passed, do the all cache quickly and return
+ if (fields == null) {
+ this.delegatorData.cache.remove(entityName);
+ return;
+ }
+
+ ModelEntity entity = this.getModelEntity(entityName);
+ if (entity == null) {
+ throw new IllegalArgumentException("[GenericDelegator.clearCacheLine] could not find entity for entityName: " + entityName);
+ }
+ // if never cached, then don't bother clearing
+ if (entity.getNeverCache())
+ return;
+
+ GenericValue dummyValue = GenericValue.create(entity, fields);
+ dummyValue.setDelegator(this);
+ this.clearCacheLineFlexible(dummyValue);
+ }
+
+ public void clearCacheLine(String entityName, Object... fields) {
+ clearCacheLine(entityName, UtilMisc.<String, Object> toMap(fields));
+ }
+
+ public void clearCacheLineByCondition(String entityName, EntityCondition condition) {
+ clearCacheLineByCondition(entityName, condition, true);
+ }
+
+ public void clearCacheLineByCondition(String entityName, EntityCondition condition, boolean distribute) {
+ if (entityName != null) {
+ // if never cached, then don't bother clearing
+ if (getModelEntity(entityName).getNeverCache())
+ return;
+
+ this.delegatorData.cache.remove(entityName, condition);
+
+ if (distribute && this.delegatorData.distributedCacheClear != null) {
+ this.delegatorData.distributedCacheClear.distributedClearCacheLineByCondition(entityName, condition);
+ }
+ }
+ }
+
+ public void clearCacheLineFlexible(GenericEntity dummyPK) {
+ this.clearCacheLineFlexible(dummyPK, true);
+ }
+
+ public void clearCacheLineFlexible(GenericEntity dummyPK, boolean distribute) {
+ if (dummyPK != null) {
+ // if never cached, then don't bother clearing
+ if (dummyPK.getModelEntity().getNeverCache())
+ return;
+
+ this.delegatorData.cache.remove(dummyPK);
+
+ if (distribute && this.delegatorData.distributedCacheClear != null) {
+ this.delegatorData.distributedCacheClear.distributedClearCacheLineFlexible(dummyPK);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void clearCacheValues(UtilCache cache, String entityName, EntityCondition condition) {
+ Iterator iterator = cache.cacheLineTable.values().iterator();
+ while (iterator.hasNext()) {
+ CacheLine line = (CacheLine) iterator.next();
+ GenericValue value = (GenericValue) line.getValue();
+ if (value != null && value.getEntityName().equals(entityName) && condition.entityMatches(value)) {
+ iterator.remove();
+ }
+ }
+ }
+
+ @Override
+ protected Object clone() {
+ return this.cloneDelegator(this.delegatorData.delegatorName);
+ }
+
+ public GenericDelegator cloneDelegator() {
+ return this.cloneDelegator(this.delegatorData.delegatorName);
+ }
+
+ public GenericDelegator cloneDelegator(String delegatorName) {
+ // creates an exact clone of the delegator; except for the sequencer
+ // note that this will not be cached and should be used only when
+ // needed to change something for single instance (use).
+ DelegatorImpl newDelegator = new DelegatorImpl((DelegatorData) this.delegatorData.clone());
+ newDelegator.delegatorData.delegatorName = delegatorName;
+ // In case this delegator is in testMode give it a reference to
+ // the rollback list
+ newDelegator.testOperations = this.testOperations;
+ // not setting the sequencer so that we have unique sequences.
+ newDelegator.delegatorData.sequencer = null;
+ return newDelegator;
+ }
+
+ public GenericValue create(GenericPK primaryKey) throws GenericEntityException {
+ return this.create(primaryKey, true);
+ }
+
+ public GenericValue create(GenericPK primaryKey, boolean doCacheClear) throws GenericEntityException {
+ if (primaryKey == null) {
+ throw new GenericEntityException("Cannot create from a null primaryKey");
+ }
+
+ return this.create(GenericValue.create(primaryKey), doCacheClear);
+ }
+
+ public GenericValue create(GenericValue value) throws GenericEntityException {
+ return this.create(value, true);
+ }
+
+ public GenericValue create(GenericValue value, boolean doCacheClear) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(value.getEntityName());
+ ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_CREATE, value, false);
+
+ if (value == null) {
+ throw new GenericEntityException("Cannot create a null value");
+ }
+ GenericHelper helper = getEntityHelper(value.getEntityName());
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_CREATE, value, false);
+
+ value.setDelegator(this);
+ this.encryptFields(value);
+
+ // if audit log on for any fields, save new value with no old value
+ // because it's a create
+ if (value != null && value.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(value, false, false);
+ }
+
+ value = helper.create(value);
+
+ if (testMode) {
+ storeForTestRollback(new TestOperation(OperationType.INSERT, value));
+ }
+ if (value != null) {
+ value.setDelegator(this);
+ if (value.lockEnabled()) {
+ refresh(value, doCacheClear);
+ } else {
+ if (doCacheClear) {
+ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_CREATE, value, false);
+ this.clearCacheLine(value);
+ }
+ }
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_CREATE, value, false);
+
+ return value;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in create operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public GenericValue create(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ if (entityName == null || fields == null) {
+ return null;
+ }
+ ModelEntity entity = this.getModelReader().getModelEntity(entityName);
+ GenericValue genericValue = GenericValue.create(entity, fields);
+
+ return this.create(genericValue, true);
+ }
+
+ public GenericValue create(String entityName, Object... fields) throws GenericEntityException {
+ return create(entityName, UtilMisc.<String, Object> toMap(fields));
+ }
+
+ protected void createEntityAuditLogAll(GenericValue value, boolean isUpdate, boolean isRemove) throws GenericEntityException {
+ for (ModelField mf : value.getModelEntity().getFieldsUnmodifiable()) {
+ if (mf.getEnableAuditLog()) {
+ createEntityAuditLogSingle(value, mf, isUpdate, isRemove);
+ }
+ }
+ }
+
+ protected void createEntityAuditLogSingle(GenericValue value, ModelField mf, boolean isUpdate, boolean isRemove) throws GenericEntityException {
+ if (value == null || mf == null || !mf.getEnableAuditLog() || this.testRollbackInProgress) {
+ return;
+ }
+
+ GenericValue entityAuditLog = this.makeValue("EntityAuditLog");
+ entityAuditLog.set("auditHistorySeqId", this.getNextSeqId("EntityAuditLog"));
+ entityAuditLog.set("changedEntityName", value.getEntityName());
+ entityAuditLog.set("changedFieldName", mf.getName());
+
+ String pkCombinedValueText = value.getPkShortValueString();
+ if (pkCombinedValueText.length() > 250) {
+ // uh-oh, the string is too long!
+ pkCombinedValueText = pkCombinedValueText.substring(0, 250);
+ }
+ entityAuditLog.set("pkCombinedValueText", pkCombinedValueText);
+
+ GenericValue oldGv = null;
+ if (isUpdate) {
+ // it's an update, get it from the database
+ oldGv = this.findOne(value.getEntityName(), value.getPrimaryKey(), false);
+ } else if (isRemove) {
+ oldGv = value;
+ }
+ if (oldGv == null) {
+ if (isUpdate || isRemove) {
+ entityAuditLog.set("oldValueText", "[ERROR] Old value not found even though it was an update or remove");
+ }
+ } else {
+ // lookup old value
+ String oldValueText = null;
+ Object oldValue = oldGv.get(mf.getName());
+ if (oldValue != null) {
+ oldValueText = oldValue.toString();
+ if (oldValueText.length() > 250) {
+ oldValueText = oldValueText.substring(0, 250);
+ }
+ }
+ entityAuditLog.set("oldValueText", oldValueText);
+ }
+
+ if (!isRemove) {
+ String newValueText = null;
+ Object newValue = value.get(mf.getName());
+ if (newValue != null) {
+ newValueText = newValue.toString();
+ if (newValueText.length() > 250) {
+ newValueText = newValueText.substring(0, 250);
+ }
+ }
+ entityAuditLog.set("newValueText", newValueText);
+ }
+
+ entityAuditLog.set("changedDate", UtilDateTime.nowTimestamp());
+ entityAuditLog.set("changedByInfo", this.userIdentifier);
+ entityAuditLog.set("changedSessionInfo", this.sessionIdentifier);
+
+ this.create(entityAuditLog);
+ }
+
+ public GenericValue createOrStore(GenericValue value) throws GenericEntityException {
+ return createOrStore(value, true);
+ }
+
+ public GenericValue createOrStore(GenericValue value, boolean doCacheClear) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ GenericValue checkValue = this.findOne(value.getEntityName(), value.getPrimaryKey(), false);
+ if (checkValue != null) {
+ this.store(value, doCacheClear);
+ } else {
+ this.create(value, doCacheClear);
+ }
+ if (value.lockEnabled()) {
+ this.refresh(value);
+ }
+
+ return value;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in createOrStore operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public GenericValue createSetNextSeqId(GenericValue value) throws GenericEntityException {
+ boolean doCacheClear = true;
+
+ GenericHelper helper = getEntityHelper(value.getEntityName());
+ // just make sure it is this delegator...
+ value.setDelegator(this);
+ // this will throw an IllegalArgumentException if the entity for the
+ // value does not have one pk field, or if it already has a value set
+ // for the one pk field
+ value.setNextSeqId();
+
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(value.getEntityName());
+ ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_CREATE, value, false);
+
+ if (value == null) {
+ throw new GenericEntityException("Cannot create a null value");
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_CREATE, value, false);
+
+ value.setDelegator(this);
+ this.encryptFields(value);
+
+ // if audit log on for any fields, save new value with no old value
+ // because it's a create
+ if (value != null && value.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(value, false, false);
+ }
+
+ try {
+ value = helper.create(value);
+
+ if (testMode) {
+ storeForTestRollback(new TestOperation(OperationType.INSERT, value));
+ }
+ } catch (GenericEntityException e) {
+ // see if this was caused by an existing record before resetting
+ // the sequencer and trying again
+ // NOTE: use the helper directly so ECA rules, etc won't be run
+ GenericValue existingValue = helper.findByPrimaryKey(value.getPrimaryKey());
+ if (existingValue == null) {
+ throw e;
+ } else {
+ Debug.logInfo("Error creating entity record with a sequenced value [" + value.getPrimaryKey() + "], trying again about to refresh bank for entity [" + value.getEntityName() + "]", module);
+
+ // found an existing value... was probably a duplicate key,
+ // so clean things up and try again
+ this.delegatorData.sequencer.forceBankRefresh(value.getEntityName(), 1);
+
+ value.setNextSeqId();
+ value = helper.create(value);
+ Debug.logInfo("Successfully created new entity record on retry with a sequenced value [" + value.getPrimaryKey() + "], after getting refreshed bank for entity [" + value.getEntityName() + "]", module);
+
+ if (testMode) {
+ storeForTestRollback(new TestOperation(OperationType.INSERT, value));
+ }
+ }
+ }
+
+ if (value != null) {
+ value.setDelegator(this);
+ if (value.lockEnabled()) {
+ refresh(value, doCacheClear);
+ } else {
+ if (doCacheClear) {
+ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_CREATE, value, false);
+ this.clearCacheLine(value);
+ }
+ }
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_CREATE, value, false);
+
+ return value;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in create operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public GenericValue createSingle(String entityName, Object singlePkValue) throws GenericEntityException {
+ if (entityName == null || singlePkValue == null) {
+ return null;
+ }
+ ModelEntity entity = this.getModelReader().getModelEntity(entityName);
+ GenericValue genericValue = GenericValue.create(entity, singlePkValue);
+
+ return this.create(genericValue, true);
+ }
+
+ public void decryptFields(GenericEntity entity) throws GenericEntityException {
+ ModelEntity model = entity.getModelEntity();
+ String entityName = model.getEntityName();
+
+ Iterator<ModelField> i = model.getFieldsIterator();
+ while (i.hasNext()) {
+ ModelField field = i.next();
+ if (field.getEncrypt()) {
+ String keyName = entityName;
+ if (model instanceof ModelViewEntity) {
+ ModelViewEntity modelView = (ModelViewEntity) model;
+ keyName = modelView.getAliasedEntity(modelView.getAlias(field.getName()).getEntityAlias(), this.delegatorData.modelReader).getEntityName();
+ }
+
+ String encHex = (String) entity.get(field.getName());
+ if (UtilValidate.isNotEmpty(encHex)) {
+ try {
+ entity.dangerousSetNoCheckButFast(field, this.delegatorData.crypto.decrypt(keyName, encHex));
+ } catch (EntityCryptoException e) {
+ // not fatal -- allow returning of the encrypted value
+ Debug.logWarning(e, "Problem decrypting field [" + entityName + " / " + field.getName() + "]", module);
+ }
+ }
+ }
+ }
+ }
+
+ public void decryptFields(List<? extends GenericEntity> entities) throws GenericEntityException {
+ if (entities != null) {
+ for (GenericEntity entity : entities) {
+ this.decryptFields(entity);
+ }
+ }
+ }
+
+ public void encryptFields(GenericEntity entity) throws GenericEntityException {
+ ModelEntity model = entity.getModelEntity();
+ String entityName = model.getEntityName();
+
+ Iterator<ModelField> i = model.getFieldsIterator();
+ while (i.hasNext()) {
+ ModelField field = i.next();
+ if (field.getEncrypt()) {
+ Object obj = entity.get(field.getName());
+ if (obj != null) {
+ if (obj instanceof String && UtilValidate.isEmpty((String) obj)) {
+ continue;
+ }
+ entity.dangerousSetNoCheckButFast(field, this.encryptFieldValue(entityName, obj));
+ }
+ }
+ }
+ }
+
+ public void encryptFields(List<? extends GenericEntity> entities) throws GenericEntityException {
+ if (entities != null) {
+ for (GenericEntity entity : entities) {
+ this.encryptFields(entity);
+ }
+ }
+ }
+
+ public Object encryptFieldValue(String entityName, Object fieldValue) throws EntityCryptoException {
+ if (fieldValue != null) {
+ if (fieldValue instanceof String && UtilValidate.isEmpty((String) fieldValue)) {
+ return fieldValue;
+ }
+ return this.delegatorData.crypto.encrypt(entityName, fieldValue);
+ }
+ return fieldValue;
+ }
+
+ public EntityListIterator find(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Set<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException {
+
+ // if there is no transaction throw an exception, we don't want to
+ // create a transaction here since closing it would mess up the ELI
+ if (!TransactionUtil.isTransactionInPlace()) {
+ // throw new GenericEntityException("ERROR: Cannot do a find that
+ // returns an EntityListIterator with no transaction in place. Wrap
+ // this call in a transaction.");
+
+ // throwing an exception is a little harsh for now, just display a
+ // really big error message since we want to get all of these
+ // fixed...
+ Exception newE = new Exception("Stack Trace");
+ Debug.logError(newE, "ERROR: Cannot do a find that returns an EntityListIterator with no transaction in place. Wrap this call in a transaction.", module);
+ }
+
+ ModelEntity modelEntity = getModelReader().getModelEntity(entityName);
+ GenericValue dummyValue = GenericValue.create(modelEntity);
+ EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(modelEntity.getEntityName());
+ ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_FIND, dummyValue, false);
+
+ if (whereEntityCondition != null) {
+ whereEntityCondition.checkCondition(modelEntity);
+ whereEntityCondition.encryptConditionFields(modelEntity, this);
+ }
+ if (havingEntityCondition != null) {
+ havingEntityCondition.checkCondition(modelEntity);
+ havingEntityCondition.encryptConditionFields(modelEntity, this);
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, dummyValue, false);
+ GenericHelper helper = getEntityHelper(modelEntity.getEntityName());
+ EntityListIterator eli = helper.findListIteratorByCondition(modelEntity, whereEntityCondition, havingEntityCondition, fieldsToSelect, orderBy, findOptions);
+ eli.setDelegator(this);
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, dummyValue, false);
+ return eli;
+ }
+
+ public List<GenericValue> findAll(String entityName) throws GenericEntityException {
+ return this.findList(entityName, null, null, null, null, false);
+ }
+
+ public List<GenericValue> findAll(String entityName, List<String> orderBy) throws GenericEntityException {
+ return this.findList(entityName, null, null, orderBy, null, false);
+ }
+
+ public List<GenericValue> findAll(String entityName, String... orderBy) throws GenericEntityException {
+ return findList(entityName, null, null, Arrays.asList(orderBy), null, false);
+ }
+
+ public List<GenericValue> findAllByPrimaryKeys(Collection<GenericPK> primaryKeys) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ // TODO: add eca eval calls
+ // TODO: maybe this should use the internal findBy methods
+ if (primaryKeys == null)
+ return null;
+ List<GenericValue> results = FastList.newInstance();
+
+ // from the delegator level this is complicated because different
+ // GenericPK
+ // objects in the list may correspond to different helpers
+ Map<String, List<GenericPK>> pksPerHelper = FastMap.newInstance();
+ for (GenericPK curPK : primaryKeys) {
+ String helperName = this.getEntityHelperName(curPK.getEntityName());
+ List<GenericPK> pks = pksPerHelper.get(helperName);
+
+ if (pks == null) {
+ pks = FastList.newInstance();
+ pksPerHelper.put(helperName, pks);
+ }
+ pks.add(curPK);
+ }
+
+ for (Map.Entry<String, List<GenericPK>> curEntry : pksPerHelper.entrySet()) {
+ String helperName = curEntry.getKey();
+ GenericHelper helper = GenericHelperFactory.getHelper(helperName);
+ List<GenericValue> values = helper.findAllByPrimaryKeys(curEntry.getValue());
+
+ results.addAll(values);
+ }
+
+ this.decryptFields(results);
+ return results;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findAllByPrimaryKeys operation, rolling back transaction";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public List<GenericValue> findAllByPrimaryKeysCache(Collection<GenericPK> primaryKeys) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ // TODO: add eca eval calls
+ // TODO: maybe this should use the internal findBy methods
+ if (primaryKeys == null)
+ return null;
+ List<GenericValue> results = FastList.newInstance();
+
+ // from the delegator level this is complicated because different
+ // GenericPK
+ // objects in the list may correspond to different helpers
+ Map<String, List<GenericPK>> pksPerHelper = FastMap.newInstance();
+ for (GenericPK curPK : primaryKeys) {
+ GenericValue value = this.getFromPrimaryKeyCache(curPK);
+
+ if (value != null) {
+ // it is in the cache, so just put the cached value in the
+ // results
+ results.add(value);
+ } else {
+ // is not in the cache, so put in a list for a call to the
+ // helper
+ String helperName = this.getEntityHelperName(curPK.getEntityName());
+ List<GenericPK> pks = pksPerHelper.get(helperName);
+
+ if (pks == null) {
+ pks = FastList.newInstance();
+ pksPerHelper.put(helperName, pks);
+ }
+ pks.add(curPK);
+ }
+ }
+
+ for (Map.Entry<String, List<GenericPK>> curEntry : pksPerHelper.entrySet()) {
+ String helperName = curEntry.getKey();
+ GenericHelper helper = GenericHelperFactory.getHelper(helperName);
+ List<GenericValue> values = helper.findAllByPrimaryKeys(curEntry.getValue());
+
+ this.putAllInPrimaryKeyCache(values);
+ results.addAll(values);
+ }
+
+ this.decryptFields(results);
+ return results;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findAllByPrimaryKeysCache operation, rolling back transaction";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public List<GenericValue> findAllCache(String entityName) throws GenericEntityException {
+ return this.findList(entityName, null, null, null, null, true);
+ }
+
+ public List<GenericValue> findAllCache(String entityName, List<String> orderBy) throws GenericEntityException {
+ return this.findList(entityName, null, null, orderBy, null, true);
+ }
+
+ public List<GenericValue> findAllCache(String entityName, String... orderBy) throws GenericEntityException {
+ return findList(entityName, null, null, Arrays.asList(orderBy), null, true);
+ }
+
+ public <T extends EntityCondition> List<GenericValue> findByAnd(String entityName, List<T> expressions) throws GenericEntityException {
+ EntityConditionList<T> ecl = EntityCondition.makeCondition(expressions, EntityOperator.AND);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public <T extends EntityCondition> List<GenericValue> findByAnd(String entityName, List<T> expressions, List<String> orderBy) throws GenericEntityException {
+ EntityConditionList<T> ecl = EntityCondition.makeCondition(expressions, EntityOperator.AND);
+ return this.findList(entityName, ecl, null, orderBy, null, false);
+ }
+
+ public List<GenericValue> findByAnd(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ EntityCondition ecl = EntityCondition.makeCondition(fields);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public List<GenericValue> findByAnd(String entityName, Map<String, ? extends Object> fields, List<String> orderBy) throws GenericEntityException {
+ EntityCondition ecl = EntityCondition.makeCondition(fields);
+ return this.findList(entityName, ecl, null, orderBy, null, false);
+ }
+
+ public List<GenericValue> findByAnd(String entityName, Object... fields) throws GenericEntityException {
+ return findByAnd(entityName, UtilMisc.<String, Object> toMap(fields));
+ }
+
+ public <T extends EntityCondition> List<GenericValue> findByAnd(String entityName, T... expressions) throws GenericEntityException {
+ EntityConditionList<T> ecl = EntityCondition.makeCondition(EntityOperator.AND, expressions);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public List<GenericValue> findByAndCache(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ return this.findList(entityName, EntityCondition.makeCondition(fields), null, null, null, true);
+ }
+
+ public List<GenericValue> findByAndCache(String entityName, Map<String, ? extends Object> fields, List<String> orderBy) throws GenericEntityException {
+ return this.findList(entityName, EntityCondition.makeCondition(fields), null, orderBy, null, true);
+ }
+
+ public List<GenericValue> findByAndCache(String entityName, Object... fields) throws GenericEntityException {
+ return this.findByAndCache(entityName, UtilMisc.<String, Object> toMap(fields));
+ }
+
+ public List<GenericValue> findByCondition(String entityName, EntityCondition entityCondition, Collection<String> fieldsToSelect, List<String> orderBy) throws GenericEntityException {
+ return this.findList(entityName, entityCondition, UtilMisc.toSet(fieldsToSelect), orderBy, null, false);
+ }
+
+ public List<GenericValue> findByCondition(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Collection<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ EntityListIterator eli = this.find(entityName, whereEntityCondition, havingEntityCondition, UtilMisc.toSet(fieldsToSelect), orderBy, findOptions);
+ eli.setDelegator(this);
+ List<GenericValue> list = eli.getCompleteList();
+ eli.close();
+
+ return list;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findByCondition operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public List<GenericValue> findByConditionCache(String entityName, EntityCondition entityCondition, Collection<String> fieldsToSelect, List<String> orderBy) throws GenericEntityException {
+ return this.findList(entityName, entityCondition, UtilMisc.collectionToSet(fieldsToSelect), orderBy, null, true);
+ }
+
+ public List<GenericValue> findByLike(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ List<EntityExpr> likeExpressions = FastList.newInstance();
+ if (fields != null) {
+ for (Map.Entry<String, ? extends Object> fieldEntry : fields.entrySet()) {
+ likeExpressions.add(EntityCondition.makeCondition(fieldEntry.getKey(), EntityOperator.LIKE, fieldEntry.getValue()));
+ }
+ }
+ EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(likeExpressions, EntityOperator.AND);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public List<GenericValue> findByLike(String entityName, Map<String, ? extends Object> fields, List<String> orderBy) throws GenericEntityException {
+ List<EntityExpr> likeExpressions = FastList.newInstance();
+ if (fields != null) {
+ for (Map.Entry<String, ? extends Object> fieldEntry : fields.entrySet()) {
+ likeExpressions.add(EntityCondition.makeCondition(fieldEntry.getKey(), EntityOperator.LIKE, fieldEntry.getValue()));
+ }
+ }
+ EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(likeExpressions, EntityOperator.AND);
+ return this.findList(entityName, ecl, null, orderBy, null, false);
+ }
+
+ public List<GenericValue> findByLike(String entityName, Object... fields) throws GenericEntityException {
+ Map<String, ? extends Object> fieldMap = UtilMisc.<String, Object> toMap(fields);
+ List<EntityExpr> likeExpressions = FastList.newInstance();
+ if (fieldMap != null) {
+ for (Map.Entry<String, ? extends Object> fieldEntry : fieldMap.entrySet()) {
+ likeExpressions.add(EntityCondition.makeCondition(fieldEntry.getKey(), EntityOperator.LIKE, fieldEntry.getValue()));
+ }
+ }
+ EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(likeExpressions, EntityOperator.AND);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public <T extends EntityCondition> List<GenericValue> findByOr(String entityName, List<T> expressions) throws GenericEntityException {
+ EntityConditionList<T> ecl = EntityCondition.makeCondition(expressions, EntityOperator.OR);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public <T extends EntityCondition> List<GenericValue> findByOr(String entityName, List<T> expressions, List<String> orderBy) throws GenericEntityException {
+ EntityConditionList<T> ecl = EntityCondition.makeCondition(expressions, EntityOperator.OR);
+ return this.findList(entityName, ecl, null, orderBy, null, false);
+ }
+
+ public List<GenericValue> findByOr(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ EntityCondition ecl = EntityCondition.makeCondition(fields, EntityOperator.OR);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public List<GenericValue> findByOr(String entityName, Map<String, ? extends Object> fields, List<String> orderBy) throws GenericEntityException {
+ EntityCondition ecl = EntityCondition.makeCondition(fields, EntityOperator.OR);
+ return this.findList(entityName, ecl, null, orderBy, null, false);
+ }
+
+ public List<GenericValue> findByOr(String entityName, Object... fields) throws GenericEntityException {
+ EntityCondition ecl = EntityCondition.makeCondition(EntityOperator.OR, fields);
+ return this.findList(entityName, ecl, null, null, null, false);
+ }
+
+ public <T extends EntityCondition> List<GenericValue> findByOr(String entityName, T... expressions) throws GenericEntityException {
+ return this.findList(entityName, EntityCondition.makeCondition(EntityOperator.AND, expressions), null, null, null, false);
+ }
+
+ public GenericValue findByPrimaryKey(GenericPK primaryKey) throws GenericEntityException {
+ return findOne(primaryKey.getEntityName(), primaryKey, false);
+ }
+
+ public GenericValue findByPrimaryKey(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ return findOne(entityName, fields, false);
+ }
+
+ public GenericValue findByPrimaryKey(String entityName, Object... fields) throws GenericEntityException {
+ return findByPrimaryKey(entityName, UtilMisc.<String, Object> toMap(fields));
+ }
+
+ public GenericValue findByPrimaryKeyCache(GenericPK primaryKey) throws GenericEntityException {
+ return findOne(primaryKey.getEntityName(), primaryKey, true);
+ }
+
+ public GenericValue findByPrimaryKeyCache(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ return findOne(entityName, fields, true);
+ }
+
+ public GenericValue findByPrimaryKeyCache(String entityName, Object... fields) throws GenericEntityException {
+ return findByPrimaryKeyCache(entityName, UtilMisc.<String, Object> toMap(fields));
+ }
+
+ public GenericValue findByPrimaryKeyCacheSingle(String entityName, Object singlePkValue) throws GenericEntityException {
+ return findOne(entityName, makePKSingle(entityName, singlePkValue), true);
+ }
+
+ public GenericValue findByPrimaryKeyPartial(GenericPK primaryKey, Set<String> keys) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(primaryKey.getEntityName());
+ ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_FIND, primaryKey, false);
+
+ GenericHelper helper = getEntityHelper(primaryKey.getEntityName());
+ GenericValue value = null;
+
+ if (!primaryKey.isPrimaryKey()) {
+ throw new GenericModelException("[GenericDelegator.findByPrimaryKey] Passed primary key is not a valid primary key: " + primaryKey);
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, primaryKey, false);
+ try {
+ value = helper.findByPrimaryKeyPartial(primaryKey, keys);
+ } catch (GenericEntityNotFoundException e) {
+ value = null;
+ }
+ if (value != null)
+ value.setDelegator(this);
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, primaryKey, false);
+ return value;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findByPrimaryKeyPartial operation for entity [" + primaryKey.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public GenericValue findByPrimaryKeyPartial(GenericPK primaryKey, String... keys) throws GenericEntityException {
+ return findByPrimaryKeyPartial(primaryKey, UtilMisc.makeSetWritable(Arrays.asList(keys)));
+ }
+
+ public GenericValue findByPrimaryKeySingle(String entityName, Object singlePkValue) throws GenericEntityException {
+ return findOne(entityName, makePKSingle(entityName, singlePkValue), false);
+ }
+
+ public long findCountByAnd(String entityName) throws GenericEntityException {
+ return findCountByCondition(entityName, null, null, null);
+ }
+
+ public long findCountByAnd(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
+ return findCountByCondition(entityName, EntityCondition.makeCondition(fields, EntityOperator.AND), null, null);
+ }
+
+ public long findCountByAnd(String entityName, Object... fields) throws GenericEntityException {
+ return findCountByCondition(entityName, EntityCondition.makeCondition(UtilMisc.<String, Object> toMap(fields), EntityOperator.AND), null, null);
+ }
+
+ public long findCountByCondition(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition) throws GenericEntityException {
+ return findCountByCondition(entityName, whereEntityCondition, havingEntityCondition, null);
+ }
+
+ public long findCountByCondition(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, EntityFindOptions findOptions) throws GenericEntityException {
+
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ ModelEntity modelEntity = getModelReader().getModelEntity(entityName);
+ GenericValue dummyValue = GenericValue.create(modelEntity);
+ EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(modelEntity.getEntityName());
+ ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_FIND, dummyValue, false);
+
+ if (whereEntityCondition != null) {
+ whereEntityCondition.checkCondition(modelEntity);
+ whereEntityCondition.encryptConditionFields(modelEntity, this);
+ }
+ if (havingEntityCondition != null) {
+ havingEntityCondition.checkCondition(modelEntity);
+ havingEntityCondition.encryptConditionFields(modelEntity, this);
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, dummyValue, false);
+ GenericHelper helper = getEntityHelper(modelEntity.getEntityName());
+ long count = helper.findCountByCondition(modelEntity, whereEntityCondition, havingEntityCondition, findOptions);
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, dummyValue, false);
+ return count;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findListIteratorByCondition operation for entity [DynamicView]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public List<GenericValue> findList(String entityName, EntityCondition entityCondition, Set<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions, boolean useCache) throws GenericEntityException {
+
+ EntityEcaRuleRunner<?> ecaRunner = null;
+ GenericValue dummyValue = null;
+ if (useCache) {
+ ecaRunner = this.getEcaRuleRunner(entityName);
+ ModelEntity modelEntity = getModelReader().getModelEntity(entityName);
+ dummyValue = GenericValue.create(modelEntity);
+ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CHECK, EntityEcaHandler.OP_FIND, dummyValue, false);
+
+ List<GenericValue> cacheList = this.delegatorData.cache.get(entityName, entityCondition, orderBy);
+ if (cacheList != null) {
+ return cacheList;
+ }
+ }
+
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ EntityListIterator eli = this.find(entityName, entityCondition, null, fieldsToSelect, orderBy, findOptions);
+ eli.setDelegator(this);
+ List<GenericValue> list = eli.getCompleteList();
+ eli.close();
+
+ if (useCache) {
+ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_PUT, EntityEcaHandler.OP_FIND, dummyValue, false);
+ this.delegatorData.cache.put(entityName, entityCondition, orderBy, list);
+ }
+ return list;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findByCondition operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public EntityListIterator findListIteratorByCondition(DynamicViewEntity dynamicViewEntity, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Collection<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException {
+
+ // if there is no transaction throw an exception, we don't want to
+ // create a transaction here since closing it would mess up the ELI
+ if (!TransactionUtil.isTransactionInPlace()) {
+ // throw new GenericEntityException("ERROR: Cannot do a find that
+ // returns an EntityListIterator with no transaction in place. Wrap
+ // this call in a transaction.");
+
+ // throwing an exception is a little harsh for now, just display a
+ // really big error message since we want to get all of these
+ // fixed...
+ Exception newE = new Exception("Stack Trace");
+ Debug.logError(newE, "ERROR: Cannot do a find that returns an EntityListIterator with no transaction in place. Wrap this call in a transaction.", module);
+ }
+
+ ModelViewEntity modelViewEntity = dynamicViewEntity.makeModelViewEntity(this);
+ if (whereEntityCondition != null)
+ whereEntityCondition.checkCondition(modelViewEntity);
+ if (havingEntityCondition != null)
+ havingEntityCondition.checkCondition(modelViewEntity);
+
+ GenericHelper helper = getEntityHelper(dynamicViewEntity.getOneRealEntityName());
+ EntityListIterator eli = helper.findListIteratorByCondition(modelViewEntity, whereEntityCondition, havingEntityCondition, fieldsToSelect, orderBy, findOptions);
+ eli.setDelegator(this);
+ // TODO: add decrypt fields
+ return eli;
+ }
+
+ public EntityListIterator findListIteratorByCondition(String entityName, EntityCondition entityCondition, Collection<String> fieldsToSelect, List<String> orderBy) throws GenericEntityException {
+ return this.find(entityName, entityCondition, null, UtilMisc.collectionToSet(fieldsToSelect), orderBy, null);
+ }
+
+ public EntityListIterator findListIteratorByCondition(String entityName, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition, Collection<String> fieldsToSelect, List<String> orderBy, EntityFindOptions findOptions) throws GenericEntityException {
+
+ return this.find(entityName, whereEntityCondition, havingEntityCondition, UtilMisc.collectionToSet(fieldsToSelect), orderBy, findOptions);
+ }
+
+ public GenericValue findOne(String entityName, boolean useCache, Object... fields) throws GenericEntityException {
+ return findOne(entityName, UtilMisc.toMap(fields), useCache);
+ }
+
+ public GenericValue findOne(String entityName, Map<String, ? extends Object> fields, boolean useCache) throws GenericEntityException {
+ GenericPK primaryKey = this.makePK(entityName, fields);
+ EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(entityName);
+ if (useCache) {
+ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CHECK, EntityEcaHandler.OP_FIND, primaryKey, false);
+
+ GenericValue value = this.getFromPrimaryKeyCache(primaryKey);
+ if (value != null) {
+ return value;
+ }
+ }
+
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_FIND, primaryKey, false);
+
+ GenericHelper helper = getEntityHelper(entityName);
+ GenericValue value = null;
+
+ if (!primaryKey.isPrimaryKey()) {
+ throw new GenericModelException("[GenericDelegator.findOne] Passed primary key is not a valid primary key: " + primaryKey);
+ }
+ ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, primaryKey, false);
+ try {
+ value = helper.findByPrimaryKey(primaryKey);
+ } catch (GenericEntityNotFoundException e) {
+ value = null;
+ }
+ if (value != null) {
+ value.setDelegator(this);
+ this.decryptFields(value);
+ }
+
+ if (useCache) {
+ if (value != null) {
+ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_PUT, EntityEcaHandler.OP_FIND, value, false);
+ this.putInPrimaryKeyCache(primaryKey, value);
+ } else {
+ this.putInPrimaryKeyCache(primaryKey, GenericValue.NULL_VALUE);
+ }
+ }
+
+ ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, (value == null ? primaryKey : value), false);
+ return value;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in findOne operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one... this will throw
+ // an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public Cache getCache() {
+ return this.delegatorData.cache;
+ }
+
+ public GenericDelegator getDelegator(String delegatorName) {
+ return DelegatorFactory.getGenericDelegator(delegatorName);
+ }
+
+ protected DelegatorInfo getDelegatorInfo() {
+ return this.delegatorData.delegatorInfo;
+ }
+
+ public String getDelegatorName() {
+ return this.delegatorData.delegatorName;
+ }
+
+ protected EntityEcaRuleRunner<?> getEcaRuleRunner(String entityName) {
+ if (this.testRollbackInProgress)
+ return createEntityEcaRuleRunner(null, null);
+ return createEntityEcaRuleRunner(this.delegatorData.entityEcaHandler, entityName);
+ }
+
+ @SuppressWarnings("unchecked")
+ public EntityEcaHandler getEntityEcaHandler() {
+ return this.delegatorData.entityEcaHandler;
+ }
+
+ public ModelFieldType getEntityFieldType(ModelEntity entity, String type) throws GenericEntityException {
+ return this.getModelFieldTypeReader(entity).getModelFieldType(type);
+ }
+
+ public Collection<String> getEntityFieldTypeNames(ModelEntity entity) throws GenericEntityException {
+ String helperName = getEntityHelperName(entity);
+
+ if (helperName == null || helperName.length() <= 0)
+ return null;
+ ModelFieldTypeReader modelFieldTypeReader = ModelFieldTypeReader.getModelFieldTypeReader(helperName);
+
+ if (modelFieldTypeReader == null) {
+ throw new GenericEntityException("ModelFieldTypeReader not found for entity " + entity.getEntityName() + " with helper name " + helperName);
+ }
+ return modelFieldTypeReader.getFieldTypeNames();
+ }
+
+ public String getEntityGroupName(String entityName) {
+ return getModelGroupReader().getEntityGroupName(entityName, getOriginalDelegatorName());
+ }
+
+ public GenericHelper getEntityHelper(ModelEntity entity) throws GenericEntityException {
+ return getEntityHelper(entity.getEntityName());
+ }
+
+ public GenericHelper getEntityHelper(String entityName) throws GenericEntityException {
+ String helperName = getEntityHelperName(entityName);
+
+ if (helperName != null && helperName.length() > 0) {
+ return GenericHelperFactory.getHelper(helperName);
+ } else {
+ throw new GenericEntityException("There is no datasource (Helper) configured for the entity-group [" + this.getEntityGroupName(entityName) + "]; was trying to find datesource (helper) for entity [" + entityName + "]");
+ }
+ }
+
+ public String getEntityHelperName(ModelEntity entity) {
+ if (entity == null)
+ return null;
+ return getEntityHelperName(entity.getEntityName());
+ }
+
+ public String getEntityHelperName(String entityName) {
+ return this.getGroupHelperName(this.getEntityGroupName(entityName));
+ }
+
+ public GenericValue getFromPrimaryKeyCache(GenericPK primaryKey) {
+ if (primaryKey == null)
+ return null;
+ GenericValue value = (GenericValue) this.delegatorData.cache.get(primaryKey);
+ if (value == GenericValue.NULL_VALUE) {
+ return null;
+ }
+ return value;
+ }
+
+ public String getGroupHelperName(String groupName) {
+ return this.getDelegatorInfo().groupMap.get(groupName);
+ }
+
+ public Locale getLocale() {
+ return this.locale;
+ }
+
+ public ModelEntity getModelEntity(String entityName) {
+ try {
+ return getModelReader().getModelEntity(entityName);
+ } catch (GenericEntityException e) {
+ Debug.logError(e, "Error getting entity definition from model", module);
+ return null;
+ }
+ }
+
+ public Map<String, ModelEntity> getModelEntityMapByGroup(String groupName) throws GenericEntityException {
+ Set<String> entityNameSet = getModelGroupReader().getEntityNamesByGroup(groupName);
+
+ if (this.getDelegatorInfo().defaultGroupName.equals(groupName)) {
+ // add all entities with no group name to the Set
+ Set<String> allEntityNames = this.getModelReader().getEntityNames();
+ for (String entityName : allEntityNames) {
+ if (this.getDelegatorInfo().defaultGroupName.equals(getModelGroupReader().getEntityGroupName(entityName, getDelegatorName()))) {
+ entityNameSet.add(entityName);
+ }
+ }
+ }
+
+ Map<String, ModelEntity> entities = FastMap.newInstance();
+ if (entityNameSet == null || entityNameSet.size() == 0) {
+ return entities;
+ }
+
+ int errorCount = 0;
+ for (String entityName : entityNameSet) {
+ try {
+ ModelEntity entity = getModelReader().getModelEntity(entityName);
+ if (entity != null) {
+ entities.put(entity.getEntityName(), entity);
+ } else {
+ throw new IllegalStateException("Could not find entity with name " + entityName);
+ }
+ } catch (GenericEntityException ex) {
+ errorCount++;
+ Debug.logError("Entity [" + entityName + "] named in Entity Group with name " + groupName + " are not defined in any Entity Definition file", module);
+ }
+ }
+
+ if (errorCount > 0) {
+ Debug.logError(errorCount + " entities were named in ModelGroup but not defined in any EntityModel", module);
+ }
+
+ return entities;
+ }
+
+ public ModelFieldTypeReader getModelFieldTypeReader(ModelEntity entity) {
+ String helperName = getEntityHelperName(entity);
+ if (helperName == null || helperName.length() <= 0) {
+ return null;
+ }
+ ModelFieldTypeReader modelFieldTypeReader = ModelFieldTypeReader.getModelFieldTypeReader(helperName);
+ if (modelFieldTypeReader == null) {
+ throw new IllegalArgumentException("ModelFieldTypeReader not found for entity " + entity.getEntityName() + " with helper name " + helperName);
+ }
+ return modelFieldTypeReader;
+ }
+
+ public ModelGroupReader getModelGroupReader() {
+ return this.delegatorData.modelGroupReader;
+ }
+
+ public ModelReader getModelReader() {
+ return this.delegatorData.modelReader;
+ }
+
+ public List<GenericValue> getMultiRelation(GenericValue value, String relationNameOne, String relationNameTwo) throws GenericEntityException {
+ return getMultiRelation(value, relationNameOne, relationNameTwo, null);
+ }
+
+ public List<GenericValue> getMultiRelation(GenericValue value, String relationNameOne, String relationNameTwo, List<String> orderBy) throws GenericEntityException {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+ // TODO: add eca eval calls
+ // traverse the relationships
+ ModelEntity modelEntity = value.getModelEntity();
+ ModelRelation modelRelationOne = modelEntity.getRelation(relationNameOne);
+ ModelEntity modelEntityOne = getModelEntity(modelRelationOne.getRelEntityName());
+ ModelRelation modelRelationTwo = modelEntityOne.getRelation(relationNameTwo);
+ ModelEntity modelEntityTwo = getModelEntity(modelRelationTwo.getRelEntityName());
+
+ GenericHelper helper = getEntityHelper(modelEntity);
+
+ return helper.findByMultiRelation(value, modelRelationOne, modelEntityOne, modelRelationTwo, modelEntityTwo, orderBy);
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in getMultiRelation operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
+ Debug.logError(e, errMsg, module);
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // after rolling back, rethrow the exception
+ throw e;
+ } finally {
+ // only commit the transaction if we started one...
+ // this will throw an exception if it fails
+ TransactionUtil.commit(beganTransaction);
+ }
+ }
+
+ public String getNextSeqId(String seqName) {
+ return this.getNextSeqId(seqName, 1);
+ }
+
+ public String getNextSeqId(String seqName, long staggerMax) {
+ Long nextSeqLong = this.getNextSeqIdLong(seqName, staggerMax);
+
+ if (nextSeqLong == null) {
+ // NOTE: the getNextSeqIdLong method SHOULD throw a runtime
+ // exception when no sequence value is found, which means we
+ // should never see it get here
+ throw new IllegalArgumentException("Could not get next sequenced ID for sequence name: " + seqName);
+ }
+
+ if (UtilValidate.isNotEmpty(this.getDelegatorInfo().sequencedIdPrefix)) {
+ return this.getDelegatorInfo().sequencedIdPrefix + nextSeqLong.toString();
+ } else {
+ return nextSeqLong.toString();
+ }
+ }
+
+ public Long getNextSeqIdLong(String seqName) {
+ return this.getNextSeqIdLong(seqName, 1);
+ }
+
+ public Long getNextSeqIdLong(String seqName, long staggerMax) {
+ boolean beganTransaction = false;
+ try {
+ if (alwaysUseTransaction) {
+ beganTransaction = TransactionUtil.begin();
+ }
+
+ if (this.delegatorData.sequencer == null) {
+ synchronized (this.delegatorData) {
+ if (this.delegatorData.sequencer == null) {
+ String helperName = this.getEntityHelperName("SequenceValueItem");
+ ModelEntity seqEntity = this.getModelEntity("SequenceValueItem");
+ this.delegatorData.sequencer = new SequenceUtil(helperName, seqEntity, "seqName", "seqId");
+ }
+ }
+ }
+
+ // might be null, but will usually match the entity name
+ ModelEntity seqModelEntity = this.getModelEntity(seqName);
+
+ Long newSeqId = this.delegatorData.sequencer == null ? null : this.delegatorData.sequencer.getNextSeqId(seqName, staggerMax, seqModelEntity);
+
+ return newSeqId;
+ } catch (GenericEntityException e) {
+ String errMsg = "Failure in getNextSeqIdLong operation for seqName [" + seqName + "]: " + e.toString() + ". Rolling back transaction.";
+ try {
+ // only rollback the transaction if we started one...
+ TransactionUtil.rollback(beganTransaction, errMsg, e);
+ } catch (GenericEntityException e2) {
+ Debug.logError(e2, "[GenericDelegator] Could not rollback transaction: " + e2.toString(), module);
+ }
+ // rather than logging the problem and returning null, thus hiding the
+ // problem, throw an exception
+ throw new GeneralRuntimeException(errMsg, e);
+ } finally {
+ try {
+ // only commit the transaction if we started one...
+ TransactionUtil.commit(beganTransaction);
+ } catch (GenericTransactionException e1) {
+ Debug.logError(e1, "[GenericDelegator] Could not commit transaction: " + e1.toString(), module);
+ }
+ }
+ }
+
+ public String getOriginalDelegatorName() {
+ return this.delegatorData.originalDelegatorName == null ? this.delegatorData.delegatorName : this.delegatorData.originalDelegatorName;
+ }
+
+ @Deprecated
+ public List<GenericValue> getRelated(String relationName, GenericValue value) throws GenericEntityException {
+ return getRelated(relationName, null, null, value);
+ }
+
+ public List<GenericValue> getRelated(String relationName, Map<String, ? extends Object> byAndFields, List<String> orderBy, GenericValue value) throws GenericEntityException {
+ ModelEntity modelEntity = value.getModelEntity();
+ ModelRelation relation = modelEntity.getRelation(relationName);
+
+ if (relation == null) {
+ throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
+ }
+
+ // put the byAndFields (if not null) into the hash map first,
+ // they will be overridden by value's fields if over-specified
+ // this is important for security and cleanliness
+ Map<String, Object> fields = FastMap.newInstance();
+ if (byAndFields != null)
+ fields.putAll(byAndFields);
+ for (int i = 0; i < relation.getKeyMapsSize(); i++) {
+ ModelKeyMap keyMap = relation.getKeyMap(i);
+ fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
+ }
+
+ return this.findByAnd(relation.getRelEntityName(), fields, orderBy);
+ }
+
+ public List<GenericValue> getRelatedByAnd(String relationName, Map<String, ? extends Object> byAndFields, GenericValue value) throws GenericEntityException {
+ return this.getRelated(relationName, byAndFields, null, value);
+ }
+
+ public List<GenericValue> getRelatedCache(String relationName, GenericValue value) throws GenericEntityException {
+ ModelEntity modelEntity = value.getModelEntity();
+ ModelRelation relation = modelEntity.getRelation(relationName);
+
+ if (relation == null) {
+ throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
+ }
+
+ Map<String, Object> fields = FastMap.newInstance();
+ for (int i = 0; i < relation.getKeyMapsSize(); i++) {
+ ModelKeyMap keyMap = relation.getKeyMap(i);
+ fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
+ }
+
+ return this.findByAndCache(relation.getRelEntityName(), fields, null);
+ }
+
+ public GenericPK getRelatedDummyPK(String relationName, Map<String, ? extends Object> byAndFields, GenericValue value) throws GenericEntityException {
+ ModelEntity modelEntity = value.getModelEntity();
+ ModelRelation relation = modelEntity.getRelation(relationName);
+
+ if (relation == null) {
+ throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
+ }
+ ModelEntity relatedEntity = getModelReader().getModelEntity(relation.getRelEntityName());
+
+ // put the byAndFields (if not null) into the hash map first,
+ // they will be overridden by value's fields if
+ // over-specified this is important for security and
+ // cleanliness
+ Map<String, Object> fields = FastMap.newInstance();
+ if (byAndFields != null)
+ fields.putAll(byAndFields);
+ for (int i = 0; i < relation.getKeyMapsSize(); i++) {
+ ModelKeyMap keyMap = relation.getKeyMap(i);
+ fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
+ }
+
+ GenericPK dummyPK = GenericPK.create(relatedEntity, fields);
+ dummyPK.setDelegator(this);
+ return dummyPK;
+ }
+
+ public GenericValue getRelatedOne(String relationName, GenericValue value) throws GenericEntityException {
+ ModelRelation relation = value.getModelEntity().getRelation(relationName);
+
+ if (relation == null) {
+ throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
+ }
+ if (!"one".equals(relation.getType()) && !"one-nofk".equals(relation.getType())) {
+ throw new GenericModelException("Relation is not a 'one' or a 'one-nofk' relation: " + relationName + " of entity " + value.getEntityName());
+ }
+
+ Map<String, Object> fields = FastMap.newInstance();
+ for (int i = 0; i < relation.getKeyMapsSize(); i++) {
+ ModelKeyMap keyMap = relation.getKeyMap(i);
+ fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
+ }
+
+ return this.findByPrimaryKey(relation.getRelEntityName(), fields);
+ }
+
+ public GenericValue getRelatedOneCache(String relationName, GenericValue value) throws GenericEntityException {
+ ModelEntity modelEntity = value.getModelEntity();
+ ModelRelation relation = modelEntity.getRelation(relationName);
+
+ if (relation == null) {
+ throw new GenericModelException("Could not find relation for relationName: " + relationName + " for value " + value);
+ }
+ if (!"one".equals(relation.getType()) && !"one-nofk".equals(relation.getType())) {
+ throw new GenericModelException("Relation is not a 'one' or a 'one-nofk' relation: " + relationName + " of entity " + value.getEntityName());
+ }
+
+ Map<String, Object> fields = FastMap.newInstance();
+ for (int i = 0; i < relation.getKeyMapsSize(); i++) {
+ ModelKeyMap keyMap = relation.getKeyMap(i);
+ fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
+ }
+
+ return this.findByPrimaryKeyCache(relation.getRelEntityName(), fields);
+ }
+
+ public List<GenericValue> getRelatedOrderBy(String relationName, List<String> orderBy, GenericValue value) throws GenericEntityException {
+ return this.getRelated(relationName, null, orderBy, value);
+ }
+
+ protected void initEntityEcaHandler() {
+ if (this.delegatorData.delegatorInfo.useEntityEca) {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ // initialize the entity eca handler
+ String entityEcaHandlerClassName = this.delegatorData.delegatorInfo.entityEcaHandlerClassName;
+ try {
+ Class<?> eecahClass = loader.loadClass(entityEcaHandlerClassName);
+ this.delegatorData.entityEcaHandler = (EntityEcaHandler<?>) eecahClass.newInstance();
+ this.delegatorData.entityEcaHandler.setDelegator(this);
+ } catch (ClassNotFoundException e) {
+ Debug.logWarning(e, "EntityEcaHandler class with name " + entityEcaHandlerClassName + " was not found, Entity ECA Rules will be disabled", module);
+ } catch (InstantiationException e) {
+ Debug.logWarning(e, "EntityEcaHandler class with name " + entityEcaHandlerClassName + " could not be instantiated, Entity ECA Rules will be disabled", module);
+ } catch (IllegalAccessException e) {
+ Debug.logWarning(e, "EntityEcaHandler class with name " + entityEcaHandlerClassName + " could not be accessed (illegal), Entity ECA Rules will be disabled", module);
+ } catch (ClassCastException e) {
+ Debug.logWarning(e, "EntityEcaHandler class with name " + entityEcaHandlerClassName + " does not implement the EntityEcaHandler interface, Entity ECA Rules will be disabled", module);
+ }
+ } else {
+ Debug.logInfo("Entity ECA Handler disabled for delegator [" + this.delegatorData.delegatorName + "]", module);
+ }
+ }
+
+ public GenericPK makePK(Element element) {
[... 864 lines stripped ...]