blob: d1c633b84b99f847e6cc38f98474be5deb77b34e [file] [log] [blame]
/*
* 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.sql.Timestamp;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import javax.xml.parsers.ParserConfigurationException;
import org.ofbiz.base.concurrent.ConstantFuture;
import org.ofbiz.base.concurrent.ExecutionPool;
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.UtilGenerics;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilObject;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.entity.cache.Cache;
import org.ofbiz.entity.condition.EntityCondition;
import org.ofbiz.entity.config.model.Datasource;
import org.ofbiz.entity.config.model.DelegatorElement;
import org.ofbiz.entity.config.model.EntityConfig;
import org.ofbiz.entity.datasource.GenericHelper;
import org.ofbiz.entity.datasource.GenericHelperFactory;
import org.ofbiz.entity.datasource.GenericHelperInfo;
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.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.EntityQuery;
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;
/**
* The default implementation of the <code>Delegator</code> interface.
*
*/
public class GenericDelegator implements Delegator {
public static final String module = GenericDelegator.class.getName();
protected ModelReader modelReader = null;
protected ModelGroupReader modelGroupReader = null;
/** 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;
protected String delegatorBaseName = null;
protected String delegatorFullName = null;
protected String delegatorTenantId = null;
private String originalDelegatorName = null;
protected DelegatorElement delegatorInfo = null;
protected Cache cache = null;
protected final AtomicReference<Future<DistributedCacheClear>> distributedCacheClear = new AtomicReference<Future<DistributedCacheClear>>();
protected boolean warnNoEcaHandler = false;
protected final AtomicReference<Future<EntityEcaHandler<?>>> entityEcaHandler = new AtomicReference<Future<EntityEcaHandler<?>>>();
protected final AtomicReference<SequenceUtil> AtomicRefSequencer = new AtomicReference<SequenceUtil>(null);
protected EntityCrypto crypto = null;
/** A ThreadLocal variable to allow other methods to specify a user identifier (usually the userLoginId, though technically the Entity Engine doesn't know anything about the UserLogin entity) */
protected static ThreadLocal<List<String>> userIdentifierStack = new ThreadLocal<List<String>>();
/** A ThreadLocal variable to allow other methods to specify a session identifier (usually the visitId, though technically the Entity Engine doesn't know anything about the Visit entity) */
protected static ThreadLocal<List<String>> sessionIdentifierStack = new ThreadLocal<List<String>>();
private boolean testMode = false;
private boolean testRollbackInProgress = false;
private static final AtomicReferenceFieldUpdater<GenericDelegator, LinkedBlockingDeque<?>> testOperationsUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericDelegator.class, LinkedBlockingDeque.class, "testOperations"));
private volatile LinkedBlockingDeque<TestOperation> testOperations = null;
protected static List<String> getUserIdentifierStack() {
List<String> curValList = userIdentifierStack.get();
if (curValList == null) {
curValList = new LinkedList<String>();
userIdentifierStack.set(curValList);
}
return curValList;
}
public static void pushUserIdentifier(String userIdentifier) {
if (userIdentifier == null) {
return;
}
List<String> curValList = getUserIdentifierStack();
curValList.add(0, userIdentifier);
}
public static String popUserIdentifier() {
List<String> curValList = getUserIdentifierStack();
if (curValList.size() == 0) {
return null;
} else {
return curValList.remove(0);
}
}
public static void clearUserIdentifierStack() {
List<String> curValList = getUserIdentifierStack();
curValList.clear();
}
protected static List<String> getSessionIdentifierStack() {
List<String> curValList = sessionIdentifierStack.get();
if (curValList == null) {
curValList = new LinkedList<String>();
sessionIdentifierStack.set(curValList);
}
return curValList;
}
public static void pushSessionIdentifier(String sessionIdentifier) {
if (sessionIdentifier == null) {
return;
}
List<String> curValList = getSessionIdentifierStack();
curValList.add(0, sessionIdentifier);
}
public static String popSessionIdentifier() {
List<String> curValList = getSessionIdentifierStack();
if (curValList.size() == 0) {
return null;
} else {
return curValList.remove(0);
}
}
public static void clearSessionIdentifierStack() {
List<String> curValList = getSessionIdentifierStack();
curValList.clear();
}
/** Only allow creation through the factory method */
protected GenericDelegator() {}
/** Only allow creation through the factory method */
protected GenericDelegator(String delegatorFullName) throws GenericEntityException {
//if (Debug.infoOn()) Debug.logInfo("Creating new Delegator with name \"" + delegatorFullName + "\".", module);
this.setDelegatorNames(delegatorFullName);
this.delegatorInfo = EntityConfig.getInstance().getDelegator(delegatorBaseName);
String kekText;
// before continuing, if there is a tenantId use the base delegator to see if it is valid
if (UtilValidate.isNotEmpty(this.delegatorTenantId)) {
Delegator baseDelegator = DelegatorFactory.getDelegator(this.delegatorBaseName);
GenericValue tenant = EntityQuery.use(baseDelegator).from("Tenant").where("tenantId", this.delegatorTenantId).cache(true).queryOne();
if (tenant == null) {
throw new GenericEntityException("No Tenant record found for delegator [" + this.delegatorFullName + "] with tenantId [" + this.delegatorTenantId + "]");
} else if ("Y".equals(tenant.getString("disabled"))) {
throw new GenericEntityException("No Tenant record found for delegator [" + this.delegatorFullName + "] with tenantId [" + this.delegatorTenantId + "]");
}
GenericValue kekValue = EntityQuery.use(baseDelegator).from("TenantKeyEncryptingKey").where("tenantId", getDelegatorTenantId()).cache(true).queryOne();
if (kekValue != null) {
kekText = kekValue.getString("kekText");
} else {
kekText = this.delegatorInfo.getKeyEncryptingKey();
}
} else {
kekText = this.delegatorInfo.getKeyEncryptingKey();
}
this.modelReader = ModelReader.getModelReader(delegatorBaseName);
this.modelGroupReader = ModelGroupReader.getModelGroupReader(delegatorBaseName);
cache = new Cache(delegatorFullName);
// do the entity model check
List<String> warningList = new LinkedList<String>();
Debug.logInfo("Doing entity definition check...", module);
ModelEntityChecker.checkEntities(this, warningList);
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(delegatorBaseName);
List<Future<Void>> futures = new LinkedList<Future<Void>>();
for (String groupName: groupNames) {
futures.add(ExecutionPool.GLOBAL_BATCH.submit(createHelperCallable(groupName)));
}
ExecutionPool.getAllFutures(futures);
// NOTE: doing some things before the ECAs and such to make sure it is in place just in case it is used in a service engine startup thing or something
// setup the crypto class; this also after the delegator is in the cache otherwise we get infinite recursion
this.crypto = new EntityCrypto(this, kekText);
}
private void initializeOneGenericHelper(String groupName) {
GenericHelperInfo helperInfo = this.getGroupHelperInfo(groupName);
if (helperInfo == null) {
if (Debug.infoOn()) {
Debug.logInfo("Delegator \"" + delegatorFullName + "\" NOT initializing helper for entity group \"" + groupName + "\" because the group is not associated to this delegator.", module);
}
return;
}
String helperBaseName = helperInfo.getHelperBaseName();
if (Debug.infoOn()) {
Debug.logInfo("Delegator \"" + delegatorFullName + "\" initializing helper \"" + helperBaseName + "\" for entity group \"" + groupName + "\".", module);
}
if (UtilValidate.isNotEmpty(helperInfo.getHelperFullName())) {
// pre-load field type defs, the return value is ignored
ModelFieldTypeReader.getModelFieldTypeReader(helperBaseName);
// get the helper and if configured, do the datasource check
GenericHelper helper = GenericHelperFactory.getHelper(helperInfo);
try {
Datasource datasource = EntityConfig.getDatasource(helperBaseName);
if (datasource.getCheckOnStart()) {
if (Debug.infoOn()) {
Debug.logInfo("Doing database check as requested in entityengine.xml with addMissing=" + datasource.getAddMissingOnStart(), module);
}
helper.checkDataSource(this.getModelEntityMapByGroup(groupName), null, datasource.getAddMissingOnStart());
}
} catch (GenericEntityException e) {
Debug.logWarning(e, e.getMessage(), module);
}
}
}
protected Callable<Void> createHelperCallable(final String groupName) {
return new Callable<Void>() {
@Override
public Void call() {
initializeOneGenericHelper(groupName);
return null;
}
};
}
protected void setDelegatorNames(String delegatorFullName) {
this.delegatorFullName = delegatorFullName;
int hashSymbolIndex = delegatorFullName.indexOf('#');
if (hashSymbolIndex == -1) {
this.delegatorBaseName = delegatorFullName;
} else {
this.delegatorBaseName = delegatorFullName.substring(0, hashSymbolIndex);
this.delegatorTenantId = delegatorFullName.substring(hashSymbolIndex + 1);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#initEntityEcaHandler()
*/
@Override
public synchronized void initEntityEcaHandler() {
// Nothing to do if already assigned: the class loader has already been called, the class instantiated and casted to EntityEcaHandler
if (this.entityEcaHandler.get() != null || this.warnNoEcaHandler) {
return;
}
Callable<EntityEcaHandler<?>> creator = new Callable<EntityEcaHandler<?>>() {
public EntityEcaHandler<?> call() {
return createEntityEcaHandler();
}
};
FutureTask<EntityEcaHandler<?>> futureTask = new FutureTask<EntityEcaHandler<?>>(creator);
if (this.entityEcaHandler.compareAndSet(null, futureTask)) {
// This needs to use BATCH, as the service engine might add it's own items into a thread pool.
ExecutionPool.GLOBAL_BATCH.submit(futureTask);
}
}
protected EntityEcaHandler<?> createEntityEcaHandler() {
// If useEntityEca is false do nothing: the entityEcaHandler member field with a null value would cause its code to do nothing
if (this.delegatorInfo.getEntityEcaEnabled()) {
//time to do some tricks with manual class loading that resolves circular dependencies, like calling services
ClassLoader loader = Thread.currentThread().getContextClassLoader();
// initialize the entity eca handler
String entityEcaHandlerClassName = this.delegatorInfo.getEntityEcaHandlerClassName();
try {
Class<?> eecahClass = loader.loadClass(entityEcaHandlerClassName);
EntityEcaHandler<?> entityEcaHandler = UtilGenerics.cast(eecahClass.newInstance());
entityEcaHandler.setDelegator(this);
return entityEcaHandler;
} 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 if (!this.warnNoEcaHandler) {
Debug.logInfo("Entity ECA Handler disabled for delegator [" + delegatorFullName + "]", module);
this.warnNoEcaHandler = true;
}
return null;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getDelegatorName()
*/
@Override
public String getDelegatorName() {
return this.delegatorFullName;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getDelegatorBaseName()
*/
@Override
public String getDelegatorBaseName() {
return this.delegatorBaseName;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getDelegatorBaseName()
*/
@Override
public String getDelegatorTenantId() {
return this.delegatorTenantId;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getOriginalDelegatorName()
*/
@Override
public String getOriginalDelegatorName() {
return this.originalDelegatorName == null ? this.delegatorFullName : this.originalDelegatorName;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getModelReader()
*/
@Override
public ModelReader getModelReader() {
return this.modelReader;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getModelGroupReader()
*/
@Override
public ModelGroupReader getModelGroupReader() {
return this.modelGroupReader;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getModelEntity(java.lang.String)
*/
@Override
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;
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityGroupName(java.lang.String)
*/
@Override
public String getEntityGroupName(String entityName) {
return getModelGroupReader().getEntityGroupName(entityName, this.delegatorBaseName);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getModelEntityMapByGroup(java.lang.String)
*/
@Override
public Map<String, ModelEntity> getModelEntityMapByGroup(String groupName) throws GenericEntityException {
Set<String> entityNameSet = getModelGroupReader().getEntityNamesByGroup(groupName);
if (this.delegatorInfo.getDefaultGroupName().equals(groupName)) {
// add all entities with no group name to the Set
Set<String> allEntityNames = this.getModelReader().getEntityNames();
for (String entityName: allEntityNames) {
if (this.delegatorInfo.getDefaultGroupName().equals(getModelGroupReader().getEntityGroupName(entityName, this.delegatorBaseName))) {
entityNameSet.add(entityName);
}
}
}
Map<String, ModelEntity> entities = new HashMap<String, ModelEntity>();
if (UtilValidate.isEmpty(entityNameSet)) {
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;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getGroupHelperName(java.lang.String)
*/
@Override
public String getGroupHelperName(String groupName) {
return this.delegatorInfo.getGroupDataSource(groupName);
}
@Override
public GenericHelperInfo getGroupHelperInfo(String entityGroupName) {
if (entityGroupName == null) {
return null;
}
String helperBaseName = this.getGroupHelperName(entityGroupName);
if (helperBaseName == null) {
return null;
}
if (UtilValidate.isNotEmpty(this.delegatorTenantId) && "org.ofbiz.tenant".equals(entityGroupName)) {
Debug.logInfo("Can't access entity of entityGroup = " + entityGroupName + " using tenant delegator "+ this.getDelegatorName()+", use base delegator instead", module);
return null;
}
GenericHelperInfo helperInfo = new GenericHelperInfo(entityGroupName, helperBaseName);
if (UtilValidate.isNotEmpty(this.delegatorTenantId)) {
// get the JDBC parameters from the DB for the entityGroupName and tenantId
try {
// NOTE: instead of caching the GenericHelpInfo object do a cached query here and create a new object each time, will avoid issues when the database data changes during run time
// NOTE: always use the base delegator for this to avoid problems when this is being initialized
Delegator baseDelegator = DelegatorFactory.getDelegator(this.delegatorBaseName);
GenericValue tenantDataSource = EntityQuery.use(baseDelegator).from("TenantDataSource").where("tenantId", this.delegatorTenantId, "entityGroupName", entityGroupName).cache(true).queryOne();
if (tenantDataSource != null) {
helperInfo.setTenantId(this.delegatorTenantId);
helperInfo.setOverrideJdbcUri(tenantDataSource.getString("jdbcUri"));
helperInfo.setOverrideUsername(tenantDataSource.getString("jdbcUsername"));
helperInfo.setOverridePassword(tenantDataSource.getString("jdbcPassword"));
} else {
return null;
}
} catch (GenericEntityException e) {
// don't complain about this too much, just log the error if there is one
Debug.logInfo(e, "Error getting TenantDataSource info for tenantId=" + this.delegatorTenantId + ", entityGroupName=" + entityGroupName, module);
}
}
return helperInfo;
}
protected GenericHelperInfo getEntityHelperInfo(String entityName) {
return this.getGroupHelperInfo(this.getEntityGroupName(entityName));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityHelperName(java.lang.String)
*/
@Override
public String getEntityHelperName(String entityName) {
return this.getGroupHelperName(this.getEntityGroupName(entityName));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityHelperName(org.ofbiz.entity.model.ModelEntity)
*/
@Override
public String getEntityHelperName(ModelEntity entity) {
if (entity == null) {
return null;
}
return getEntityHelperName(entity.getEntityName());
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityHelper(java.lang.String)
*/
@Override
public GenericHelper getEntityHelper(String entityName) throws GenericEntityException {
GenericHelperInfo helperInfo = getEntityHelperInfo(entityName);
if (helperInfo != null) {
return GenericHelperFactory.getHelper(helperInfo);
} else {
throw new GenericEntityException("There is no datasource (Helper) configured for the entity-group [" + this.getEntityGroupName(entityName) + "]; was trying to find datasource (helper) for entity [" + entityName + "]");
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityHelper(org.ofbiz.entity.model.ModelEntity)
*/
@Override
public GenericHelper getEntityHelper(ModelEntity entity) throws GenericEntityException {
return getEntityHelper(entity.getEntityName());
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityFieldType(org.ofbiz.entity.model.ModelEntity, java.lang.String)
*/
@Override
public ModelFieldType getEntityFieldType(ModelEntity entity, String type) throws GenericEntityException {
return this.getModelFieldTypeReader(entity).getModelFieldType(type);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getModelFieldTypeReader(org.ofbiz.entity.model.ModelEntity)
*/
@Override
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;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityFieldTypeNames(org.ofbiz.entity.model.ModelEntity)
*/
@Override
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();
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValue(java.lang.String)
*/
@Override
public GenericValue makeValue(String entityName) {
ModelEntity entity = this.getModelEntity(entityName);
if (entity == null) {
throw new IllegalArgumentException("[GenericDelegator.makeValue] could not find entity for entityName: " + entityName);
}
GenericValue value = GenericValue.create(entity);
value.setDelegator(this);
return value;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValue(java.lang.String, java.lang.Object)
*/
@Override
public GenericValue makeValue(String entityName, Object... fields) {
return makeValue(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValue(java.lang.String, java.util.Map)
*/
@Override
public GenericValue makeValue(String entityName, Map<String, ? extends Object> fields) {
ModelEntity entity = this.getModelEntity(entityName);
if (entity == null) {
throw new IllegalArgumentException("[GenericDelegator.makeValue] could not find entity for entityName: " + entityName);
}
return GenericValue.create(this, entity, fields);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValueSingle(java.lang.String, java.lang.Object)
*/
@Override
public GenericValue makeValueSingle(String entityName, Object singlePkValue) {
ModelEntity entity = this.getModelEntity(entityName);
if (entity == null) {
throw new IllegalArgumentException("[GenericDelegator.makeValue] could not find entity for entityName: " + entityName);
}
return GenericValue.create(this, entity, singlePkValue);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValidValue(java.lang.String, java.lang.Object)
*/
@Override
public GenericValue makeValidValue(String entityName, Object... fields) {
return makeValidValue(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValidValue(java.lang.String, java.util.Map)
*/
@Override
public GenericValue makeValidValue(String entityName, Map<String, ? extends Object> fields) {
ModelEntity entity = this.getModelEntity(entityName);
if (entity == null) {
throw new IllegalArgumentException("[GenericDelegator.makeValidValue] could not find entity for entityName: " + entityName);
}
GenericValue value = GenericValue.create(entity);
value.setDelegator(this);
value.setAllFields(fields, true, null, null);
return value;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makePK(java.lang.String)
*/
@Override
public GenericPK makePK(String entityName) {
return this.makePK(entityName, (Map<String, Object>) null);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makePK(java.lang.String, java.lang.Object)
*/
@Override
public GenericPK makePK(String entityName, Object... fields) {
return makePK(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makePK(java.lang.String, java.util.Map)
*/
@Override
public GenericPK makePK(String entityName, Map<String, ? extends Object> fields) {
ModelEntity entity = this.getModelEntity(entityName);
if (entity == null) {
throw new IllegalArgumentException("[GenericDelegator.makePK] could not find entity for entityName: " + entityName);
}
return GenericPK.create(this, entity, fields);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makePKSingle(java.lang.String, java.lang.Object)
*/
@Override
public GenericPK makePKSingle(String entityName, Object singlePkValue) {
ModelEntity entity = this.getModelEntity(entityName);
if (entity == null) {
throw new IllegalArgumentException("[GenericDelegator.makePKSingle] could not find entity for entityName: " + entityName);
}
return GenericPK.create(this, entity, singlePkValue);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#create(org.ofbiz.entity.GenericPK)
*/
@Override
public GenericValue create(GenericPK primaryKey) throws GenericEntityException {
return this.create(primaryKey, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#create(org.ofbiz.entity.GenericPK, boolean)
* @deprecated use {@link #create(GenericPK primaryKey)}
*/
@Override
@Deprecated
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);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#create(java.lang.String, java.lang.Object)
*/
@Override
public GenericValue create(String entityName, Object... fields) throws GenericEntityException {
return create(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#create(java.lang.String, java.util.Map)
*/
@Override
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(this, entity, fields);
return this.create(genericValue, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#createSingle(java.lang.String, java.lang.Object)
*/
@Override
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(this, entity, singlePkValue);
return this.create(genericValue, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#create(org.ofbiz.entity.GenericValue)
*/
@Override
public GenericValue create(GenericValue value) throws GenericEntityException {
return this.create(value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#createSetNextSeqId(org.ofbiz.entity.GenericValue)
*/
@Override
public GenericValue createSetNextSeqId(GenericValue value) throws GenericEntityException {
@Deprecated
boolean doCacheClear = true;
if (value == null) {
throw new GenericEntityException("Cannot create a null value");
}
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);
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_CREATE, value, false);
value.setDelegator(this);
// 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 = null;
try {
existingValue = helper.findByPrimaryKey(value.getPrimaryKey());
} catch (GenericEntityException e1) {
// ignore this error, if not found it'll probably be a GenericEntityNotFoundException
// it is important to not let this get thrown because it will mask the original exception
}
if (existingValue == null) {
throw e;
} else {
if (Debug.infoOn()) {
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.AtomicRefSequencer.get().forceBankRefresh(value.getEntityName(), 1);
value.setNextSeqId();
value = helper.create(value);
if (Debug.infoOn()) {
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);
TransactionUtil.commit(beganTransaction);
return value;
} catch (Exception e) {
String errMsg = "Failure in createSetNextSeqId operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#create(org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #create(GenericValue value)}
*/
@Override
@Deprecated
public GenericValue create(GenericValue value, boolean doCacheClear) throws GenericEntityException {
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
if (value == null) {
throw new GenericEntityException("Cannot create a null value");
}
EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(value.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_CREATE, value, false);
GenericHelper helper = getEntityHelper(value.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_CREATE, value, false);
value.setDelegator(this);
// 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);
TransactionUtil.commit(beganTransaction);
return value;
} catch (Exception e) {
String errMsg = "Failure in create operation for entity [" + (value != null ? value.getEntityName() : "null") + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#createOrStore(org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #createOrStore(GenericValue value)}
*/
@Override
@Deprecated
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);
}
TransactionUtil.commit(beganTransaction);
return value;
} catch (Exception e) {
String errMsg = "Failure in createOrStore operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#createOrStore(org.ofbiz.entity.GenericValue)
*/
@Override
public GenericValue createOrStore(GenericValue value) throws GenericEntityException {
return createOrStore(value, true);
}
protected void saveEntitySyncRemoveInfo(GenericEntity dummyPK) throws GenericEntityException {
// don't store remove info on entities where it is disabled
if (dummyPK.getModelEntity().getNoAutoStamp() || this.testRollbackInProgress) {
return;
}
// don't store remove info on things removed on an entity sync
if (dummyPK.getIsFromEntitySync()) {
return;
}
String serializedPK = null;
try {
serializedPK = XmlSerializer.serialize(dummyPK);
} catch (SerializeException e) {
Debug.logError(e, "Could not serialize primary key to save EntitySyncRemove", module);
} catch (FileNotFoundException e) {
Debug.logError(e, "Could not serialize primary key to save EntitySyncRemove", module);
} catch (IOException e) {
Debug.logError(e, "Could not serialize primary key to save EntitySyncRemove", module);
}
if (serializedPK != null) {
GenericValue entitySyncRemove = this.makeValue("EntitySyncRemove");
entitySyncRemove.set("primaryKeyRemoved", serializedPK);
this.createSetNextSeqId(entitySyncRemove);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByPrimaryKey(org.ofbiz.entity.GenericPK)
*/
@Override
public int removeByPrimaryKey(GenericPK primaryKey) throws GenericEntityException {
int retVal = this.removeByPrimaryKey(primaryKey, true);
return retVal;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByPrimaryKey(org.ofbiz.entity.GenericPK, boolean)
* @deprecated use {@link #removeByPrimaryKey(GenericPK primaryKey)}
*/
@Override
@Deprecated
public int removeByPrimaryKey(GenericPK primaryKey, boolean doCacheClear) throws GenericEntityException {
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(primaryKey.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_REMOVE, primaryKey, false);
GenericHelper helper = getEntityHelper(primaryKey.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_REMOVE, primaryKey, false);
// if audit log on for any fields, save old value before removing so it's still there
if (primaryKey.getModelEntity().getHasFieldWithAuditLog()) {
createEntityAuditLogAll(this.findOne(primaryKey.getEntityName(), primaryKey, false), true, true);
}
GenericValue removedEntity = null;
if (testMode) {
removedEntity = this.findOne(primaryKey.getEntityName(), primaryKey, false);
}
int num = helper.removeByPrimaryKey(primaryKey);
if (doCacheClear) {
ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_REMOVE, primaryKey, false);
this.clearCacheLine(primaryKey);
}
this.saveEntitySyncRemoveInfo(primaryKey);
if (testMode) {
if (removedEntity != null) {
storeForTestRollback(new TestOperation(OperationType.DELETE, removedEntity));
}
}
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_REMOVE, primaryKey, false);
TransactionUtil.commit(beganTransaction);
return num;
} catch (Exception e) {
String errMsg = "Failure in removeByPrimaryKey operation for entity [" + primaryKey.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeValue(org.ofbiz.entity.GenericValue)
*/
@Override
public int removeValue(GenericValue value) throws GenericEntityException {
return this.removeValue(value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeValue(org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #removeValue(GenericValue value)}
*/
@Override
@Deprecated
public int removeValue(GenericValue value, boolean doCacheClear) throws GenericEntityException {
// NOTE: this does not call the GenericDelegator.removeByPrimaryKey method because it has more information to pass to the ECA rule hander
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(value.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_VALIDATE, EntityEcaHandler.OP_REMOVE, value, false);
GenericHelper helper = getEntityHelper(value.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_REMOVE, value, false);
// if audit log on for any fields, save old value before actual remove
if (value.getModelEntity().getHasFieldWithAuditLog()) {
createEntityAuditLogAll(value, true, true);
}
GenericValue removedValue = null;
if (testMode) {
removedValue = this.findOne(value.getEntityName(), value.getPrimaryKey(), false);
}
int num = helper.removeByPrimaryKey(value.getPrimaryKey());
// Need to call removedFromDatasource() here because the helper calls removedFromDatasource() on the PK instead of the GenericEntity.
value.removedFromDatasource();
if (doCacheClear) {
ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_REMOVE, value, false);
this.clearCacheLine(value);
}
if (testMode) {
if (removedValue != null) {
storeForTestRollback(new TestOperation(OperationType.DELETE, removedValue));
}
}
this.saveEntitySyncRemoveInfo(value.getPrimaryKey());
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_REMOVE, value, false);
TransactionUtil.commit(beganTransaction);
return num;
} catch (Exception e) {
String errMsg = "Failure in removeValue operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByAnd(java.lang.String, java.lang.Object)
*/
@Override
public int removeByAnd(String entityName, Object... fields) throws GenericEntityException {
return removeByAnd(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByAnd(java.lang.String, java.util.Map)
*/
@Override
public int removeByAnd(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
return this.removeByAnd(entityName, fields, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByAnd(java.lang.String, boolean, java.lang.Object)
* @deprecated use {@link #removeByAnd(String entityName, Object... fields)}
*/
@Override
@Deprecated
public int removeByAnd(String entityName, boolean doCacheClear, Object... fields) throws GenericEntityException {
return removeByAnd(entityName, UtilMisc.<String, Object>toMap(fields), doCacheClear);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByAnd(java.lang.String, java.util.Map, boolean)
* @deprecated use {@link #removeByAnd(String entityName, Map<String, ? extends Object> fields)}}
*/
@Override
@Deprecated
public int removeByAnd(String entityName, Map<String, ? extends Object> fields, boolean doCacheClear) throws GenericEntityException {
EntityCondition ecl = EntityCondition.makeCondition(fields);
return removeByCondition(entityName, ecl, doCacheClear);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByCondition(java.lang.String, org.ofbiz.entity.condition.EntityCondition)
*/
@Override
public int removeByCondition(String entityName, EntityCondition condition) throws GenericEntityException {
return this.removeByCondition(entityName, condition, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeByCondition(java.lang.String, org.ofbiz.entity.condition.EntityCondition, boolean)
* @deprecated use {@link #removeByCondition(String entityName, EntityCondition condition)}
*/
@Override
@Deprecated
public int removeByCondition(String entityName, EntityCondition condition, boolean doCacheClear) throws GenericEntityException {
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
ModelEntity modelEntity = getModelReader().getModelEntity(entityName);
GenericHelper helper = getEntityHelper(entityName);
List<GenericValue> removedEntities = null;
if (testMode) {
removedEntities = this.findList(entityName, condition, null, null, null, false);
}
int rowsAffected = helper.removeByCondition(this, modelEntity, condition);
if (rowsAffected > 0 && doCacheClear) {
this.clearCacheLine(entityName);
}
if (testMode) {
for (GenericValue entity : removedEntities) {
storeForTestRollback(new TestOperation(OperationType.DELETE, entity));
}
}
TransactionUtil.commit(beganTransaction);
return rowsAffected;
} catch (Exception e) {
String errMsg = "Failure in removeByCondition operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeRelated(java.lang.String, org.ofbiz.entity.GenericValue)
*/
@Override
public int removeRelated(String relationName, GenericValue value) throws GenericEntityException {
return this.removeRelated(relationName, value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeRelated(java.lang.String, org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #removeRelated(String relationName, GenericValue value)}
*/
@Override
@Deprecated
public int removeRelated(String relationName, GenericValue value, boolean doCacheClear) 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 = new HashMap<String, Object>();
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return this.removeByAnd(relation.getRelEntityName(), fields, doCacheClear);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#refresh(org.ofbiz.entity.GenericValue)
*/
@Override
public void refresh(GenericValue value) throws GenericEntityException {
this.refresh(value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#refresh(org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #refresh(GenericValue value)}
*/
@Override
@Deprecated
public void refresh(GenericValue value, boolean doCacheClear) throws GenericEntityException {
if (doCacheClear) {
// always clear cache before the operation
clearCacheLine(value);
}
GenericPK pk = value.getPrimaryKey();
GenericValue newValue = this.findOne(pk.getEntityName(), pk, false);
value.refreshFromValue(newValue);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#refreshFromCache(org.ofbiz.entity.GenericValue)
*/
@Override
public void refreshFromCache(GenericValue value) throws GenericEntityException {
GenericPK pk = value.getPrimaryKey();
GenericValue newValue = findOne(pk.getEntityName(), pk, true);
value.refreshFromValue(newValue);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#storeByCondition(java.lang.String, java.util.Map, org.ofbiz.entity.condition.EntityCondition)
*/
@Override
public int storeByCondition(String entityName, Map<String, ? extends Object> fieldsToSet, EntityCondition condition) throws GenericEntityException {
return storeByCondition(entityName, fieldsToSet, condition, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#storeByCondition(java.lang.String, java.util.Map, org.ofbiz.entity.condition.EntityCondition, boolean)
* @deprecated use {@link #storeByCondition(String entityName, Map<String, ? extends Object> fieldsToSet, EntityCondition condition)}
*/
@Override
@Deprecated
public int storeByCondition(String entityName, Map<String, ? extends Object> fieldsToSet, EntityCondition condition, boolean doCacheClear) throws GenericEntityException {
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
ModelEntity modelEntity = getModelReader().getModelEntity(entityName);
GenericHelper helper = getEntityHelper(entityName);
List<GenericValue> updatedEntities = null;
if (testMode) {
updatedEntities = this.findList(entityName, condition, null, null, null, false);
}
int rowsAffected = helper.storeByCondition(this, modelEntity, fieldsToSet, condition);
if (rowsAffected > 0 && doCacheClear) {
this.clearCacheLine(entityName);
}
if (testMode) {
for (GenericValue entity : updatedEntities) {
storeForTestRollback(new TestOperation(OperationType.UPDATE, entity));
}
}
TransactionUtil.commit(beganTransaction);
return rowsAffected;
} catch (Exception e) {
String errMsg = "Failure in storeByCondition operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#store(org.ofbiz.entity.GenericValue)
*/
@Override
public int store(GenericValue value) throws GenericEntityException {
return this.store(value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#store(org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #store(GenericValue value)}
*/
@Override
@Deprecated
public int store(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_STORE, value, false);
GenericHelper helper = getEntityHelper(value.getEntityName());
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_STORE, value, false);
// if audit log on for any fields, save old value before the update so we still have both
if (value.getModelEntity().getHasFieldWithAuditLog()) {
createEntityAuditLogAll(value, true, false);
}
GenericValue updatedEntity = null;
if (testMode) {
updatedEntity = this.findOne(value.getEntityName(), value.getPrimaryKey(), false);
}
int retVal = helper.store(value);
if (doCacheClear) {
ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CLEAR, EntityEcaHandler.OP_STORE, value, false);
this.clearCacheLine(value);
}
if (testMode) {
storeForTestRollback(new TestOperation(OperationType.UPDATE, updatedEntity));
}
// refresh the valueObject to get the new version
if (value.lockEnabled()) {
refresh(value, doCacheClear);
}
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_STORE, value, false);
TransactionUtil.commit(beganTransaction);
return retVal;
} catch (Exception e) {
String errMsg = "Failure in store operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#storeAll(java.util.List)
*/
@Override
public int storeAll(List<GenericValue> values) throws GenericEntityException {
return this.storeAll(values, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#storeAll(java.util.List, boolean)
* @deprecated use {@link #storeAll(List<GenericValue> values)}
* TODO: JLR 2013-09-19 - doCacheClear refactoring: to be removed and replaced by storeAll(List<GenericValue> values, boolean createDummyFks)
*/
@Override
@Deprecated
public int storeAll(List<GenericValue> values, boolean doCacheClear) throws GenericEntityException {
return this.storeAll(values, doCacheClear, false);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#storeAll(java.util.List, boolean, boolean)
* TODO: JLR 2013-09-19 - doCacheClear refactoring: to be changed to storeAll(List<GenericValue> values, boolean createDummyFks)
*/
@Override
public int storeAll(List<GenericValue> values, boolean doCacheClear, boolean createDummyFks) throws GenericEntityException {
if (values == null) {
return 0;
}
int numberChanged = 0;
boolean beganTransaction = false;
try {
beganTransaction = TransactionUtil.begin();
for (GenericValue value: values) {
String entityName = value.getEntityName();
GenericPK primaryKey = value.getPrimaryKey();
GenericHelper helper = getEntityHelper(entityName);
// exists?
// NOTE: don't use findByPrimaryKey because we don't want to the ECA events to fire and such
if (!primaryKey.isPrimaryKey()) {
throw new GenericModelException("[GenericDelegator.storeAll] One of the passed primary keys is not a valid primary key: " + primaryKey);
}
GenericValue existing = null;
try {
existing = helper.findByPrimaryKey(primaryKey);
} catch (GenericEntityNotFoundException e) {
existing = null;
}
if (existing == null) {
if (createDummyFks) {
value.checkFks(true);
}
this.create(value, doCacheClear);
numberChanged++;
} else {
// don't send fields that are the same, and if no fields have changed, update nothing
ModelEntity modelEntity = value.getModelEntity();
GenericValue toStore = GenericValue.create(this, modelEntity, value.getPrimaryKey());
boolean atLeastOneField = false;
Iterator<ModelField> nonPksIter = modelEntity.getNopksIterator();
while (nonPksIter.hasNext()) {
ModelField modelField = nonPksIter.next();
String fieldName = modelField.getName();
if (value.containsKey(fieldName)) {
Object fieldValue = value.get(fieldName);
Object oldValue = existing.get(fieldName);
if (!UtilObject.equalsHelper(oldValue, fieldValue)) {
toStore.put(fieldName, fieldValue);
atLeastOneField = true;
}
}
}
if (atLeastOneField) {
if (createDummyFks) {
value.checkFks(true);
}
numberChanged += this.store(toStore, doCacheClear);
}
}
}
TransactionUtil.commit(beganTransaction);
return numberChanged;
} catch (Exception e) {
String errMsg = "Failure in storeAll operation: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeAll(java.lang.String)
*/
@Override
public int removeAll(String entityName) throws GenericEntityException {
return removeByAnd(entityName, (Map<String, Object>) null);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeAll(java.util.List)
*/
@Override
public int removeAll(List<? extends GenericEntity> dummyPKs) throws GenericEntityException {
return this.removeAll(dummyPKs, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#removeAll(java.util.List, boolean)
* @deprecated use {@link #removeAll(List<? extends GenericEntity> dummyPKs)}
*/
@Override
@Deprecated
public int removeAll(List<? extends GenericEntity> dummyPKs, boolean doCacheClear) throws GenericEntityException {
if (dummyPKs == null) {
return 0;
}
boolean beganTransaction = false;
int numRemoved = 0;
try {
for (GenericEntity value: dummyPKs) {
if (value.containsPrimaryKey()) {
numRemoved += this.removeByPrimaryKey(value.getPrimaryKey(), doCacheClear);
} else {
numRemoved += this.removeByAnd(value.getEntityName(), value.getAllFields(), doCacheClear);
}
}
TransactionUtil.commit(beganTransaction);
return numRemoved;
} catch (Exception e) {
String errMsg = "Failure in removeAll operation: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
// ======================================
// ======= Find Methods =================
// ======================================
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findOne(java.lang.String, boolean, java.lang.Object)
*/
@Override
public GenericValue findOne(String entityName, boolean useCache, Object... fields) throws GenericEntityException {
return findOne(entityName, UtilMisc.toMap(fields), useCache);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findOne(java.lang.String, java.util.Map, boolean)
*/
@Override
public GenericValue findOne(String entityName, Map<String, ? extends Object> fields, boolean useCache) throws GenericEntityException {
GenericPK primaryKey = this.makePK(entityName, fields);
if (!primaryKey.isPrimaryKey()) {
throw new GenericModelException("[GenericDelegator.findOne] Passed primary key is not a valid primary key: " + primaryKey);
}
EntityEcaRuleRunner<?> ecaRunner = this.getEcaRuleRunner(entityName);
if (useCache) {
ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_CHECK, EntityEcaHandler.OP_FIND, primaryKey, false);
GenericValue value = cache.get(primaryKey);
if (value == GenericValue.NULL_VALUE) {
return null;
}
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;
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, primaryKey, false);
try {
value = helper.findByPrimaryKey(primaryKey);
} catch (GenericEntityNotFoundException e) {
}
if (value != null) {
value.setDelegator(this);
}
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);
TransactionUtil.commit(beganTransaction);
return value;
} catch (Exception e) {
String errMsg = "Failure in findOne operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByPrimaryKey(java.lang.String, java.util.Map)
* @deprecated use {@link #findOne(String, Map, boolean)}
*/
@Override
@Deprecated
public GenericValue findByPrimaryKey(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
return findOne(entityName, fields, false);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByPrimaryKeyCache(java.lang.String, java.lang.Object)
* @deprecated use {@link #findOne(String, boolean, Object...)}
*/
@Override
@Deprecated
public GenericValue findByPrimaryKeyCache(String entityName, Object... fields) throws GenericEntityException {
return findByPrimaryKeyCache(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByPrimaryKeyCache(java.lang.String, java.util.Map)
* @deprecated use {@link #findOne(String, Map, boolean)}
*/
@Override
@Deprecated
public GenericValue findByPrimaryKeyCache(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
return findOne(entityName, fields, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByPrimaryKeyPartial(org.ofbiz.entity.GenericPK, java.util.Set)
*/
@Override
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) {
}
if (value != null) value.setDelegator(this);
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, primaryKey, false);
TransactionUtil.commit(beganTransaction);
return value;
} catch (Exception e) {
String errMsg = "Failure in findByPrimaryKeyPartial operation for entity [" + primaryKey.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/** Finds all Generic entities
*@param entityName The Name of the Entity as defined in the entity XML file
* @see org.ofbiz.entity.Delegator#findAll(java.lang.String, boolean)
*/
@Override
public List<GenericValue> findAll(String entityName, boolean useCache) throws GenericEntityException {
return this.findList(entityName, null, null, null, null, useCache);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByAnd(java.lang.String, java.lang.Object)
* @deprecated use {@link #findByAnd(String, Map, List, boolean)}
*/
@Override
@Deprecated
public List<GenericValue> findByAnd(String entityName, Object... fields) throws GenericEntityException {
EntityCondition ecl = EntityCondition.makeCondition(UtilMisc.<String, Object>toMap(fields));
return this.findList(entityName, ecl, null, null, null, false);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByAnd(java.lang.String, java.util.Map)
* @deprecated use {@link #findByAnd(String, Map, List, boolean)}
*/
@Override
@Deprecated
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);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByAnd(java.lang.String, java.util.Map, java.util.List)
* @deprecated use {@link #findByAnd(String, Map, List, boolean)}
*/
@Override
@Deprecated
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);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByAndCache(java.lang.String, java.util.Map)
* @deprecated use {@link #findByAnd(String, Map, List, boolean)}
*/
@Override
@Deprecated
public List<GenericValue> findByAndCache(String entityName, Map<String, ? extends Object> fields) throws GenericEntityException {
return this.findList(entityName, EntityCondition.makeCondition(fields), null, null, null, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByAndCache(java.lang.String, java.util.Map, java.util.List)
* @deprecated use {@link #findByAnd(String, Map, List, boolean)}
*/
@Override
@Deprecated
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);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findByAnd(java.lang.String, java.util.Map, java.util.List, boolean)
*/
@Override
public List<GenericValue> findByAnd(String entityName, Map<String, ? extends Object> fields, List<String> orderBy, boolean useCache) throws GenericEntityException {
return this.findList(entityName, EntityCondition.makeCondition(fields), null, orderBy, null, useCache);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#find(java.lang.String, org.ofbiz.entity.condition.EntityCondition, org.ofbiz.entity.condition.EntityCondition, java.util.Set, java.util.List, org.ofbiz.entity.util.EntityFindOptions)
*/
@Override
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);
}
if (havingEntityCondition != null) {
havingEntityCondition.checkCondition(modelEntity);
}
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, dummyValue, false);
GenericHelper helper = getEntityHelper(modelEntity.getEntityName());
EntityListIterator eli = helper.findListIteratorByCondition(this, modelEntity, whereEntityCondition, havingEntityCondition, fieldsToSelect, orderBy, findOptions);
eli.setDelegator(this);
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, dummyValue, false);
return eli;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findList(java.lang.String, org.ofbiz.entity.condition.EntityCondition, java.util.Set, java.util.List, org.ofbiz.entity.util.EntityFindOptions, boolean)
*/
@Override
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.cache.get(entityName, entityCondition, orderBy);
if (cacheList != null) {
return cacheList;
}
}
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
EntityListIterator eli = null;
List<GenericValue> list = null;
try {
eli = this.find(entityName, entityCondition, null, fieldsToSelect, orderBy, findOptions);
list = eli.getCompleteList();
} finally {
if (eli != null) {
try {
eli.close();
} catch (Exception exc) {}
}
}
if (useCache) {
ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_PUT, EntityEcaHandler.OP_FIND, dummyValue, false);
this.cache.put(entityName, entityCondition, orderBy, list);
}
TransactionUtil.commit(beganTransaction);
return list;
} catch (Exception e) {
String errMsg = "Failure in findByCondition operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findListIteratorByCondition(org.ofbiz.entity.model.DynamicViewEntity, org.ofbiz.entity.condition.EntityCondition, org.ofbiz.entity.condition.EntityCondition, java.util.Collection, java.util.List, org.ofbiz.entity.util.EntityFindOptions)
*/
@Override
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(this, modelViewEntity, whereEntityCondition,
havingEntityCondition, fieldsToSelect, orderBy, findOptions);
eli.setDelegator(this);
//TODO: add decrypt fields
return eli;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#findCountByCondition(java.lang.String, org.ofbiz.entity.condition.EntityCondition, org.ofbiz.entity.condition.EntityCondition, org.ofbiz.entity.util.EntityFindOptions)
*/
@Override
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);
}
if (havingEntityCondition != null) {
havingEntityCondition.checkCondition(modelEntity);
}
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_FIND, dummyValue, false);
GenericHelper helper = getEntityHelper(modelEntity.getEntityName());
long count = helper.findCountByCondition(this, modelEntity, whereEntityCondition, havingEntityCondition, findOptions);
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, dummyValue, false);
TransactionUtil.commit(beganTransaction);
return count;
} catch (Exception e) {
String errMsg = "Failure in findListIteratorByCondition operation for entity [DynamicView]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getMultiRelation(org.ofbiz.entity.GenericValue, java.lang.String, java.lang.String, java.util.List)
*/
@Override
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);
List<GenericValue> result = helper.findByMultiRelation(value, modelRelationOne, modelEntityOne, modelRelationTwo, modelEntityTwo, orderBy);
TransactionUtil.commit(beganTransaction);
return result;
} catch (Exception e) {
String errMsg = "Failure in getMultiRelation operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
TransactionUtil.rollback(beganTransaction, errMsg, e);
throw new GenericEntityException(e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelated(java.lang.String, java.util.Map, java.util.List, org.ofbiz.entity.GenericValue)
* @deprecated use {@link #getRelated(String, Map, List, GenericValue, boolean)}
*/
@Override
@Deprecated
public List<GenericValue> getRelated(String relationName, Map<String, ? extends Object> byAndFields, List<String> orderBy, GenericValue value) throws GenericEntityException {
return getRelated(relationName, byAndFields, orderBy, value, false);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelated(java.lang.String, java.util.Map, java.util.List, org.ofbiz.entity.GenericValue, boolean)
*/
@Override
public List<GenericValue> getRelated(String relationName, Map<String, ? extends Object> byAndFields, List<String> orderBy, GenericValue value, boolean useCache) 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 = new HashMap<String, Object>();
if (byAndFields != null) {
fields.putAll(byAndFields);
}
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return this.findByAnd(relation.getRelEntityName(), fields, orderBy, useCache);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelatedDummyPK(java.lang.String, java.util.Map, org.ofbiz.entity.GenericValue)
*/
@Override
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 = new HashMap<String, Object>();
if (byAndFields != null) {
fields.putAll(byAndFields);
}
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return GenericPK.create(this, relatedEntity, fields);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelatedCache(java.lang.String, org.ofbiz.entity.GenericValue)
* @deprecated use {@link #getRelated(String, Map, List, GenericValue, boolean)}
*/
@Override
@Deprecated
public List<GenericValue> getRelatedCache(String relationName, GenericValue value) throws GenericEntityException {
return getRelated(relationName, null, null, value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelatedOne(java.lang.String, org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #getRelatedOne(String, GenericValue, boolean)}
*/
@Override
@Deprecated
public GenericValue getRelatedOne(String relationName, GenericValue value) throws GenericEntityException {
return this.getRelatedOne(relationName, value, false);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelatedOneCache(java.lang.String, org.ofbiz.entity.GenericValue, boolean)
* @deprecated use {@link #getRelatedOne(String, GenericValue, boolean)}
*/
@Override
@Deprecated
public GenericValue getRelatedOneCache(String relationName, GenericValue value) throws GenericEntityException {
return this.getRelatedOne(relationName, value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getRelatedOne(java.lang.String, org.ofbiz.entity.GenericValue, boolean)
*/
@Override
public GenericValue getRelatedOne(String relationName, GenericValue value, boolean useCache) 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 = new HashMap<String, Object>();
for (ModelKeyMap keyMap : relation.getKeyMaps()) {
fields.put(keyMap.getRelFieldName(), value.get(keyMap.getFieldName()));
}
return this.findOne(relation.getRelEntityName(), fields, useCache);
}
// ======================================
// ======= Cache Related Methods ========
// ======================================
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearAllCaches()
*/
@Override
public void clearAllCaches() {
this.clearAllCaches(true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearAllCaches(boolean)
*/
@Override
public void clearAllCaches(boolean distribute) {
cache.clear();
if (!distribute) {
return;
}
DistributedCacheClear dcc = getDistributedCacheClear();
if (dcc != null) {
dcc.clearAllCaches();
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(java.lang.String)
*/
@Override
public void clearCacheLine(String entityName) {
cache.remove(entityName);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(java.lang.String, java.lang.Object)
*/
@Override
public void clearCacheLine(String entityName, Object... fields) {
clearCacheLine(entityName, UtilMisc.<String, Object>toMap(fields));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(java.lang.String, java.util.Map)
*/
@Override
public void clearCacheLine(String entityName, Map<String, ? extends Object> fields) {
// if no fields passed, do the all cache quickly and return
if (fields == null) {
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(this, entity, fields);
this.clearCacheLineFlexible(dummyValue);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLineFlexible(org.ofbiz.entity.GenericEntity)
*/
@Override
public void clearCacheLineFlexible(GenericEntity dummyPK) {
this.clearCacheLineFlexible(dummyPK, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLineFlexible(org.ofbiz.entity.GenericEntity, boolean)
*/
@Override
public void clearCacheLineFlexible(GenericEntity dummyPK, boolean distribute) {
if (dummyPK != null) {
//if never cached, then don't bother clearing
if (dummyPK.getModelEntity().getNeverCache()) return;
cache.remove(dummyPK);
if (!distribute) {
return;
}
DistributedCacheClear dcc = getDistributedCacheClear();
if (dcc != null) {
dcc.distributedClearCacheLineFlexible(dummyPK);
}
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLineByCondition(java.lang.String, org.ofbiz.entity.condition.EntityCondition)
*/
@Override
public void clearCacheLineByCondition(String entityName, EntityCondition condition) {
clearCacheLineByCondition(entityName, condition, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLineByCondition(java.lang.String, org.ofbiz.entity.condition.EntityCondition, boolean)
*/
@Override
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;
}
cache.remove(entityName, condition);
if (!distribute) {
return;
}
DistributedCacheClear dcc = getDistributedCacheClear();
if (dcc != null) {
dcc.distributedClearCacheLineByCondition(entityName, condition);
}
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(org.ofbiz.entity.GenericPK)
*/
@Override
public void clearCacheLine(GenericPK primaryKey) {
this.clearCacheLine(primaryKey, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(org.ofbiz.entity.GenericPK, boolean)
*/
@Override
public void clearCacheLine(GenericPK primaryKey, boolean distribute) {
if (primaryKey == null) {
return;
}
//if never cached, then don't bother clearing
if (primaryKey.getModelEntity().getNeverCache()) {
return;
}
cache.remove(primaryKey);
if (!distribute) {
return;
}
DistributedCacheClear dcc = getDistributedCacheClear();
if (dcc != null) {
dcc.distributedClearCacheLine(primaryKey);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(org.ofbiz.entity.GenericValue)
*/
@Override
public void clearCacheLine(GenericValue value) {
this.clearCacheLine(value, true);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearCacheLine(org.ofbiz.entity.GenericValue, boolean)
*/
@Override
public void clearCacheLine(GenericValue value, boolean distribute) {
// 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;
}
cache.remove(value);
if (!distribute) {
return;
}
DistributedCacheClear dcc = getDistributedCacheClear();
if (dcc != null) {
dcc.distributedClearCacheLine(value);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearAllCacheLinesByDummyPK(java.util.Collection)
*/
@Override
public void clearAllCacheLinesByDummyPK(Collection<GenericPK> dummyPKs) {
if (dummyPKs == null) {
return;
}
for (GenericEntity entity: dummyPKs) {
this.clearCacheLineFlexible(entity);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#clearAllCacheLinesByValue(java.util.Collection)
*/
@Override
public void clearAllCacheLinesByValue(Collection<GenericValue> values) {
if (values == null) {
return;
}
for (GenericValue value: values) {
this.clearCacheLine(value);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getFromPrimaryKeyCache(org.ofbiz.entity.GenericPK)
*/
@Override
public GenericValue getFromPrimaryKeyCache(GenericPK primaryKey) {
if (primaryKey == null) {
return null;
}
GenericValue value = cache.get(primaryKey);
if (value == GenericValue.NULL_VALUE) {
return null;
}
return value;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#putInPrimaryKeyCache(org.ofbiz.entity.GenericPK, org.ofbiz.entity.GenericValue)
*/
@Override
public void putInPrimaryKeyCache(GenericPK primaryKey, GenericValue value) {
if (primaryKey == null) {
return;
}
if (primaryKey.getModelEntity().getNeverCache()) {
if (Debug.warningOn()) {
Debug.logWarning("Tried to put a value of the " + value.getEntityName() + " entity in the BY PRIMARY KEY cache but this entity has never-cache set to true, not caching.", module);
}
return;
}
// before going into the cache, make this value immutable
value.setImmutable();
cache.put(primaryKey, value);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#putAllInPrimaryKeyCache(java.util.List)
*/
@Override
public void putAllInPrimaryKeyCache(List<GenericValue> values) {
if (values == null) {
return;
}
for (GenericValue value: values) {
this.putInPrimaryKeyCache(value.getPrimaryKey(), value);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#setDistributedCacheClear(org.ofbiz.entity.util.DistributedCacheClear)
*/
@Override
public void setDistributedCacheClear(DistributedCacheClear distributedCacheClear) {
this.distributedCacheClear.set(new ConstantFuture<DistributedCacheClear>(distributedCacheClear));
}
// ======= XML Related Methods ========
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#readXmlDocument(java.net.URL)
*/
@Override
public List<GenericValue> readXmlDocument(URL url) throws SAXException, ParserConfigurationException, java.io.IOException {
if (url == null) {
return null;
}
return this.makeValues(UtilXml.readXmlDocument(url, false));
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValues(org.w3c.dom.Document)
*/
@Override
public List<GenericValue> makeValues(Document document) {
if (document == null) {
return null;
}
List<GenericValue> values = new LinkedList<GenericValue>();
Element docElement = document.getDocumentElement();
if (docElement == null) {
return null;
}
if (!"entity-engine-xml".equals(docElement.getTagName())) {
Debug.logError("[GenericDelegator.makeValues] Root node was not <entity-engine-xml>", module);
throw new java.lang.IllegalArgumentException("Root node was not <entity-engine-xml>");
}
docElement.normalize();
Node curChild = docElement.getFirstChild();
if (curChild != null) {
do {
if (curChild.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) curChild;
GenericValue value = this.makeValue(element);
if (value != null) {
values.add(value);
}
}
} while ((curChild = curChild.getNextSibling()) != null);
} else {
Debug.logWarning("[GenericDelegator.makeValues] No child nodes found in document.", module);
}
return values;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makePK(org.w3c.dom.Element)
*/
@Override
public GenericPK makePK(Element element) {
GenericValue value = makeValue(element);
return value.getPrimaryKey();
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeValue(org.w3c.dom.Element)
*/
@Override
public GenericValue makeValue(Element element) {
if (element == null) {
return null;
}
String entityName = element.getTagName();
// if a dash or colon is in the tag name, grab what is after it
if (entityName.indexOf('-') > 0) {
entityName = entityName.substring(entityName.indexOf('-') + 1);
}
if (entityName.indexOf(':') > 0) {
entityName = entityName.substring(entityName.indexOf(':') + 1);
}
GenericValue value = this.makeValue(entityName);
ModelEntity modelEntity = value.getModelEntity();
Iterator<ModelField> modelFields = modelEntity.getFieldsIterator();
while (modelFields.hasNext()) {
ModelField modelField = modelFields.next();
String name = modelField.getName();
String attr = element.getAttribute(name);
if (UtilValidate.isNotEmpty(attr)) {
// GenericEntity.makeXmlElement() sets null values to GenericEntity.NULL_FIELD.toString(), so look for
// that and treat it as null
if (GenericEntity.NULL_FIELD.toString().equals(attr)) {
value.set(name, null);
} else {
value.setString(name, attr);
}
} else {
// if no attribute try a subelement
Element subElement = UtilXml.firstChildElement(element, name);
if (subElement != null) {
value.setString(name, UtilXml.elementValue(subElement));
}
}
}
return value;
}
// ======= Misc Methods ========
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;
}
//if (!"find".equals(currentOperation)) {
// Debug.logWarning("evalRules for entity " + value.getEntityName() + ", currentOperation " + currentOperation + ", event " + event, module);
//}
entityEcaHandler.evalRules(currentOperation, eventMap, event, value, isError);
}
}
protected EntityEcaRuleRunner<?> getEcaRuleRunner(String entityName) {
if (this.testRollbackInProgress) {
return createEntityEcaRuleRunner(null, null);
}
return createEntityEcaRuleRunner(getEntityEcaHandler(), entityName);
}
protected static <T> EntityEcaRuleRunner<T> createEntityEcaRuleRunner(EntityEcaHandler<T> entityEcaHandler, String entityName) {
return new EntityEcaRuleRunner<T>(entityEcaHandler, entityEcaHandler != null ? entityEcaHandler.getEntityEventMap(entityName) : null);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#setEntityEcaHandler(org.ofbiz.entity.eca.EntityEcaHandler)
*/
@Override
public <T> void setEntityEcaHandler(EntityEcaHandler<T> entityEcaHandler) {
this.entityEcaHandler.set(new ConstantFuture<EntityEcaHandler<?>>(entityEcaHandler));
this.warnNoEcaHandler = false;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getEntityEcaHandler()
*/
@Override
public <T> EntityEcaHandler<T> getEntityEcaHandler() {
Future<EntityEcaHandler<?>> future = this.entityEcaHandler.get();
try {
return UtilGenerics.cast(future != null ? future.get() : null);
} catch (ExecutionException e) {
Debug.logError(e, "Could not fetch EntityEcaHandler from the asynchronous instantiation", module);
} catch (InterruptedException e) {
Debug.logError(e, "Could not fetch EntityEcaHandler from the asynchronous instantiation", module);
}
return null;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getNextSeqId(java.lang.String)
*/
@Override
public String getNextSeqId(String seqName) {
return this.getNextSeqId(seqName, 1);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getNextSeqId(java.lang.String, long)
*/
@Override
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.delegatorInfo.getSequencedIdPrefix())) {
return this.delegatorInfo.getSequencedIdPrefix() + nextSeqLong.toString();
} else {
return nextSeqLong.toString();
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getNextSeqIdLong(java.lang.String)
*/
@Override
public Long getNextSeqIdLong(String seqName) {
return this.getNextSeqIdLong(seqName, 1);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getNextSeqIdLong(java.lang.String, long)
*/
public Long getNextSeqIdLong(String seqName, long staggerMax) {
try {
SequenceUtil sequencer = this.AtomicRefSequencer.get();
if (sequencer == null) {
ModelEntity seqEntity = this.getModelEntity("SequenceValueItem");
sequencer = new SequenceUtil(this.getEntityHelperInfo("SequenceValueItem"), seqEntity, "seqName", "seqId");
if (!AtomicRefSequencer.compareAndSet(null, sequencer)) {
sequencer = this.AtomicRefSequencer.get();
}
}
ModelEntity seqModelEntity = null;
try {
seqModelEntity = getModelReader().getModelEntity(seqName);
} catch (GenericEntityException e) {
Debug.logInfo("Entity definition not found for sequence name " + seqName, module);
}
Long newSeqId = sequencer == null ? null : sequencer.getNextSeqId(seqName, staggerMax, seqModelEntity);
return newSeqId;
} catch (Exception e) {
String errMsg = "Failure in getNextSeqIdLong operation for seqName [" + seqName + "]: " + e.toString() + ". Rolling back transaction.";
Debug.logError(e, errMsg, module);
throw new GeneralRuntimeException(errMsg, e);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#setSequencer(org.ofbiz.entity.util.SequenceUtil)
*/
@Override
public void setSequencer(SequenceUtil sequencer) {
this.AtomicRefSequencer.set(sequencer);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#refreshSequencer()
*/
@Override
public void refreshSequencer() {
this.AtomicRefSequencer.set(null);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#setNextSubSeqId(org.ofbiz.entity.GenericValue, java.lang.String, int, int)
*/
@Override
public void setNextSubSeqId(GenericValue value, String seqFieldName, int numericPadding, int incrementBy) {
if (value != null && UtilValidate.isEmpty(value.getString(seqFieldName))) {
String sequencedIdPrefix = this.delegatorInfo.getSequencedIdPrefix();
value.remove(seqFieldName);
GenericValue lookupValue = this.makeValue(value.getEntityName());
lookupValue.setPKFields(value);
boolean beganTransaction = false;
try {
if (alwaysUseTransaction) {
beganTransaction = TransactionUtil.begin();
}
// get values in whatever order, we will go through all of them to find the highest value
List<GenericValue> allValues = this.findByAnd(value.getEntityName(), lookupValue, null, false);
//Debug.logInfo("Get existing values from entity " + value.getEntityName() + " with lookupValue: " + lookupValue + ", and the seqFieldName: " + seqFieldName + ", and the results are: " + allValues, module);
Integer highestSeqVal = null;
for (GenericValue curValue: allValues) {
String currentSeqId = curValue.getString(seqFieldName);
if (currentSeqId != null) {
if (UtilValidate.isNotEmpty(sequencedIdPrefix)) {
if (currentSeqId.startsWith(sequencedIdPrefix)) {
currentSeqId = currentSeqId.substring(sequencedIdPrefix.length());
} else {
continue;
}
}
try {
int seqVal = Integer.parseInt(currentSeqId);
if (highestSeqVal == null || seqVal > highestSeqVal.intValue()) {
highestSeqVal = Integer.valueOf(seqVal);
}
} catch (Exception e) {
Debug.logWarning("Error in make-next-seq-id converting SeqId [" + currentSeqId + "] in field: " + seqFieldName + " from entity: " + value.getEntityName() + " to a number: " + e.toString(), module);
}
}
}
int seqValToUse = (highestSeqVal == null ? 1 : highestSeqVal.intValue() + incrementBy);
String newSeqId = sequencedIdPrefix + UtilFormatOut.formatPaddedNumber(seqValToUse, numericPadding);
value.set(seqFieldName, newSeqId);
// only commit the transaction if we started one...
TransactionUtil.commit(beganTransaction);
} catch (Exception e) {
String errMsg = "Failure in setNextSubSeqId 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);
}
Debug.logError(e, "Error making next seqId", module);
}
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#encryptFields(java.util.List)
*/
@Override
@Deprecated
public void encryptFields(List<? extends GenericEntity> entities) throws GenericEntityException {
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#encryptFields(org.ofbiz.entity.GenericEntity)
*/
@Override
@Deprecated
public void encryptFields(GenericEntity entity) throws GenericEntityException {
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#encryptFieldValue(java.lang.String, java.lang.Object)
*/
@Override
@Deprecated
public Object encryptFieldValue(String entityName, Object fieldValue) throws EntityCryptoException {
return encryptFieldValue(entityName, null, fieldValue);
}
@Override
public Object encryptFieldValue(String entityName, ModelField.EncryptMethod encryptMethod, Object fieldValue) throws EntityCryptoException {
if (encryptMethod == null) {
encryptMethod = ModelField.EncryptMethod.TRUE;
}
if (fieldValue != null) {
if (fieldValue instanceof String && UtilValidate.isEmpty(fieldValue)) {
return fieldValue;
}
return this.crypto.encrypt(entityName, encryptMethod, fieldValue);
}
return fieldValue;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#encryptFieldValue(java.lang.String, java.lang.Object)
*/
@Override
public Object decryptFieldValue(String entityName, String encValue) throws EntityCryptoException {
if (UtilValidate.isNotEmpty(encValue)) {
return this.crypto.decrypt(entityName, encValue);
}
return null;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#decryptFields(java.util.List)
*/
@Override
@Deprecated
public void decryptFields(List<? extends GenericEntity> entities) throws GenericEntityException {
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#decryptFields(org.ofbiz.entity.GenericEntity)
*/
@Override
@Deprecated
public void decryptFields(GenericEntity entity) throws GenericEntityException {
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#setEntityCrypto(org.ofbiz.entity.util.EntityCrypto)
*/
@Override
public void setEntityCrypto(EntityCrypto crypto) {
this.crypto = crypto;
}
protected void absorbList(List<GenericValue> lst) {
if (lst == null) {
return;
}
for (GenericValue value: lst) {
value.setDelegator(this);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#getCache()
*/
@Override
public Cache getCache() {
return cache;
}
protected void createEntityAuditLogAll(GenericValue value, boolean isUpdate, boolean isRemove) throws GenericEntityException {
Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
for (ModelField mf: value.getModelEntity().getFieldsUnmodifiable()) {
if (mf.getEnableAuditLog()) {
createEntityAuditLogSingle(value, mf, isUpdate, isRemove, nowTimestamp);
}
}
}
protected void createEntityAuditLogSingle(GenericValue value, ModelField mf, boolean isUpdate, boolean isRemove, Timestamp nowTimestamp) throws GenericEntityException {
if (value == null || mf == null || !mf.getEnableAuditLog() || this.testRollbackInProgress) {
return;
}
String newValueText = null;
String oldValueText = null;
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) {
oldValueText = "[ERROR] Old value not found even though it was an update or remove";
}
} else {
// lookup old value
Object oldValue = oldGv.get(mf.getName());
if (oldValue != null) {
oldValueText = oldValue.toString();
if (oldValueText.length() > 250) {
oldValueText = oldValueText.substring(0, 250);
}
}
}
if (!isRemove) {
Object newValue = value.get(mf.getName());
if (newValue != null) {
newValueText = newValue.toString();
if (newValueText.length() > 250) {
newValueText = newValueText.substring(0, 250);
}
}
}
if (!(newValueText == null ? "" : newValueText).equals((oldValueText == null ? "" : oldValueText))) {
// only save changed values
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);
entityAuditLog.set("newValueText", newValueText);
entityAuditLog.set("oldValueText", oldValueText);
entityAuditLog.set("changedDate", nowTimestamp);
entityAuditLog.set("changedByInfo", getCurrentUserIdentifier());
entityAuditLog.set("changedSessionInfo", getCurrentSessionIdentifier());
this.create(entityAuditLog);
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#cloneDelegator(java.lang.String)
*/
@Override
public Delegator cloneDelegator(String delegatorFullName) {
// 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).
GenericDelegator newDelegator = new GenericDelegator();
newDelegator.modelReader = this.modelReader;
newDelegator.modelGroupReader = this.modelGroupReader;
newDelegator.setDelegatorNames(UtilValidate.isNotEmpty(delegatorFullName) ? delegatorFullName : this.delegatorFullName);
// set the delegatorBaseName to be the same so that configuration settings all work the same as the current
// delegator, allowing the new delegatorFullName to not match a delegator name in the entityengine.xml file
newDelegator.delegatorBaseName = this.delegatorBaseName;
newDelegator.delegatorInfo = this.delegatorInfo;
newDelegator.cache = this.cache;
newDelegator.distributedCacheClear.set(this.distributedCacheClear.get());
newDelegator.originalDelegatorName = getOriginalDelegatorName();
newDelegator.entityEcaHandler.set(this.entityEcaHandler.get());
newDelegator.crypto = this.crypto;
// In case this delegator is in testMode give it a reference to
// the rollback list
newDelegator.testMode = this.testMode;
testOperationsUpdater.set(newDelegator, this.testOperations);
// not setting the sequencer so that we have unique sequences.
return newDelegator;
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#cloneDelegator()
*/
@Override
public Delegator cloneDelegator() {
return this.cloneDelegator(this.delegatorFullName);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#makeTestDelegator(java.lang.String)
*/
@Override
public Delegator makeTestDelegator(String delegatorName) {
GenericDelegator testDelegator = (GenericDelegator) this.cloneDelegator(delegatorName);
testDelegator.entityEcaHandler.set(null);
testDelegator.initEntityEcaHandler();
testDelegator.setTestMode(true);
return testDelegator;
}
private void setTestMode(boolean testMode) {
this.testMode = testMode;
if (testMode) {
testOperationsUpdater.set(this, new LinkedBlockingDeque<TestOperation>());
} else {
this.testOperations.clear();
}
}
private void storeForTestRollback(TestOperation testOperation) {
if (!this.testMode || this.testRollbackInProgress) {
throw new IllegalStateException("An attempt was made to store a TestOperation during rollback or outside of test mode");
}
this.testOperations.add(testOperation);
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#rollback()
*/
@Override
public void rollback() {
if (!this.testMode) {
Debug.logError("Rollback requested outside of testmode", module);
}
this.testMode = false;
this.testRollbackInProgress = true;
if (Debug.infoOn()) {
Debug.logInfo("Rolling back " + testOperations.size() + " entity operations", module);
}
while (!this.testOperations.isEmpty()) {
TestOperation testOperation = this.testOperations.pollLast();
if (testOperation == null) {
break;
}
try {
if (testOperation.getOperation().equals(OperationType.INSERT)) {
this.removeValue(testOperation.getValue());
} else if (testOperation.getOperation().equals(OperationType.UPDATE)) {
this.store(testOperation.getValue());
} else if (testOperation.getOperation().equals(OperationType.DELETE)) {
this.create(testOperation.getValue());
}
} catch (GenericEntityException e) {
Debug.logWarning(e.toString(), module);
}
}
this.testOperations.clear();
this.testRollbackInProgress = false;
this.testMode = true;
}
public final 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;
}
}
/* (non-Javadoc)
* @see org.ofbiz.entity.Delegator#initDistributedCacheClear()
*/
@Override
public void initDistributedCacheClear() {
// Nothing to do if already assigned: the class loader has already been called, the class instantiated and casted to DistributedCacheClear
if (this.distributedCacheClear.get() != null) {
return;
}
Callable<DistributedCacheClear> creator = new Callable<DistributedCacheClear>() {
public DistributedCacheClear call() {
return createDistributedCacheClear();
}
};
FutureTask<DistributedCacheClear> futureTask = new FutureTask<DistributedCacheClear>(creator);
if (distributedCacheClear.compareAndSet(null, futureTask)) {
ExecutionPool.GLOBAL_BATCH.submit(futureTask);
}
}
protected DistributedCacheClear createDistributedCacheClear() {
// If useDistributedCacheClear is false do nothing: the distributedCacheClear member field with a null value would cause dcc code to do nothing
if (useDistributedCacheClear()) {
//time to do some tricks with manual class loading that resolves circular dependencies, like calling services
ClassLoader loader = Thread.currentThread().getContextClassLoader();
// initialize the distributedCacheClear mechanism
String distributedCacheClearClassName = this.delegatorInfo.getDistributedCacheClearClassName();
try {
Class<?> dccClass = loader.loadClass(distributedCacheClearClassName);
DistributedCacheClear distributedCacheClear = UtilGenerics.cast(dccClass.newInstance());
distributedCacheClear.setDelegator(this, this.delegatorInfo.getDistributedCacheClearUserLoginId());
return distributedCacheClear;
} 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.logVerbose("Distributed Cache Clear System disabled for delegator [" + delegatorFullName + "]", module);
}
return null;
}
protected DistributedCacheClear getDistributedCacheClear() {
Future<DistributedCacheClear> future = this.distributedCacheClear.get();
try {
return future != null ? future.get() : null;
} catch (ExecutionException e) {
Debug.logError(e, "Could not fetch DistributedCacheClear from the asynchronous instantiation", module);
} catch (InterruptedException e) {
Debug.logError(e, "Could not fetch DistributedCacheClear from the asynchronous instantiation", module);
}
return null;
}
@Override
public boolean useDistributedCacheClear() {
return this.delegatorInfo.getDistributedCacheClearEnabled();
}
@Override
public String getCurrentSessionIdentifier() {
List<String> curValList = getSessionIdentifierStack();
return curValList.size() > 0 ? curValList.get(0) : null;
}
@Override
public String getCurrentUserIdentifier() {
List<String> curValList = getUserIdentifierStack();
return curValList.size() > 0 ? curValList.get(0) : null;
}
}