You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by jo...@apache.org on 2008/04/30 04:02:29 UTC
svn commit: r652226 - in /ofbiz/trunk/framework: entity/dtd/
entity/entitydef/ entity/src/org/ofbiz/entity/
entity/src/org/ofbiz/entity/datasource/ entity/src/org/ofbiz/entity/jdbc/
entity/src/org/ofbiz/entity/model/ service/src/org/ofbiz/service/ weba...
Author: jonesde
Date: Tue Apr 29 19:02:29 2008
New Revision: 652226
URL: http://svn.apache.org/viewvc?rev=652226&view=rev
Log:
Added feature to entity engine to support generic audit log that can be used for any field; values are converted to a string and l using the enable-audit-log attribute on the entity->field element; the Testing entity uses it now for the testName; this also has functionality to associate user info like the userLoginId with the thread so that the EE knows about it automatically, and uses a stack for flexibility
Modified:
ofbiz/trunk/framework/entity/dtd/entitymodel.xsd
ofbiz/trunk/framework/entity/entitydef/entitygroup.xml
ofbiz/trunk/framework/entity/entitydef/entitymodel.xml
ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java
ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelField.java
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceDispatcher.java
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java
Modified: ofbiz/trunk/framework/entity/dtd/entitymodel.xsd
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/dtd/entitymodel.xsd?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/dtd/entitymodel.xsd (original)
+++ ofbiz/trunk/framework/entity/dtd/entitymodel.xsd Tue Apr 29 19:02:29 2008
@@ -133,6 +133,15 @@
</xs:restriction>
</xs:simpleType>
</xs:attribute>
+ <xs:attribute name="enable-audit-log" default="false">
+ <xs:annotation><xs:documentation>If this is set to true then whenever the value for this field on a record changes the Entity Engine will record the change in the EntityAuditLog entity. Defaults to false.</xs:documentation></xs:annotation>
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="true"/>
+ <xs:enumeration value="false"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
</xs:attributeGroup>
<xs:element name="validate">
<xs:complexType>
Modified: ofbiz/trunk/framework/entity/entitydef/entitygroup.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/entitydef/entitygroup.xml?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/entitydef/entitygroup.xml (original)
+++ ofbiz/trunk/framework/entity/entitydef/entitygroup.xml Tue Apr 29 19:02:29 2008
@@ -21,16 +21,7 @@
<entitygroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entitygroup.xsd">
- <!-- ========================================================= -->
- <!-- org.ofbiz.entity.sequence -->
- <!-- ========================================================= -->
-
- <entity-group group="org.ofbiz" entity="SequenceValueItem" />
-
- <!-- ========================================================= -->
- <!-- org.ofbiz.entity.crypto -->
- <!-- ========================================================= -->
-
+ <entity-group group="org.ofbiz" entity="EntityAuditLog" />
<entity-group group="org.ofbiz" entity="EntityKeyStore" />
+ <entity-group group="org.ofbiz" entity="SequenceValueItem" />
</entitygroup>
-
Modified: ofbiz/trunk/framework/entity/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/entitydef/entitymodel.xml?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/framework/entity/entitydef/entitymodel.xml Tue Apr 29 19:02:29 2008
@@ -32,31 +32,30 @@
<!-- ========================================================= -->
<!-- ======================== Data Model ===================== -->
<!-- The modules in this file are as follows: -->
- <!-- - org.ofbiz.entity.sequence -->
+ <!-- - org.ofbiz.entity.audit -->
<!-- - org.ofbiz.entity.crypto -->
+ <!-- - org.ofbiz.entity.sequence -->
<!-- ========================================================= -->
- <!-- ========================================================= -->
- <!-- org.ofbiz.entity.sequence -->
- <!-- ========================================================= -->
-
- <entity entity-name="SequenceValueItem"
- package-name="org.ofbiz.entity.sequence"
- title="Sequence Entity">
+ <entity entity-name="EntityAuditLog" package-name="org.ofbiz.entity.audit" title="Entity Audit Log">
+ <field name="auditHistorySeqId" type="id-ne"><description>Sequenced primary key</description></field>
+ <field name="changedEntityName" type="long-varchar"></field>
+ <field name="changedFieldName" type="long-varchar"></field>
+ <field name="pkCombinedValueText" type="long-varchar"></field>
+ <field name="oldValueText" type="long-varchar"></field>
+ <field name="newValueText" type="long-varchar"></field>
+ <field name="changedDate" type="date-time"></field>
+ <field name="changedByInfo" type="long-varchar"><description>This should contain whatever information about the user or system that changed the value that is available. This could be a userLoginId, but could be something else too, so there is no foreign key.</description></field>
+ <prim-key field="auditHistorySeqId"/>
+ </entity>
+ <entity entity-name="EntityKeyStore" package-name="org.ofbiz.entity.crypto" title="Entity Key Store Entity">
+ <field name="keyName" type="id-vlong-ne"></field>
+ <field name="keyText" type="long-varchar"></field>
+ <prim-key field="keyName"/>
+ </entity>
+ <entity entity-name="SequenceValueItem" package-name="org.ofbiz.entity.sequence" title="Sequence Value Item Entity">
<field name="seqName" type="id-long-ne"></field>
<field name="seqId" type="numeric"></field>
<prim-key field="seqName"/>
</entity>
-
- <!-- ========================================================= -->
- <!-- org.ofbiz.entity.crypto -->
- <!-- ========================================================= -->
-
- <entity entity-name="EntityKeyStore"
- package-name="org.ofbiz.entity.crypto"
- title="Entity Key Entity">
- <field name="keyName" type="id-vlong-ne"></field>
- <field name="keyText" type="long-varchar"></field>
- <prim-key field="keyName"/>
- </entity>
</entitymodel>
Modified: ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml (original)
+++ ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml Tue Apr 29 19:02:29 2008
@@ -52,7 +52,7 @@
title="Testing Entity">
<field name="testingId" type="id-ne"/>
<field name="testingTypeId" type="id-ne"/>
- <field name="testingName" type="name"/>
+ <field name="testingName" type="name" enable-audit-log="true"/>
<field name="description" type="description"/>
<field name="comments" type="comment"/>
<field name="testingSize" type="numeric"/>
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericDelegator.java Tue Apr 29 19:02:29 2008
@@ -41,6 +41,7 @@
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralRuntimeException;
+import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilFormatOut;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilValidate;
@@ -92,13 +93,16 @@
protected Cache cache = null;
- // keeps a list of field key sets used in the by and cache, a Set (of Sets of fieldNames) for each entityName
+ /** keeps a list of field key sets used in the by and cache, a Set (of Sets of fieldNames) for each entityName */
protected Map andCacheFieldSets = FastMap.newInstance();
protected DistributedCacheClear distributedCacheClear = null;
protected EntityEcaHandler<?> entityEcaHandler = null;
protected SequenceUtil sequencer = null;
protected EntityCrypto crypto = null;
+
+ /** A ThreadLocal variable to allow other methods to specify an identifier (usually the userLoginId, though technically the Entity Engine doesn't know anything about the UserLogin entity) */
+ protected static ThreadLocal<List<Object>> userIdentifierStack = new ThreadLocal<List<Object>>();
public static GenericDelegator getGenericDelegator(String delegatorName) {
if (delegatorName == null) {
@@ -130,6 +134,47 @@
return delegator;
}
+ protected static List<Object> getUserIdentifierStack() {
+ List<Object> curValList = userIdentifierStack.get();
+ if (curValList == null) {
+ curValList = FastList.newInstance();
+ userIdentifierStack.set(curValList);
+ }
+ return curValList;
+ }
+
+ public static String getCurrentUserIdentifier() {
+ List<Object> curValList = getUserIdentifierStack();
+ Object curVal = curValList.get(0);
+ if (curVal == null) {
+ return null;
+ } else {
+ return curVal.toString();
+ }
+ }
+
+ public static void pushUserIdentifier(String userIdentifier) {
+ if (userIdentifier == null) {
+ return;
+ }
+ List<Object> curValList = getUserIdentifierStack();
+ curValList.add(0, userIdentifier);
+ }
+
+ public static String popUserIdentifier() {
+ List<Object> curValList = getUserIdentifierStack();
+ if (curValList.size() == 0) {
+ return null;
+ } else {
+ return (String) curValList.remove(0);
+ }
+ }
+
+ public static void clearUserIdentifierStack() {
+ List<Object> curValList = getUserIdentifierStack();
+ curValList.clear();
+ }
+
/** Only allow creation through the factory method */
protected GenericDelegator() {}
@@ -250,7 +295,7 @@
public String getDelegatorName() {
return this.delegatorName;
}
-
+
protected DelegatorInfo getDelegatorInfo() {
if (delegatorInfo == null) {
delegatorInfo = EntityConfigUtil.getDelegatorInfo(this.delegatorName);
@@ -618,6 +663,12 @@
value.setDelegator(this);
this.encryptFields(value);
+
+ // if audit log on for any fields, save new value with no old value because it's a create
+ if (value != null && value.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(value, false, false);
+ }
+
try {
value = helper.create(value);
} catch (GenericEntityException e) {
@@ -651,6 +702,7 @@
}
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_CREATE, value, false);
+
return value;
} catch (GenericEntityException e) {
String errMsg = "Failure in create operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
@@ -668,7 +720,7 @@
TransactionUtil.commit(beganTransaction);
}
}
-
+
/** Creates a Entity in the form of a GenericValue and write it to the datasource
*@param value The GenericValue to create a value in the datasource from
*@param doCacheClear boolean that specifies whether or not to automatically clear cache entries related to this operation
@@ -693,6 +745,12 @@
value.setDelegator(this);
this.encryptFields(value);
+
+ // if audit log on for any fields, save new value with no old value because it's a create
+ if (value != null && value.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(value, false, false);
+ }
+
value = helper.create(value);
if (value != null) {
@@ -708,6 +766,7 @@
}
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_CREATE, value, false);
+
return value;
} catch (GenericEntityException e) {
String errMsg = "Failure in create operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
@@ -836,10 +895,17 @@
}
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 != null && primaryKey.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(this.findByPrimaryKey(primaryKey), true, true);
+ }
+
int num = helper.removeByPrimaryKey(primaryKey);
this.saveEntitySyncRemoveInfo(primaryKey);
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_REMOVE, primaryKey, false);
+
return num;
} catch (GenericEntityException e) {
String errMsg = "Failure in removeByPrimaryKey operation for entity [" + primaryKey.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
@@ -890,10 +956,17 @@
}
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 != null && value.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(value, true, true);
+ }
+
int num = helper.removeByPrimaryKey(value.getPrimaryKey());
this.saveEntitySyncRemoveInfo(value.getPrimaryKey());
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_REMOVE, value, false);
+
return num;
} catch (GenericEntityException e) {
String errMsg = "Failure in removeValue operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
@@ -1147,6 +1220,12 @@
ecaRunner.evalRules(EntityEcaHandler.EV_RUN, EntityEcaHandler.OP_STORE, value, false);
this.encryptFields(value);
+
+ // if audit log on for any fields, save old value before the update so we still have both
+ if (value != null && value.getModelEntity().getHasFieldWithAuditLog()) {
+ createEntityAuditLogAll(value, true, false);
+ }
+
int retVal = helper.store(value);
// refresh the valueObject to get the new version
@@ -1155,6 +1234,7 @@
}
ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_STORE, value, false);
+
return retVal;
} catch (GenericEntityException e) {
String errMsg = "Failure in store operation for entity [" + value.getEntityName() + "]: " + e.toString() + ". Rolling back transaction.";
@@ -3001,6 +3081,73 @@
return cache;
}
+ protected void createEntityAuditLogAll(GenericValue value, boolean isUpdate, boolean isRemove) throws GenericEntityException {
+ for (ModelField mf: value.getModelEntity().getFieldsUnmodifiable()) {
+ if (mf.getEnableAuditLog()) {
+ createEntityAuditLogSingle(value, mf, isUpdate, isRemove);
+ }
+ }
+ }
+
+ protected void createEntityAuditLogSingle(GenericValue value, ModelField mf, boolean isUpdate, boolean isRemove) throws GenericEntityException {
+ if (value == null || mf == null || !mf.getEnableAuditLog()) {
+ return;
+ }
+
+ GenericValue entityAuditLog = this.makeValue("EntityAuditLog");
+ entityAuditLog.set("auditHistorySeqId", this.getNextSeqId("EntityAuditLog"));
+ entityAuditLog.set("changedEntityName", value.getEntityName());
+ entityAuditLog.set("changedFieldName", mf.getName());
+
+ String pkCombinedValueText = value.getPkShortValueString();
+ if (pkCombinedValueText.length() > 250) {
+ // uh-oh, the string is too long!
+ pkCombinedValueText = pkCombinedValueText.substring(0, 250);
+ }
+ entityAuditLog.set("pkCombinedValueText", pkCombinedValueText);
+
+ GenericValue oldGv = null;
+ if (isUpdate) {
+ // it's an update, get it from the database
+ oldGv = this.findByPrimaryKey(value.getPrimaryKey());
+ } else if (isRemove) {
+ oldGv = value;
+ }
+ if (oldGv == null) {
+ if (isUpdate || isRemove) {
+ entityAuditLog.set("oldValueText", "[ERROR] Old value not found even though it was an update or remove");
+ }
+ } else {
+ // lookup old value
+ String oldValueText = null;
+ Object oldValue = oldGv.get(mf.getName());
+ if (oldValue != null) {
+ oldValueText = oldValue.toString();
+ if (oldValueText.length() > 250) {
+ oldValueText = oldValueText.substring(0, 250);
+ }
+ }
+ entityAuditLog.set("oldValueText", oldValueText);
+ }
+
+ if (!isRemove) {
+ String newValueText = null;
+ Object newValue = value.get(mf.getName());
+ if (newValue != null) {
+ newValueText = newValue.toString();
+ if (newValueText.length() > 250) {
+ newValueText = newValueText.substring(0, 250);
+ }
+ }
+ entityAuditLog.set("newValueText", newValueText);
+ }
+
+ entityAuditLog.set("changedDate", UtilDateTime.nowTimestamp());
+ entityAuditLog.set("changedByInfo", getCurrentUserIdentifier());
+
+ this.create(entityAuditLog);
+ }
+
public GenericDelegator cloneDelegator(String delegatorName) {
// creates an exact clone of the delegator; except for the sequencer
// note that this will not be cached and should be used only when
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/GenericEntity.java Tue Apr 29 19:02:29 2008
@@ -316,9 +316,7 @@
}
public boolean isPrimaryKey(boolean requireValue) {
TreeSet<String> fieldKeys = new TreeSet<String>(this.fields.keySet());
- Iterator<ModelField> pkIter = getModelEntity().getPksIterator();
- while (pkIter.hasNext()) {
- ModelField curPk = pkIter.next();
+ for (ModelField curPk: this.getModelEntity().getPkFieldsUnmodifiable()) {
String fieldName = curPk.getName();
if (requireValue) {
if (this.fields.get(fieldName) == null) return false;
@@ -337,9 +335,7 @@
}
public boolean containsPrimaryKey(boolean requireValue) {
//TreeSet fieldKeys = new TreeSet(fields.keySet());
- Iterator pkIter = getModelEntity().getPksIterator();
- while (pkIter.hasNext()) {
- ModelField curPk = (ModelField) pkIter.next();
+ for (ModelField curPk: this.getModelEntity().getPkFieldsUnmodifiable()) {
String fieldName = curPk.getName();
if (requireValue) {
if (this.fields.get(fieldName) == null) return false;
@@ -349,6 +345,17 @@
}
return true;
}
+
+ public String getPkShortValueString() {
+ StringBuffer sb = new StringBuffer();
+ for (ModelField curPk: this.getModelEntity().getPkFieldsUnmodifiable()) {
+ if (sb.length() > 0) {
+ sb.append("::");
+ }
+ sb.append(this.get(curPk.getName()));
+ }
+ return sb.toString();
+ }
/** Sets the named field to the passed value, even if the value is null
* @param name The field name to set
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java Tue Apr 29 19:02:29 2008
@@ -108,7 +108,7 @@
SQLProcessor sqlP = new SQLProcessor(helperName);
try {
- return singleInsert(entity, modelEntity, modelEntity.getFieldsCopy(), sqlP);
+ return singleInsert(entity, modelEntity, modelEntity.getFieldsUnmodifiable(), sqlP);
} catch (GenericEntityException e) {
sqlP.rollback();
// no need to create nested, just throw original which will have all info: throw new GenericEntityException("Exception while inserting the following entity: " + entity.toString(), e);
@@ -259,7 +259,7 @@
}
String sql = "UPDATE " + modelEntity.getTableName(datasourceInfo) + " SET " + modelEntity.colNameString(fieldsToSave, "=?, ", "=?", false) + " WHERE " +
- SqlJdbcUtil.makeWhereStringFromFields(modelEntity.getPksCopy(), entity, "AND");
+ SqlJdbcUtil.makeWhereStringFromFields(modelEntity.getPkFieldsUnmodifiable(), entity, "AND");
int retVal = 0;
@@ -461,7 +461,7 @@
* If not all member entities can be updated, then none should be updated
*/
if (meResult.size() == 0) {
- retVal += singleInsert(meGenericValue, memberModelEntity, memberModelEntity.getFieldsCopy(), sqlP);
+ retVal += singleInsert(meGenericValue, memberModelEntity, memberModelEntity.getFieldsUnmodifiable(), sqlP);
} else {
if (meFieldsToSave.size() > 0) {
retVal += singleUpdate(meGenericValue, memberModelEntity, meFieldsToSave, sqlP);
@@ -508,7 +508,7 @@
}
sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, datasourceInfo));
- sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPksCopy(), entity, "AND", datasourceInfo.joinStyle));
+ sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPkFieldsUnmodifiable(), entity, "AND", datasourceInfo.joinStyle));
try {
sqlP.prepareStatement(sqlBuffer.toString(), true, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
@@ -577,7 +577,7 @@
sqlBuffer.append("*");
}
sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, datasourceInfo));
- sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPksCopy(), entity, "AND", datasourceInfo.joinStyle));
+ sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPkFieldsUnmodifiable(), entity, "AND", datasourceInfo.joinStyle));
SQLProcessor sqlP = new SQLProcessor(helperName);
@@ -650,7 +650,7 @@
throw new GenericModelException("In selectListIteratorByCondition invalid field names specified: " + tempKeys.toString());
}
} else {
- selectFields = modelEntity.getFieldsCopy();
+ selectFields = modelEntity.getFieldsUnmodifiable();
}
StringBuilder sqlBuffer = new StringBuilder("SELECT ");
@@ -1007,7 +1007,7 @@
throw new org.ofbiz.entity.GenericNotImplementedException("Operation delete not supported yet for view entities");
}
- String sql = "DELETE FROM " + modelEntity.getTableName(datasourceInfo) + " WHERE " + SqlJdbcUtil.makeWhereStringFromFields(modelEntity.getPksCopy(), entity, "AND");
+ String sql = "DELETE FROM " + modelEntity.getTableName(datasourceInfo) + " WHERE " + SqlJdbcUtil.makeWhereStringFromFields(modelEntity.getPkFieldsUnmodifiable(), entity, "AND");
int retVal;
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/DatabaseUtil.java Tue Apr 29 19:02:29 2008
@@ -1320,9 +1320,7 @@
}
if (pkCount == 0) {
Debug.logInfo("Searching in " + tableNames.size() + " tables for primary key fields ...", module);
- Iterator it = tableNames.iterator();
- while (it.hasNext()) {
- String curTable = (String) it.next();
+ for (String curTable: tableNames) {
curTable = curTable.substring(curTable.indexOf('.') + 1); //cut off schema name
ResultSet rsPks = dbData.getPrimaryKeys(null, lookupSchemaName, curTable);
pkCount += checkPrimaryKeyInfo(rsPks, lookupSchemaName, needsUpperCase, colInfo, messages);
@@ -1765,7 +1763,7 @@
sqlBuf.append(pkName);
}
sqlBuf.append(" PRIMARY KEY (");
- sqlBuf.append(entity.colNameString(entity.getPksCopy()));
+ sqlBuf.append(entity.colNameString(entity.getPkFieldsUnmodifiable()));
sqlBuf.append(")");
if (addFks) {
@@ -2597,7 +2595,7 @@
sqlBuf.append(pkName);
}
sqlBuf.append(" PRIMARY KEY (");
- sqlBuf.append(entity.colNameString(entity.getPksCopy()));
+ sqlBuf.append(entity.colNameString(entity.getPkFieldsUnmodifiable()));
sqlBuf.append(")");
if (Debug.verboseOn()) Debug.logVerbose("[createPrimaryKey] sql=" + sqlBuf.toString(), module);
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java Tue Apr 29 19:02:29 2008
@@ -22,6 +22,7 @@
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -116,6 +117,8 @@
protected boolean autoClearCache = true;
+ protected Boolean hasFieldWithAuditLog = null;
+
/** The location of this entity's definition */
protected String location = "";
@@ -382,6 +385,20 @@
public void setAutoClearCache(boolean autoClearCache) {
this.autoClearCache = autoClearCache;
}
+
+ public boolean getHasFieldWithAuditLog() {
+ if (this.hasFieldWithAuditLog == null) {
+ this.hasFieldWithAuditLog = false;
+ for (ModelField mf: this.fields) {
+ if (mf.getEnableAuditLog()) {
+ this.hasFieldWithAuditLog = true;
+ }
+ }
+ return this.hasFieldWithAuditLog;
+ } else {
+ return this.hasFieldWithAuditLog;
+ }
+ }
/* Get the location of this entity's definition */
public String getLocation() {
@@ -466,11 +483,18 @@
return this.pks.iterator();
}
+ /**
+ * @deprecated Use getPkFieldsUnmodifiable instead.
+ */
public List<ModelField> getPksCopy() {
List<ModelField> newList = FastList.newInstance();
newList.addAll(this.pks);
return newList;
}
+
+ public List<ModelField> getPkFieldsUnmodifiable() {
+ return Collections.unmodifiableList(this.pks);
+ }
public String getFirstPkFieldName() {
List<String> pkFieldNames = this.getPkFieldNames();
@@ -517,12 +541,19 @@
return this.fields.iterator();
}
+ /**
+ * @deprecated Use getFieldsUnmodifiable instead.
+ */
public List<ModelField> getFieldsCopy() {
List<ModelField> newList = FastList.newInstance();
newList.addAll(this.fields);
return newList;
}
+ public List<ModelField> getFieldsUnmodifiable() {
+ return Collections.unmodifiableList(this.fields);
+ }
+
/** The col-name of the Field, the alias of the field if this is on a view-entity */
public String getColNameOrAlias(String fieldName) {
ModelField modelField = this.getField(fieldName);
Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelField.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelField.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelField.java Tue Apr 29 19:02:29 2008
@@ -43,6 +43,7 @@
protected boolean isPk = false;
protected boolean encrypt = false;
protected boolean isAutoCreatedInternal = false;
+ protected boolean enableAuditLog = false;
/** validators to be called when an update is done */
protected List<String> validators = new ArrayList<String>();
@@ -52,15 +53,16 @@
/** Fields Constructor */
public ModelField(String name, String type, String colName, boolean isPk) {
- this(name, type, colName, isPk, false);
+ this(name, type, colName, isPk, false, false);
}
- public ModelField(String name, String type, String colName, boolean isPk, boolean encrypt) {
+ public ModelField(String name, String type, String colName, boolean isPk, boolean encrypt, boolean enableAuditLog) {
this.name = name;
this.type = type;
this.setColName(colName);
this.isPk = isPk;
this.encrypt = encrypt;
+ this.enableAuditLog = enableAuditLog;
}
/** XML Constructor */
@@ -71,6 +73,7 @@
this.isPk = false; // is set elsewhere
this.encrypt = UtilXml.checkBoolean(fieldElement.getAttribute("encrypt"), false);
this.description = UtilXml.childElementValue(fieldElement, "description");
+ this.enableAuditLog = UtilXml.checkBoolean(fieldElement.getAttribute("enable-audit-log"), false);
NodeList validateList = fieldElement.getElementsByTagName("validate");
@@ -138,6 +141,10 @@
public void setEncrypt(boolean encrypt) {
this.encrypt = encrypt;
}
+
+ public boolean getEnableAuditLog() {
+ return this.enableAuditLog;
+ }
public boolean getIsAutoCreatedInternal() {
return this.isAutoCreatedInternal;
Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceDispatcher.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceDispatcher.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceDispatcher.java (original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceDispatcher.java Tue Apr 29 19:02:29 2008
@@ -313,7 +313,6 @@
}
try {
-
int lockRetriesRemaining = LOCK_RETRIES;
boolean needsLockRetry = false;
@@ -341,12 +340,17 @@
//Debug.logInfo("After [" + modelService.name + "] pre-auth ECA, before auth; isFailure=" + isFailure + ", isError=" + isError, module);
context = checkAuth(localName, context, modelService);
- Object userLogin = context.get("userLogin");
+ GenericValue userLogin = (GenericValue) context.get("userLogin");
if (modelService.auth && userLogin == null) {
throw new ServiceAuthException("User authorization is required for this service: " + modelService.name + modelService.debugInfo());
}
+ // now that we have authed, if there is a userLogin, set the EE userIdentifier
+ if (userLogin != null && userLogin.getString("userLoginId") != null) {
+ GenericDelegator.pushUserIdentifier(userLogin.getString("userLoginId"));
+ }
+
// pre-validate ECA
if (eventMap != null) ServiceEcaUtil.evalRules(modelService.name, eventMap, "in-validate", ctx, context, result, isError, isFailure);
@@ -539,6 +543,9 @@
// call notifications -- event is determined from the result (success, error, fail)
modelService.evalNotifications(this.getLocalContext(localName), context, result);
+
+ // clear out the EE userIdentifier
+ GenericDelegator.popUserIdentifier();
}
} catch (GenericTransactionException te) {
Debug.logError(te, "Problems with the transaction", module);
Modified: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java?rev=652226&r1=652225&r2=652226&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java (original)
+++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ControlServlet.java Tue Apr 29 19:02:29 2008
@@ -108,6 +108,11 @@
GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
//Debug.log("Cert Chain: " + request.getAttribute("javax.servlet.request.X509Certificate"), module);
+ // set the Entity Engine user info if we have a userLogin
+ if (userLogin != null) {
+ GenericDelegator.pushUserIdentifier(userLogin.getString("userLoginId"));
+ }
+
// workaraound if we are in the root webapp
String webappName = UtilHttp.getApplicationName(request);
@@ -176,7 +181,7 @@
// setup some things that should always be there
UtilHttp.setInitialRequestInfo(request);
VisitHandler.getVisitor(request, response);
-
+
// display details on the servlet objects
if (Debug.verboseOn()) {
logRequestInfo(request);
@@ -255,7 +260,7 @@
}
}
- // sanity check; make sure we don't have any transactions in place
+ // sanity check: make sure we don't have any transactions in place
try {
// roll back current TX first
if (TransactionUtil.isTransactionInPlace()) {
@@ -271,6 +276,9 @@
} catch (GenericTransactionException e) {
Debug.logWarning(e, module);
}
+
+ // sanity check 2: make sure there are no user infos in the delegator, ie clear the thread
+ GenericDelegator.clearUserIdentifierStack();
// run these two again before the ServerHitBin.countRequest call because on a logout this will end up creating a new visit
if (response.isCommitted() && request.getSession(false) == null) {