mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Audit queries
- Any combination of application (e.g. RM, repo, etc), user and time - TODO: Extend queries to support finding audit entries by arbitrary audited values - TODO: Full map retrieval in single query git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16086 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -85,6 +85,10 @@
|
|||||||
<bean name="auditModel.extractor.simpleValue" class="org.alfresco.repo.audit.extractor.SimpleValueDataExtractor">
|
<bean name="auditModel.extractor.simpleValue" class="org.alfresco.repo.audit.extractor.SimpleValueDataExtractor">
|
||||||
<property name="registry" ref="auditModel.extractorRegistry" />
|
<property name="registry" ref="auditModel.extractorRegistry" />
|
||||||
</bean>
|
</bean>
|
||||||
|
<bean name="auditModel.extractor.nodeName" class="org.alfresco.repo.audit.extractor.NodeNameDataExtractor">
|
||||||
|
<property name="registry" ref="auditModel.extractorRegistry" />
|
||||||
|
<property name="nodeService" ref="nodeService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Data Generators -->
|
<!-- Data Generators -->
|
||||||
<bean id="auditModel.generatorRegistry" class="org.alfresco.util.registry.NamedObjectRegistry">
|
<bean id="auditModel.generatorRegistry" class="org.alfresco.util.registry.NamedObjectRegistry">
|
||||||
@@ -96,6 +100,11 @@
|
|||||||
<bean name="auditModel.generator.user" class="org.alfresco.repo.audit.generator.AuthenticatedUserDataGenerator">
|
<bean name="auditModel.generator.user" class="org.alfresco.repo.audit.generator.AuthenticatedUserDataGenerator">
|
||||||
<property name="registry" ref="auditModel.generatorRegistry" />
|
<property name="registry" ref="auditModel.generatorRegistry" />
|
||||||
</bean>
|
</bean>
|
||||||
|
<bean name="auditModel.generator.personFullName" class="org.alfresco.repo.audit.generator.AuthenticatedPersonDataGenerator">
|
||||||
|
<property name="registry" ref="auditModel.generatorRegistry" />
|
||||||
|
<property name="personService" ref="personService" />
|
||||||
|
<property name="nodeService" ref="nodeService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Models -->
|
<!-- Models -->
|
||||||
<bean id="auditModel.modelRegistry" class="org.alfresco.repo.audit.model.AuditModelRegistry">
|
<bean id="auditModel.modelRegistry" class="org.alfresco.repo.audit.model.AuditModelRegistry">
|
||||||
|
@@ -78,6 +78,7 @@ CREATE TABLE alf_prop_link
|
|||||||
value_prop_id BIGINT NOT NULL,
|
value_prop_id BIGINT NOT NULL,
|
||||||
key_prop_id BIGINT NOT NULL,
|
key_prop_id BIGINT NOT NULL,
|
||||||
INDEX idx_alf_prop_coll_rev (value_prop_id, root_prop_id),
|
INDEX idx_alf_prop_coll_rev (value_prop_id, root_prop_id),
|
||||||
|
CONSTRAINT fk_alf_prop_link_root FOREIGN KEY (root_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
|
||||||
PRIMARY KEY (root_prop_id, current_prop_id, value_prop_id, key_prop_id)
|
PRIMARY KEY (root_prop_id, current_prop_id, value_prop_id, key_prop_id)
|
||||||
) ENGINE=InnoDB;
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
<typeAlias alias="AuditModel" type="org.alfresco.repo.domain.audit.AuditModelEntity"/>
|
<typeAlias alias="AuditModel" type="org.alfresco.repo.domain.audit.AuditModelEntity"/>
|
||||||
<typeAlias alias="AuditApplication" type="org.alfresco.repo.domain.audit.AuditApplicationEntity"/>
|
<typeAlias alias="AuditApplication" type="org.alfresco.repo.domain.audit.AuditApplicationEntity"/>
|
||||||
<typeAlias alias="AuditEntry" type="org.alfresco.repo.domain.audit.AuditEntryEntity"/>
|
<typeAlias alias="AuditEntry" type="org.alfresco.repo.domain.audit.AuditEntryEntity"/>
|
||||||
|
<typeAlias alias="AuditQueryParameters" type="org.alfresco.repo.domain.audit.AuditQueryParameters"/>
|
||||||
|
<typeAlias alias="AuditQueryResult" type="org.alfresco.repo.domain.audit.AuditQueryResult"/>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- Result Maps -->
|
<!-- Result Maps -->
|
||||||
@@ -35,6 +37,13 @@
|
|||||||
<result property="auditTime" column="audit_time" jdbcType="BIGINT" javaType="long"/>
|
<result property="auditTime" column="audit_time" jdbcType="BIGINT" javaType="long"/>
|
||||||
<result property="auditValuesId" column="audit_values_id" jdbcType="BIGINT" javaType="long"/>
|
<result property="auditValuesId" column="audit_values_id" jdbcType="BIGINT" javaType="long"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
<resultMap id="result.AuditQuery" class="AuditQueryResult">
|
||||||
|
<result property="auditEntryId" column="audit_entry_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
|
<result property="auditAppName" column="audit_app_name" jdbcType="VARCHAR" javaType="string"/>
|
||||||
|
<result property="auditUser" column="audit_user" jdbcType="VARCHAR" javaType="string"/>
|
||||||
|
<result property="auditTime" column="audit_time" jdbcType="BIGINT" javaType="long"/>
|
||||||
|
<result property="auditValuesId" column="audit_values_id" jdbcType="BIGINT" javaType="long"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- Parameter Maps -->
|
<!-- Parameter Maps -->
|
||||||
@@ -43,6 +52,14 @@
|
|||||||
<parameterMap id="parameter.IdMap" class="map">
|
<parameterMap id="parameter.IdMap" class="map">
|
||||||
<parameter property="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
</parameterMap>
|
</parameterMap>
|
||||||
|
<parameterMap id="parameter.AuditQuery" class="AuditQueryParameters">
|
||||||
|
<parameter property="auditAppNameShort" jdbcType="VARCHAR" javaType="string"/>
|
||||||
|
<parameter property="auditAppNameCrc" jdbcType="BIGINT" javaType="long"/>
|
||||||
|
<parameter property="auditUserShort" jdbcType="VARCHAR" javaType="string"/>
|
||||||
|
<parameter property="auditUserCrc" jdbcType="BIGINT" javaType="long"/>
|
||||||
|
<parameter property="auditFromTime" jdbcType="BIGINT" javaType="long"/>
|
||||||
|
<parameter property="auditToTime" jdbcType="BIGINT" javaType="long"/>
|
||||||
|
</parameterMap>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!-- SQL Snippets -->
|
<!-- SQL Snippets -->
|
||||||
@@ -87,4 +104,39 @@
|
|||||||
audit_model_id = ?
|
audit_model_id = ?
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- Get audit entries by application name -->
|
||||||
|
<!-- TODO: Use compound parameters for string searching, possibly namespaced from propval -->
|
||||||
|
<!-- TODO: Use compound result map for audit values -->
|
||||||
|
<select id="select.AuditEntriesSimple" parameterClass="AuditQueryParameters" resultMap="result.AuditQuery">
|
||||||
|
select
|
||||||
|
entry.id as audit_entry_id,
|
||||||
|
user_sv.string_value as audit_user,
|
||||||
|
app_sv.string_value as audit_app_name,
|
||||||
|
entry.audit_time as audit_time,
|
||||||
|
entry.audit_values_id as audit_values_id
|
||||||
|
from
|
||||||
|
alf_audit_app app
|
||||||
|
join alf_prop_value app_pv on (app_pv.id = app.app_name_id)
|
||||||
|
join alf_prop_string_value app_sv on (app_sv.id = app_pv.long_value and app_pv.persisted_type = 3)
|
||||||
|
join alf_audit_entry entry on (entry.audit_app_id = app.id)
|
||||||
|
join alf_prop_value user_pv on (user_pv.id = entry.audit_user_id)
|
||||||
|
join alf_prop_string_value user_sv on (user_sv.id = user_pv.long_value and user_pv.persisted_type = 3)
|
||||||
|
<dynamic prepend="where">
|
||||||
|
<isNotNull prepend="and" property="auditAppNameShort">
|
||||||
|
app_sv.string_end_lower = #auditAppNameShort# and
|
||||||
|
app_sv.string_crc = #auditAppNameCrc#
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditUserShort">
|
||||||
|
user_sv.string_end_lower = #auditUserShort# and
|
||||||
|
user_sv.string_crc = #auditUserCrc#
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditFromTime">
|
||||||
|
<![CDATA[entry.audit_time >= #auditFromTime#]]>
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditToTime">
|
||||||
|
<![CDATA[entry.audit_time < #auditToTime#]]>
|
||||||
|
</isNotNull>
|
||||||
|
</dynamic>
|
||||||
|
</select>
|
||||||
|
|
||||||
</sqlMap>
|
</sqlMap>
|
@@ -31,6 +31,7 @@ import java.util.Map;
|
|||||||
import org.alfresco.repo.audit.model.AuditApplication;
|
import org.alfresco.repo.audit.model.AuditApplication;
|
||||||
import org.alfresco.repo.audit.model._3.AuditPath;
|
import org.alfresco.repo.audit.model._3.AuditPath;
|
||||||
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.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
|
||||||
@@ -107,4 +108,18 @@ public interface AuditComponent
|
|||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
Map<String, Serializable> audit(String applicationName, String rootPath, Map<String, Serializable> values);
|
Map<String, Serializable> audit(String applicationName, String rootPath, Map<String, Serializable> values);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the audit entries that match the given criteria.
|
||||||
|
*
|
||||||
|
* @param callback the callback that will handle results
|
||||||
|
* @param applicationName if not <tt>null</tt>, find entries logged against this application
|
||||||
|
* @param user if not <tt>null</tt>, find entries logged against this user
|
||||||
|
* @param from the start search time (<tt>null</tt> to start at the beginning)
|
||||||
|
* @param to the end search time (<tt>null</tt> for no limit)
|
||||||
|
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
||||||
|
*/
|
||||||
|
void auditQuery(
|
||||||
|
AuditQueryCallback callback,
|
||||||
|
String applicationName, String user, Long from, Long to, int maxResults);
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.repo.audit.extractor.DataExtractor;
|
import org.alfresco.repo.audit.extractor.DataExtractor;
|
||||||
import org.alfresco.repo.audit.generator.DataGenerator;
|
import org.alfresco.repo.audit.generator.DataGenerator;
|
||||||
import org.alfresco.repo.audit.model.AuditApplication;
|
import org.alfresco.repo.audit.model.AuditApplication;
|
||||||
@@ -49,6 +50,7 @@ import org.alfresco.service.Auditable;
|
|||||||
import org.alfresco.service.NotAuditable;
|
import org.alfresco.service.NotAuditable;
|
||||||
import org.alfresco.service.PublicService;
|
import org.alfresco.service.PublicService;
|
||||||
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.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
@@ -883,30 +885,16 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
final Serializable data;
|
final Serializable data;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
data = extractor.convert(value);
|
data = extractor.extractData(value);
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
Log extractorLogger = LogFactory.getLog(extractor.getClass());
|
throw new AlfrescoRuntimeException(
|
||||||
if (extractorLogger.isDebugEnabled())
|
"Failed to extract audit data: \n" +
|
||||||
{
|
" Path: " + path + "\n" +
|
||||||
extractorLogger.debug(
|
" Raw value: " + value + "\n" +
|
||||||
"Failed to extract audit data: \n" +
|
" Extractor: " + extractor,
|
||||||
" Path: " + path + "\n" +
|
e);
|
||||||
" Raw value: " + value + "\n" +
|
|
||||||
" Extractor: " + extractor,
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
extractorLogger.warn(
|
|
||||||
"Failed to extract audit data (turn on DEBUG for full stack): \n" +
|
|
||||||
" Path: " + path + "\n" +
|
|
||||||
" Raw value: " + value + "\n" +
|
|
||||||
" Extractor: " + extractor + "\n" +
|
|
||||||
" Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// Add it to the map
|
// Add it to the map
|
||||||
newData.put(extractorPath, data);
|
newData.put(extractorPath, data);
|
||||||
@@ -943,24 +931,11 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
Log generatorLogger = LogFactory.getLog(generator.getClass());
|
throw new AlfrescoRuntimeException(
|
||||||
if (generatorLogger.isDebugEnabled())
|
"Failed to generate audit data: \n" +
|
||||||
{
|
" Path: " + path + "\n" +
|
||||||
generatorLogger.debug(
|
" Generator: " + generator,
|
||||||
"Failed to generate audit data: \n" +
|
e);
|
||||||
" Path: " + path + "\n" +
|
|
||||||
" Generator: " + generator,
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
generatorLogger.warn(
|
|
||||||
"Failed to generate audit data (turn on DEBUG for full stack): \n" +
|
|
||||||
" Path: " + path + "\n" +
|
|
||||||
" Generator: " + generator + "\n" +
|
|
||||||
" Error: " + e.getMessage());
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// Add it to the map
|
// Add it to the map
|
||||||
newData.put(path, data);
|
newData.put(path, data);
|
||||||
@@ -968,4 +943,27 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
// Done
|
// Done
|
||||||
return newData;
|
return newData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void auditQuery(
|
||||||
|
AuditQueryCallback callback,
|
||||||
|
String applicationName,
|
||||||
|
String user,
|
||||||
|
Long from,
|
||||||
|
Long to,
|
||||||
|
int maxResults)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("callback", callback);
|
||||||
|
|
||||||
|
// Shortcuts
|
||||||
|
if (from != null && to != null && from.compareTo(to) > 0)
|
||||||
|
{
|
||||||
|
// Time range can't yield results
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auditDAO.findAuditEntries(callback, applicationName, user, from, to, maxResults);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,12 +39,16 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.alfresco.util.EqualsHelper;
|
import org.alfresco.util.EqualsHelper;
|
||||||
|
import org.apache.commons.lang.mutable.MutableInt;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
@@ -62,6 +66,8 @@ public class AuditComponentTest extends TestCase
|
|||||||
private static final String APPLICATION_TEST = "Alfresco Test";
|
private static final String APPLICATION_TEST = "Alfresco Test";
|
||||||
private static final String APPLICATION_ACTIONS_TEST = "Actions Test";
|
private static final String APPLICATION_ACTIONS_TEST = "Actions Test";
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(AuditComponentTest.class);
|
||||||
|
|
||||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||||
|
|
||||||
private AuditModelRegistry auditModelRegistry;
|
private AuditModelRegistry auditModelRegistry;
|
||||||
@@ -71,6 +77,7 @@ public class AuditComponentTest extends TestCase
|
|||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
private NodeRef nodeRef;
|
private NodeRef nodeRef;
|
||||||
|
private String user;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
@@ -96,7 +103,8 @@ public class AuditComponentTest extends TestCase
|
|||||||
nodeRef = AuthenticationUtil.runAs(testRunAs, AuthenticationUtil.getSystemUserName());
|
nodeRef = AuthenticationUtil.runAs(testRunAs, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
// Authenticate
|
// Authenticate
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser("User-" + getName());
|
user = "User-" + getName();
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -254,9 +262,9 @@ public class AuditComponentTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a session and use it within a single txn
|
* Test auditing of something resembling real-world data
|
||||||
*/
|
*/
|
||||||
public void testSession_Action01() throws Exception
|
public void testAudit_Action01() throws Exception
|
||||||
{
|
{
|
||||||
Serializable valueA = new Date();
|
Serializable valueA = new Date();
|
||||||
Serializable valueB = "BBB-value-here";
|
Serializable valueB = "BBB-value-here";
|
||||||
@@ -283,4 +291,81 @@ public class AuditComponentTest extends TestCase
|
|||||||
// Check
|
// Check
|
||||||
checkAuditMaps(result, expected);
|
checkAuditMaps(result, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testQuery_Action01() throws Exception
|
||||||
|
{
|
||||||
|
final Long beforeTime = new Long(System.currentTimeMillis());
|
||||||
|
|
||||||
|
// Make sure that we have something to search for
|
||||||
|
testAudit_Action01();
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
final MutableInt rowCount = new MutableInt();
|
||||||
|
|
||||||
|
AuditQueryCallback callback = new AuditQueryCallback()
|
||||||
|
{
|
||||||
|
public boolean handleAuditEntry(
|
||||||
|
Long entryId, String applicationName, String user, long time, Map<String, Serializable> values)
|
||||||
|
{
|
||||||
|
assertNotNull(applicationName);
|
||||||
|
assertNotNull(user);
|
||||||
|
|
||||||
|
sb.append("Row: ")
|
||||||
|
.append(entryId).append(" | ")
|
||||||
|
.append(applicationName).append(" | ")
|
||||||
|
.append(user).append(" | ")
|
||||||
|
.append(new Date(time)).append(" | ")
|
||||||
|
.append(values).append(" | ")
|
||||||
|
.append("\n");
|
||||||
|
;
|
||||||
|
rowCount.setValue(rowCount.intValue() + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
rowCount.setValue(0);
|
||||||
|
auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, null, null, -1);
|
||||||
|
assertTrue("Expected some data", rowCount.intValue() > 0);
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
int allResults = rowCount.intValue();
|
||||||
|
|
||||||
|
// Limit by count
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
rowCount.setValue(0);
|
||||||
|
auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, null, null, 1);
|
||||||
|
assertEquals("Expected to limit data", 1, rowCount.intValue());
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
|
||||||
|
// Limit by time and query up to and excluding the 'before' time
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
rowCount.setValue(0);
|
||||||
|
auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, null, beforeTime, -1);
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
int resultsBefore = rowCount.intValue();
|
||||||
|
|
||||||
|
// Limit by time and query from and including the 'before' time
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
rowCount.setValue(0);
|
||||||
|
auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, null, beforeTime, null, -1);
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
int resultsAfter = rowCount.intValue();
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
"Time-limited queries did not get all results before and after a time",
|
||||||
|
allResults, (resultsBefore + resultsAfter));
|
||||||
|
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
rowCount.setValue(0);
|
||||||
|
auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, user, null, null, -1);
|
||||||
|
assertTrue("Expected some data for specific user", rowCount.intValue() > 0);
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
|
||||||
|
sb.delete(0, sb.length());
|
||||||
|
rowCount.setValue(0);
|
||||||
|
auditComponent.auditQuery(callback, APPLICATION_ACTIONS_TEST, "Numpty", null, null, -1);
|
||||||
|
assertTrue("Expected no data for bogus user", rowCount.intValue() == 0);
|
||||||
|
logger.debug(sb.toString());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
* As a special exception to the terms and conditions of version 2.0 of
|
|
||||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
|
||||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
|
||||||
* FLOSS exception. You should have recieved a copy of the text describing
|
|
||||||
* the FLOSS exception, and it is also available here:
|
|
||||||
* http://www.alfresco.com/legal/licensing"
|
|
||||||
*/
|
|
||||||
package org.alfresco.repo.audit;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.alfresco.util.ParameterCheck;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bean to hold audit entry data. An audit entry represents a single audit call, but the
|
|
||||||
* data stored may be a large map.
|
|
||||||
*
|
|
||||||
* @author Derek Hulley
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public class AuditEntry
|
|
||||||
{
|
|
||||||
private final String user;
|
|
||||||
private final long time;
|
|
||||||
private final Long valuesId;
|
|
||||||
private final Map<String, Serializable> values;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Comment
|
|
||||||
*/
|
|
||||||
public AuditEntry(String user, long time, Long valuesId, Map<String, Serializable> values)
|
|
||||||
{
|
|
||||||
ParameterCheck.mandatoryString("user", user);
|
|
||||||
ParameterCheck.mandatory("time", time);
|
|
||||||
|
|
||||||
this.user = user;
|
|
||||||
this.time = time;
|
|
||||||
this.valuesId = valuesId;
|
|
||||||
this.values = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder(512);
|
|
||||||
sb.append("AuditEntry")
|
|
||||||
.append("[ user=").append(user)
|
|
||||||
.append(", time=").append(new Date(time))
|
|
||||||
.append(", valuesId=").append(valuesId)
|
|
||||||
.append(", values=").append(values)
|
|
||||||
.append("]");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUser()
|
|
||||||
{
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTime()
|
|
||||||
{
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getValuesId()
|
|
||||||
{
|
|
||||||
return valuesId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Serializable> getValues()
|
|
||||||
{
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -35,6 +35,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,9 +130,16 @@ public class AuditServiceImpl implements AuditService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
|
* @see AuditComponent#auditQuery(AuditQueryCallback, String, String, Long, Long, int)
|
||||||
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public void auditQuery(AuditQueryCallback callback, String auditPath, String user, long from, long to, int limit)
|
public void auditQuery(
|
||||||
|
AuditQueryCallback callback,
|
||||||
|
String applicationName, String user, Long from, Long to, int maxResults)
|
||||||
|
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException();
|
ParameterCheck.mandatory("callback", callback);
|
||||||
|
|
||||||
|
auditComponent.auditQuery(callback, applicationName, user, from, to, maxResults);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -26,6 +26,8 @@ package org.alfresco.repo.audit.extractor;
|
|||||||
|
|
||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
import org.alfresco.util.registry.NamedObjectRegistry;
|
import org.alfresco.util.registry.NamedObjectRegistry;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.BeanNameAware;
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
@@ -37,6 +39,9 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractDataExtractor implements DataExtractor, InitializingBean, BeanNameAware
|
public abstract class AbstractDataExtractor implements DataExtractor, InitializingBean, BeanNameAware
|
||||||
{
|
{
|
||||||
|
/** Logger that can be used by subclasses */
|
||||||
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private NamedObjectRegistry<DataExtractor> registry;
|
private NamedObjectRegistry<DataExtractor> registry;
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ import java.io.Serializable;
|
|||||||
* components for recording.
|
* components for recording.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The framework will first determine if data passed into the instance is {@link #isSupported(Object) supported}
|
* The framework will first determine if data passed into the instance is {@link #isSupported(Object) supported}
|
||||||
* and will then pass it in for {@link #convert(Object) conversion} to the type that will be
|
* and will then pass it in for {@link #extractData(Serializable) conversion} to the type that will be
|
||||||
* recorded.
|
* recorded.
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
@@ -51,9 +51,9 @@ public interface DataExtractor
|
|||||||
/**
|
/**
|
||||||
* Convert an value passed into the audit components into a value to be recorded.
|
* Convert an value passed into the audit components into a value to be recorded.
|
||||||
*
|
*
|
||||||
* @param value the value to convert
|
* @param value the source data
|
||||||
* @return the (potentially) converted value
|
* @return the extracted data or <tt>null</tt> if the value is not relevant
|
||||||
* @throws Throwable All errors will be handled by the calling framework
|
* @throws Throwable All errors will be handled by the calling framework
|
||||||
*/
|
*/
|
||||||
public Serializable convert(Serializable value) throws Throwable;
|
public Serializable extractData(Serializable value) throws Throwable;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.audit.extractor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An extractor that pulls out the {@link ContentModel#PROP_NAME <b>cm:name</b>} property from a node.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public class NodeNameDataExtractor extends AbstractDataExtractor
|
||||||
|
{
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the service to get the property from
|
||||||
|
*/
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
super.afterPropertiesSet();
|
||||||
|
PropertyCheck.mandatory(this, "nodeService", nodeService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns <tt>true</tt> if the data is a {@link NodeRef}
|
||||||
|
*/
|
||||||
|
public boolean isSupported(Serializable data)
|
||||||
|
{
|
||||||
|
return (data != null && data instanceof NodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the <b>cm:name</b> property from the node
|
||||||
|
*/
|
||||||
|
public Serializable extractData(Serializable in) throws Throwable
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = (NodeRef) in;
|
||||||
|
String nodeName = null;
|
||||||
|
if (!nodeService.exists(nodeRef))
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Extractor can't pull value from non-existent node: " + nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodeName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||||
|
}
|
||||||
|
return nodeName;
|
||||||
|
}
|
||||||
|
}
|
@@ -47,7 +47,7 @@ public class SimpleValueDataExtractor extends AbstractDataExtractor
|
|||||||
/**
|
/**
|
||||||
* Just returns the value unchanged
|
* Just returns the value unchanged
|
||||||
*/
|
*/
|
||||||
public Serializable convert(Serializable in) throws Throwable
|
public Serializable extractData(Serializable in) throws Throwable
|
||||||
{
|
{
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,8 @@ package org.alfresco.repo.audit.generator;
|
|||||||
|
|
||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
import org.alfresco.util.registry.NamedObjectRegistry;
|
import org.alfresco.util.registry.NamedObjectRegistry;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.BeanNameAware;
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
@@ -37,6 +39,9 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractDataGenerator implements DataGenerator, InitializingBean, BeanNameAware
|
public abstract class AbstractDataGenerator implements DataGenerator, InitializingBean, BeanNameAware
|
||||||
{
|
{
|
||||||
|
/** Logger that can be used by subclasses */
|
||||||
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private NamedObjectRegistry<DataGenerator> registry;
|
private NamedObjectRegistry<DataGenerator> registry;
|
||||||
|
|
||||||
|
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.audit.generator;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives back the full name (person details) of the currently-authenticated user.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public class AuthenticatedPersonDataGenerator extends AbstractDataGenerator
|
||||||
|
{
|
||||||
|
private PersonService personService;
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the service used to discover the user's person node
|
||||||
|
*/
|
||||||
|
public void setPersonService(PersonService personService)
|
||||||
|
{
|
||||||
|
this.personService = personService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the service to retrieve the user's full name
|
||||||
|
*/
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception
|
||||||
|
{
|
||||||
|
super.afterPropertiesSet();
|
||||||
|
PropertyCheck.mandatory(this, "personService", personService);
|
||||||
|
PropertyCheck.mandatory(this, "nodeService", nodeService);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the full name of the currently-authenticated user
|
||||||
|
*/
|
||||||
|
public Serializable getData() throws Throwable
|
||||||
|
{
|
||||||
|
String user = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||||
|
NodeRef personNodeRef = personService.getPerson(user);
|
||||||
|
String fullName = null;
|
||||||
|
if (personNodeRef != null && nodeService.exists(personNodeRef))
|
||||||
|
{
|
||||||
|
String firstName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_FIRSTNAME);
|
||||||
|
String lastName = (String)nodeService.getProperty(personNodeRef, ContentModel.PROP_LASTNAME);
|
||||||
|
|
||||||
|
fullName = ((firstName != null && firstName.length() > 0) ? firstName : "");
|
||||||
|
if (lastName != null && lastName.length() > 0)
|
||||||
|
{
|
||||||
|
fullName += (fullName.length() > 0 ? " " : "");
|
||||||
|
fullName += lastName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Done
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Generated name '" + fullName + "' for user '" + user + "'.");
|
||||||
|
}
|
||||||
|
return fullName;
|
||||||
|
}
|
||||||
|
}
|
@@ -41,7 +41,7 @@ public interface DataGenerator
|
|||||||
/**
|
/**
|
||||||
* Get the data generated by the instance.
|
* Get the data generated by the instance.
|
||||||
*
|
*
|
||||||
* @return Returns the generated data
|
* @return Returns the generated data or <tt>null</tt> if no data could be generated
|
||||||
* @throws Throwable All exceptions are handled by the framework
|
* @throws Throwable All exceptions are handled by the framework
|
||||||
*/
|
*/
|
||||||
public Serializable getData() throws Throwable;
|
public Serializable getData() throws Throwable;
|
||||||
|
@@ -52,6 +52,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
|||||||
import org.alfresco.repo.transaction.TransactionalDao;
|
import org.alfresco.repo.transaction.TransactionalDao;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
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.repository.ContentData;
|
import org.alfresco.service.cmr.repository.ContentData;
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
@@ -140,39 +141,6 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
|
|||||||
this.localSessionFactory = localSessionFactory;
|
this.localSessionFactory = localSessionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Fallout implementation from new audit DAO
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException always
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public Pair<Long, ContentData> getOrCreateAuditModel(URL url)
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fallout implementation from new audit DAO
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException always
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public Long getOrCreateAuditApplication(Long modelId, String applicationName)
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fallout implementation from new audit DAO
|
|
||||||
*
|
|
||||||
* @throws UnsupportedOperationException always
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values)
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void audit(AuditState auditInfo)
|
public void audit(AuditState auditInfo)
|
||||||
{
|
{
|
||||||
if (auditInfo.getUserIdentifier() == null)
|
if (auditInfo.getUserIdentifier() == null)
|
||||||
@@ -680,5 +648,54 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
|
|||||||
query.setParameter(QUERY_AUDIT_DATE_PARAM, date);
|
query.setParameter(QUERY_AUDIT_DATE_PARAM, date);
|
||||||
return (AuditDate) query.uniqueResult();
|
return (AuditDate) query.uniqueResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* V3.2 from here on. Put all fixes to the older audit code before this point, please.
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* Fallout implementation from new audit DAO
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public Pair<Long, ContentData> getOrCreateAuditModel(URL url)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallout implementation from new audit DAO
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public Long getOrCreateAuditApplication(Long modelId, String applicationName)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallout implementation from new audit DAO
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallout implementation from new audit DAO
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public void findAuditEntries(
|
||||||
|
AuditQueryCallback callback,
|
||||||
|
String applicationName, String user, Long from, Long to, int maxResults)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
@@ -40,6 +40,7 @@ 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.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.repository.ContentData;
|
import org.alfresco.service.cmr.repository.ContentData;
|
||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
@@ -61,7 +62,7 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
private HibernateAuditDAO oldDAO;
|
private HibernateAuditDAO oldDAO;
|
||||||
private ContentService contentService;
|
private ContentService contentService;
|
||||||
private ContentDataDAO contentDataDAO;
|
private ContentDataDAO contentDataDAO;
|
||||||
private PropertyValueDAO propertyValueDAO;
|
protected PropertyValueDAO propertyValueDAO;
|
||||||
|
|
||||||
public void setOldDAO(HibernateAuditDAO oldDAO)
|
public void setOldDAO(HibernateAuditDAO oldDAO)
|
||||||
{
|
{
|
||||||
@@ -271,4 +272,59 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId);
|
protected abstract AuditEntryEntity createAuditEntry(Long applicationId, long time, Long usernameId, Long valuesId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Searches
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that passes results from a result entity into the client callback
|
||||||
|
*/
|
||||||
|
protected class AuditQueryRowHandler
|
||||||
|
{
|
||||||
|
private final AuditQueryCallback callback;
|
||||||
|
private boolean more;
|
||||||
|
private AuditQueryRowHandler(AuditQueryCallback callback)
|
||||||
|
{
|
||||||
|
this.callback = callback;
|
||||||
|
this.more = true;
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void processResult(AuditQueryResult row)
|
||||||
|
{
|
||||||
|
if (!more)
|
||||||
|
{
|
||||||
|
// No more results required
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Get the value map
|
||||||
|
// TODO: Should be done with a nested resultmapping
|
||||||
|
Long auditValuesId = row.getAuditValuesId();
|
||||||
|
Pair<Long, Serializable> auditValuesPair = propertyValueDAO.getPropertyValueById(auditValuesId);
|
||||||
|
if (auditValuesPair == null)
|
||||||
|
{
|
||||||
|
// Ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String, Serializable> auditValues = (Map<String, Serializable>) auditValuesPair.getSecond();
|
||||||
|
more = callback.handleAuditEntry(
|
||||||
|
row.getAuditEntryId(),
|
||||||
|
row.getAuditAppName(),
|
||||||
|
row.getAuditUser(),
|
||||||
|
row.getAuditTime(),
|
||||||
|
auditValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findAuditEntries(
|
||||||
|
AuditQueryCallback callback,
|
||||||
|
String applicationName, String user, Long from, Long to, int maxResults)
|
||||||
|
{
|
||||||
|
AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback);
|
||||||
|
findAuditEntries(rowHandler, applicationName, user, from, to, maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void findAuditEntries(
|
||||||
|
AuditQueryRowHandler rowHandler,
|
||||||
|
String applicationName, String user, Long from, Long to, int maxResults);
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.alfresco.repo.audit.AuditState;
|
import org.alfresco.repo.audit.AuditState;
|
||||||
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.repository.ContentData;
|
import org.alfresco.service.cmr.repository.ContentData;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
@@ -93,4 +94,8 @@ public interface AuditDAO
|
|||||||
* @return Returns the unique entry ID
|
* @return Returns the unique entry ID
|
||||||
*/
|
*/
|
||||||
Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values);
|
Long createAuditEntry(Long applicationId, long time, String username, Map<String, Serializable> values);
|
||||||
|
|
||||||
|
void findAuditEntries(
|
||||||
|
AuditQueryCallback callback,
|
||||||
|
String applicationName, String user, Long from, Long to, int maxResults);
|
||||||
}
|
}
|
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.domain.audit;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query parameters for <b>alf_audit_entry</b> table.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public class AuditQueryParameters
|
||||||
|
{
|
||||||
|
private Long auditEntryId;
|
||||||
|
private Pair<String, Long> auditAppNameCrcPair;
|
||||||
|
private Pair<String, Long> auditUserCrcPair;
|
||||||
|
private Long auditFromTime;
|
||||||
|
private Long auditToTime;
|
||||||
|
|
||||||
|
public AuditQueryParameters()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder(512);
|
||||||
|
sb.append("AuditEntryParameters")
|
||||||
|
.append("[ auditEntryId=").append(auditEntryId)
|
||||||
|
.append(", auditAppNameCrcPair=").append(auditAppNameCrcPair)
|
||||||
|
.append(", auditUserCrcPair=").append(auditUserCrcPair)
|
||||||
|
.append(", auditFromTime").append(new Date(auditFromTime))
|
||||||
|
.append(", auditToTime").append(new Date(auditToTime))
|
||||||
|
.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditEntryId()
|
||||||
|
{
|
||||||
|
return auditEntryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditEntryId(Long entryId)
|
||||||
|
{
|
||||||
|
this.auditEntryId = entryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuditAppNameShort()
|
||||||
|
{
|
||||||
|
return auditAppNameCrcPair == null ? null : auditAppNameCrcPair.getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditAppNameCrc()
|
||||||
|
{
|
||||||
|
return auditAppNameCrcPair == null ? null : auditAppNameCrcPair.getSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditAppNameCrcPair(Pair<String, Long> appNameCrcPair)
|
||||||
|
{
|
||||||
|
this.auditAppNameCrcPair = appNameCrcPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuditUserShort()
|
||||||
|
{
|
||||||
|
return auditUserCrcPair == null ? null : auditUserCrcPair.getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditUserCrc()
|
||||||
|
{
|
||||||
|
return auditUserCrcPair == null ? null : auditUserCrcPair.getSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditUserCrcPair(Pair<String, Long> userCrcPair)
|
||||||
|
{
|
||||||
|
this.auditUserCrcPair = userCrcPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditFromTime()
|
||||||
|
{
|
||||||
|
return auditFromTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditFromTime(Long from)
|
||||||
|
{
|
||||||
|
this.auditFromTime = from;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditToTime()
|
||||||
|
{
|
||||||
|
return auditToTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditToTime(Long to)
|
||||||
|
{
|
||||||
|
this.auditToTime = to;
|
||||||
|
}
|
||||||
|
}
|
110
source/java/org/alfresco/repo/domain/audit/AuditQueryResult.java
Normal file
110
source/java/org/alfresco/repo/domain/audit/AuditQueryResult.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.domain.audit;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Results bean for <b>alf_audit_entry</b> table.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
public class AuditQueryResult
|
||||||
|
{
|
||||||
|
private Long auditEntryId;
|
||||||
|
private String auditAppName;
|
||||||
|
private String auditUser;
|
||||||
|
private long auditTime;
|
||||||
|
private Long auditValuesId;
|
||||||
|
|
||||||
|
public AuditQueryResult()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder(512);
|
||||||
|
sb.append("AuditEntryResult")
|
||||||
|
.append("[ auditEntryId=").append(auditEntryId)
|
||||||
|
.append(", auditAppName=").append(auditAppName)
|
||||||
|
.append(", auditUser=").append(auditUser)
|
||||||
|
.append(", auditTime").append(new Date(auditTime))
|
||||||
|
.append(", auditValuesId=").append(auditValuesId)
|
||||||
|
.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditEntryId()
|
||||||
|
{
|
||||||
|
return auditEntryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditEntryId(Long entryId)
|
||||||
|
{
|
||||||
|
this.auditEntryId = entryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuditAppName()
|
||||||
|
{
|
||||||
|
return auditAppName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditAppName(String appName)
|
||||||
|
{
|
||||||
|
this.auditAppName = appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuditUser()
|
||||||
|
{
|
||||||
|
return auditUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditUser(String user)
|
||||||
|
{
|
||||||
|
this.auditUser = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAuditTime()
|
||||||
|
{
|
||||||
|
return auditTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditTime(long time)
|
||||||
|
{
|
||||||
|
this.auditTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAuditValuesId()
|
||||||
|
{
|
||||||
|
return auditValuesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuditValuesId(Long auditValuesId)
|
||||||
|
{
|
||||||
|
this.auditValuesId = auditValuesId;
|
||||||
|
}
|
||||||
|
}
|
@@ -33,9 +33,13 @@ 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;
|
||||||
import org.alfresco.repo.domain.audit.AuditModelEntity;
|
import org.alfresco.repo.domain.audit.AuditModelEntity;
|
||||||
|
import org.alfresco.repo.domain.audit.AuditQueryParameters;
|
||||||
|
import org.alfresco.repo.domain.audit.AuditQueryResult;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||||
|
|
||||||
|
import com.ibatis.sqlmap.client.event.RowHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iBatis-specific implementation of the DAO for <b>alf_audit_XXX</b> tables.
|
* iBatis-specific implementation of the DAO for <b>alf_audit_XXX</b> tables.
|
||||||
*
|
*
|
||||||
@@ -52,6 +56,8 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
|
|||||||
|
|
||||||
private static final String INSERT_ENTRY = "insert.AuditEntry";
|
private static final String INSERT_ENTRY = "insert.AuditEntry";
|
||||||
|
|
||||||
|
private static final String SELECT_ENTRIES_SIMPLE = "select.AuditEntriesSimple";
|
||||||
|
|
||||||
private SqlMapClientTemplate template;
|
private SqlMapClientTemplate template;
|
||||||
|
|
||||||
public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate)
|
public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate)
|
||||||
@@ -142,4 +148,50 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
|
|||||||
entity.setId(id);
|
entity.setId(id);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
protected void findAuditEntries(
|
||||||
|
final AuditQueryRowHandler rowHandler,
|
||||||
|
String appName,
|
||||||
|
String user,
|
||||||
|
Long from,
|
||||||
|
Long to,
|
||||||
|
int maxResults)
|
||||||
|
{
|
||||||
|
AuditQueryParameters params = new AuditQueryParameters();
|
||||||
|
if (appName != null)
|
||||||
|
{
|
||||||
|
Pair<String, Long> appNameCrcPair = propertyValueDAO.getPropertyStringCaseSensitiveSearchParameters(appName);
|
||||||
|
params.setAuditAppNameCrcPair(appNameCrcPair);
|
||||||
|
}
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
Pair<String, Long> userCrcPair = propertyValueDAO.getPropertyStringCaseSensitiveSearchParameters(user);
|
||||||
|
params.setAuditUserCrcPair(userCrcPair);
|
||||||
|
}
|
||||||
|
params.setAuditFromTime(from);
|
||||||
|
params.setAuditToTime(to);
|
||||||
|
|
||||||
|
if (maxResults <= 0)
|
||||||
|
{
|
||||||
|
RowHandler rowHandlerInternal = new RowHandler()
|
||||||
|
{
|
||||||
|
public void handleRow(Object valueObject)
|
||||||
|
{
|
||||||
|
AuditQueryResult row = (AuditQueryResult) valueObject;
|
||||||
|
rowHandler.processResult(row);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template.queryWithRowHandler(SELECT_ENTRIES_SIMPLE, params, rowHandlerInternal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<AuditQueryResult> rows = template.queryForList(SELECT_ENTRIES_SIMPLE, params, 0, maxResults);
|
||||||
|
for (AuditQueryResult row : rows)
|
||||||
|
{
|
||||||
|
rowHandler.processResult(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -408,6 +408,11 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
|||||||
// 'alf_prop_string_value' accessors
|
// 'alf_prop_string_value' accessors
|
||||||
//================================
|
//================================
|
||||||
|
|
||||||
|
public Pair<String, Long> getPropertyStringCaseSensitiveSearchParameters(String value)
|
||||||
|
{
|
||||||
|
return CrcHelper.getStringCrcPair(value, 16, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
public Pair<Long, String> getPropertyStringValueById(Long id)
|
public Pair<Long, String> getPropertyStringValueById(Long id)
|
||||||
{
|
{
|
||||||
if (id == null)
|
if (id == null)
|
||||||
@@ -449,7 +454,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
|||||||
{
|
{
|
||||||
public Pair<String, Long> getValueKey(String value)
|
public Pair<String, Long> getValueKey(String value)
|
||||||
{
|
{
|
||||||
return CrcHelper.getStringCrcPair(value, 128, true, true);
|
return getPropertyStringCaseSensitiveSearchParameters(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Long, String> createValue(String value)
|
public Pair<Long, String> createValue(String value)
|
||||||
|
@@ -31,6 +31,8 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType;
|
import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType;
|
||||||
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.Period;
|
import org.alfresco.service.cmr.repository.Period;
|
||||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||||
@@ -60,6 +62,8 @@ public class DefaultPropertyTypeConverter implements PropertyTypeConverter
|
|||||||
mapClass.put(NodeRef.class, PersistedType.STRING);
|
mapClass.put(NodeRef.class, PersistedType.STRING);
|
||||||
mapClass.put(Period.class, PersistedType.STRING);
|
mapClass.put(Period.class, PersistedType.STRING);
|
||||||
mapClass.put(Locale.class, PersistedType.STRING);
|
mapClass.put(Locale.class, PersistedType.STRING);
|
||||||
|
mapClass.put(AssociationRef.class, PersistedType.STRING);
|
||||||
|
mapClass.put(ChildAssociationRef.class, PersistedType.STRING);
|
||||||
defaultPersistedTypesByClass = Collections.unmodifiableMap(mapClass);
|
defaultPersistedTypesByClass = Collections.unmodifiableMap(mapClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@ package org.alfresco.repo.domain.propval;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.alfresco.repo.domain.CrcHelper;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +85,11 @@ public interface PropertyValueDAO
|
|||||||
//================================
|
//================================
|
||||||
// 'alf_prop_string_value' accessors
|
// 'alf_prop_string_value' accessors
|
||||||
//================================
|
//================================
|
||||||
|
/**
|
||||||
|
* Utility method to get query parameters for case-sensitive string searching
|
||||||
|
* @see CrcHelper
|
||||||
|
*/
|
||||||
|
Pair<String, Long> getPropertyStringCaseSensitiveSearchParameters(String value);
|
||||||
/**
|
/**
|
||||||
* <b>alf_prop_string_value</b> accessor
|
* <b>alf_prop_string_value</b> accessor
|
||||||
*
|
*
|
||||||
|
@@ -114,50 +114,34 @@ public interface AuditService
|
|||||||
public static interface AuditQueryCallback
|
public static interface AuditQueryCallback
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Check if summary or full data fetching is required. Depending on the return value,
|
* Handle a row of audit entry data.
|
||||||
* the underlying query may be completely different; it is not possible to change the
|
|
||||||
* return value and expect the callback to be used differently during row handling.
|
|
||||||
*
|
|
||||||
* @return Return <tt>true</tt> if summary data is required only i.e
|
|
||||||
* the full map of audit values for the entries will not be
|
|
||||||
* retrieved.
|
|
||||||
*/
|
|
||||||
boolean isSummaryOnly();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a summary row of audit entry data. The ID of the full values map is provided.
|
|
||||||
*
|
|
||||||
* @param applicationName the name of the application
|
|
||||||
* @param user the user that logged the entry
|
|
||||||
* @param time the time of the entry
|
|
||||||
* @param valuesId the ID of the values map as created
|
|
||||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
|
||||||
*/
|
|
||||||
boolean handleAuditEntrySummary(String applicationName, String user, long time, Long valuesId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a full row of audit entry data.
|
|
||||||
*
|
*
|
||||||
|
* @param entryId the unique audit entry ID
|
||||||
* @param applicationName the name of the application
|
* @param applicationName the name of the application
|
||||||
* @param user the user that logged the entry
|
* @param user the user that logged the entry
|
||||||
* @param time the time of the entry
|
* @param time the time of the entry
|
||||||
* @param values the values map as created
|
* @param values the values map as created
|
||||||
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
* @return Return <tt>true</tt> to continue processing rows or <tt>false</tt> to stop
|
||||||
*/
|
*/
|
||||||
boolean handleAuditEntryFull(String applicationName, String user, long time, Map<String, Serializable> values);
|
boolean handleAuditEntry(
|
||||||
|
Long entryId,
|
||||||
|
String applicationName,
|
||||||
|
String user,
|
||||||
|
long time,
|
||||||
|
Map<String, Serializable> values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the audit entries that match the given criteria.
|
* Get the audit entries that match the given criteria.
|
||||||
*
|
*
|
||||||
* @param callback the callback that will handle results
|
* @param callback the callback that will handle results
|
||||||
* @param auditPath if not <tt>null</tt>, at least one value in the entry must start with this path
|
* @param applicationName if not <tt>null</tt>, find entries logged against this application
|
||||||
* @param user if not <tt>null</tt>, the entry must be logged against this user
|
* @param user if not <tt>null</tt>, find entries logged against this user
|
||||||
* @param from the start search time (use 0L) to cover all times
|
* @param from the start search time (<tt>null</tt> to start at the beginning)
|
||||||
* @param to the end search time (use Long.MAX_VALUE) to cover all times
|
* @param to the end search time (<tt>null</tt> for no limit)
|
||||||
* @param limit the maximum number of results to retrieve
|
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
||||||
*/
|
*/
|
||||||
void auditQuery(
|
void auditQuery(
|
||||||
AuditQueryCallback callback,
|
AuditQueryCallback callback,
|
||||||
String auditPath, String user, long from, long to, int limit);
|
String applicationName, String user, Long from, Long to, int maxResults);
|
||||||
}
|
}
|
||||||
|
@@ -31,13 +31,13 @@
|
|||||||
<AuditPath key="4.2">
|
<AuditPath key="4.2">
|
||||||
<RecordValue key="value.1" dataExtractor="simpleValue"/>
|
<RecordValue key="value.1" dataExtractor="simpleValue"/>
|
||||||
<RecordValue key="value.2" dataExtractor="simpleValue"/>
|
<RecordValue key="value.2" dataExtractor="simpleValue"/>
|
||||||
<GenerateValue key="value.3" dataGenerator="systemTime" scope="AUDIT"/>
|
<GenerateValue key="value.3" dataGenerator="systemTime"/>
|
||||||
</AuditPath>
|
</AuditPath>
|
||||||
</AuditPath>
|
</AuditPath>
|
||||||
<AuditPath key="3.2">
|
<AuditPath key="3.2">
|
||||||
<AuditPath key="4.1">
|
<AuditPath key="4.1">
|
||||||
<RecordValue key="value.1" dataExtractor="simpleValue"/>
|
<RecordValue key="value.1" dataExtractor="simpleValue"/>
|
||||||
<GenerateValue key="time" dataGenerator="systemTime" scope="AUDIT"/>
|
<GenerateValue key="time" dataGenerator="systemTime"/>
|
||||||
</AuditPath>
|
</AuditPath>
|
||||||
<AuditPath key="4.2">
|
<AuditPath key="4.2">
|
||||||
<RecordValue key="value.1" dataExtractor="simpleValue"/>
|
<RecordValue key="value.1" dataExtractor="simpleValue"/>
|
||||||
|
Reference in New Issue
Block a user