mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Full resultset audit queries
- Use RollupRowHandler and nested ResultMap - Audit Map values are pulled back with entries git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16130 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -46,8 +46,7 @@
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap id="result_AuditQueryAllValues"
|
<resultMap id="result_AuditQueryAllValues"
|
||||||
extends="alfresco.audit.result_AuditQueryNoValues"
|
extends="alfresco.audit.result_AuditQueryNoValues"
|
||||||
class="AuditQueryResult"
|
class="AuditQueryResult">
|
||||||
groupBy="auditEntryId">
|
|
||||||
<result property="auditValues" resultMap="alfresco.propval.result_PropertyIdSearchRow"/>
|
<result property="auditValues" resultMap="alfresco.propval.result_PropertyIdSearchRow"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@ import org.alfresco.repo.audit.AuditState;
|
|||||||
import org.alfresco.repo.audit.hibernate.HibernateAuditDAO;
|
import org.alfresco.repo.audit.hibernate.HibernateAuditDAO;
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
|
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
|
||||||
|
import org.alfresco.repo.domain.propval.PropertyIdSearchRow;
|
||||||
import org.alfresco.repo.domain.propval.PropertyValueDAO;
|
import org.alfresco.repo.domain.propval.PropertyValueDAO;
|
||||||
import org.alfresco.service.cmr.audit.AuditInfo;
|
import org.alfresco.service.cmr.audit.AuditInfo;
|
||||||
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||||
@@ -298,15 +299,39 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Get the value map
|
// Get the value map
|
||||||
// TODO: Should be done with a nested resultmapping
|
Map<String, Serializable> auditValues;
|
||||||
Long auditValuesId = row.getAuditValuesId();
|
List<PropertyIdSearchRow> propMapRows = row.getAuditValues();
|
||||||
Pair<Long, Serializable> auditValuesPair = propertyValueDAO.getPropertyValueById(auditValuesId);
|
if (propMapRows == null)
|
||||||
if (auditValuesPair == null)
|
|
||||||
{
|
{
|
||||||
// Ignore
|
// Use the audit values ID
|
||||||
return;
|
Long auditValuesId = row.getAuditValuesId();
|
||||||
|
Pair<Long, Serializable> auditValuesPair = propertyValueDAO.getPropertyValueById(auditValuesId);
|
||||||
|
if (auditValuesPair == null)
|
||||||
|
{
|
||||||
|
// Ignore
|
||||||
|
logger.warn("Audit entry not joined to audit properties: " + row);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auditValues = (Map<String, Serializable>) auditValuesPair.getSecond();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Resolve the map
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auditValues = (Map<String, Serializable>) propertyValueDAO.convertPropertyIdSearchRows(propMapRows);
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
logger.warn("Audit entry not linked to a Map<String, Serializable> value: " + row);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (auditValues == null)
|
||||||
|
{
|
||||||
|
logger.warn("Audit entry incompletely joined to audit properties: " + row);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Map<String, Serializable> auditValues = (Map<String, Serializable>) auditValuesPair.getSecond();
|
|
||||||
more = callback.handleAuditEntry(
|
more = callback.handleAuditEntry(
|
||||||
row.getAuditEntryId(),
|
row.getAuditEntryId(),
|
||||||
row.getAuditAppName(),
|
row.getAuditAppName(),
|
||||||
|
@@ -29,6 +29,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.ibatis.RollupRowHandler;
|
||||||
import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl;
|
import org.alfresco.repo.domain.audit.AbstractAuditDAOImpl;
|
||||||
import org.alfresco.repo.domain.audit.AuditApplicationEntity;
|
import org.alfresco.repo.domain.audit.AuditApplicationEntity;
|
||||||
import org.alfresco.repo.domain.audit.AuditEntryEntity;
|
import org.alfresco.repo.domain.audit.AuditEntryEntity;
|
||||||
@@ -175,25 +176,38 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
|
|||||||
params.setAuditFromTime(from);
|
params.setAuditFromTime(from);
|
||||||
params.setAuditToTime(to);
|
params.setAuditToTime(to);
|
||||||
|
|
||||||
|
// RowHandlers in RowHandlers: See 'groupBy' issue https://issues.apache.org/jira/browse/IBATIS-503
|
||||||
|
RowHandler shreddedRowHandler = new RowHandler()
|
||||||
|
{
|
||||||
|
public void handleRow(Object valueObject)
|
||||||
|
{
|
||||||
|
rowHandler.processResult((AuditQueryResult)valueObject);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
RollupRowHandler rollupRowHandler = new RollupRowHandler(
|
||||||
|
new String[] {"auditEntryId"},
|
||||||
|
"auditValues",
|
||||||
|
shreddedRowHandler,
|
||||||
|
maxResults);
|
||||||
|
|
||||||
if (maxResults > 0)
|
if (maxResults > 0)
|
||||||
{
|
{
|
||||||
List<AuditQueryResult> rows = template.queryForList(SELECT_ENTRIES_SIMPLE, params, 0, maxResults);
|
// Calculate the maximum results required
|
||||||
|
int sqlMaxResults = (maxResults > 0 ? ((maxResults+1) * 20) : Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
List<AuditQueryResult> rows = template.queryForList(SELECT_ENTRIES_WITH_VALUES, params, 0, sqlMaxResults);
|
||||||
for (AuditQueryResult row : rows)
|
for (AuditQueryResult row : rows)
|
||||||
{
|
{
|
||||||
rowHandler.processResult(row);
|
rollupRowHandler.handleRow(row);
|
||||||
}
|
}
|
||||||
|
// Don't process last result:
|
||||||
|
// rollupRowHandler.processLastResults();
|
||||||
|
// The last result may be incomplete
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RowHandler rowHandlerInternal = new RowHandler()
|
template.queryWithRowHandler(SELECT_ENTRIES_WITH_VALUES, params, rollupRowHandler);
|
||||||
{
|
rollupRowHandler.processLastResults();
|
||||||
public void handleRow(Object valueObject)
|
|
||||||
{
|
|
||||||
AuditQueryResult row = (AuditQueryResult) valueObject;
|
|
||||||
rowHandler.processResult(row);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template.queryWithRowHandler(SELECT_ENTRIES_SIMPLE, params, rowHandlerInternal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -833,7 +833,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
|||||||
protected abstract PropertyValueEntity createPropertyValue(Serializable value);
|
protected abstract PropertyValueEntity createPropertyValue(Serializable value);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected Serializable convertPropertyIdSearchRows(List<PropertyIdSearchRow> rows)
|
public Serializable convertPropertyIdSearchRows(List<PropertyIdSearchRow> rows)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The results are ordered by the root_prop_id, current_prop_id and value_prop_id.
|
* The results are ordered by the root_prop_id, current_prop_id and value_prop_id.
|
||||||
@@ -843,8 +843,21 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
|||||||
final Map<Long, Serializable> values = new HashMap<Long, Serializable>(rows.size());
|
final Map<Long, Serializable> values = new HashMap<Long, Serializable>(rows.size());
|
||||||
List<PropertyLinkEntity> keyRows = new ArrayList<PropertyLinkEntity>(5);
|
List<PropertyLinkEntity> keyRows = new ArrayList<PropertyLinkEntity>(5);
|
||||||
Serializable result = null;
|
Serializable result = null;
|
||||||
|
Long rootPropId = null;
|
||||||
for (PropertyIdSearchRow row : rows)
|
for (PropertyIdSearchRow row : rows)
|
||||||
{
|
{
|
||||||
|
// Check that we are handling a single root property
|
||||||
|
if (rootPropId == null)
|
||||||
|
{
|
||||||
|
rootPropId = row.getLinkEntity().getRootPropId();
|
||||||
|
}
|
||||||
|
else if (!rootPropId.equals(row.getLinkEntity().getRootPropId()))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"The root_prop_id for the property search rows must not change: \n" +
|
||||||
|
" Rows: " + rows);
|
||||||
|
}
|
||||||
|
|
||||||
PropertyLinkEntity linkEntity = row.getLinkEntity();
|
PropertyLinkEntity linkEntity = row.getLinkEntity();
|
||||||
PropertyValueEntity valueEntity = row.getValueEntity();
|
PropertyValueEntity valueEntity = row.getValueEntity();
|
||||||
// Construct the value (Maps and Collections should be CONSTRUCTABLE)
|
// Construct the value (Maps and Collections should be CONSTRUCTABLE)
|
||||||
|
@@ -43,34 +43,6 @@ public class PropertyIdSearchRow
|
|||||||
valueEntity = new PropertyValueEntity();
|
valueEntity = new PropertyValueEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public int hashCode()
|
|
||||||
// {
|
|
||||||
// return (int) rootCollectionPropId + (int) valuePropId;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean equals(Object obj)
|
|
||||||
// {
|
|
||||||
// if (this == obj)
|
|
||||||
// {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// else if (obj instanceof PropertyCollectionLinkEntity)
|
|
||||||
// {
|
|
||||||
// PropertyCollectionLinkEntity that = (PropertyCollectionLinkEntity) obj;
|
|
||||||
// return
|
|
||||||
// this.rootCollectionPropId == that.rootCollectionPropId &&
|
|
||||||
// this.currentCollectionPropId == that.currentCollectionPropId &&
|
|
||||||
// this.valuePropId == that.valuePropId &&
|
|
||||||
// this.keyPropId == that.keyPropId;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
@@ -26,6 +26,7 @@ package org.alfresco.repo.domain.propval;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.CrcHelper;
|
import org.alfresco.repo.domain.CrcHelper;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
@@ -195,4 +196,18 @@ public interface PropertyValueDAO
|
|||||||
* @param maxDepth the maximum depth of collections and maps to iterate into
|
* @param maxDepth the maximum depth of collections and maps to iterate into
|
||||||
*/
|
*/
|
||||||
Pair<Long, Serializable> getOrCreatePropertyValue(Serializable value, int maxDepth);
|
Pair<Long, Serializable> getOrCreatePropertyValue(Serializable value, int maxDepth);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to convert property query results into the original value. Note
|
||||||
|
* that the rows must all share the same root property ID.
|
||||||
|
* <p/>
|
||||||
|
* If the rows passed in don't constitute a valid, full property - they don't contain all
|
||||||
|
* the link entities for the property - then the result may be <tt>null</tt>.
|
||||||
|
*
|
||||||
|
* @param rows the search results for a single root property
|
||||||
|
* @return Returns the root property as originally persisted, or <tt>null</tt>
|
||||||
|
* if the rows don't represent a complete property
|
||||||
|
* @throws IllegalArgumentException if rows don't all share the same root property ID
|
||||||
|
*/
|
||||||
|
Serializable convertPropertyIdSearchRows(List<PropertyIdSearchRow> rows);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user