diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml index a42f26a4a1..f8ea71a6d3 100644 --- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml @@ -188,6 +188,12 @@ entry.audit_user_id = #auditUserId# + + = #auditFromId#]]> + + + + = #auditFromTime#]]> @@ -237,6 +243,12 @@ entry.audit_user_id = #auditUserId# + + = #auditFromId#]]> + + + + = #auditFromTime#]]> diff --git a/source/java/org/alfresco/repo/audit/AuditComponent.java b/source/java/org/alfresco/repo/audit/AuditComponent.java index 516913b3bc..b60fed19bc 100644 --- a/source/java/org/alfresco/repo/audit/AuditComponent.java +++ b/source/java/org/alfresco/repo/audit/AuditComponent.java @@ -32,6 +32,7 @@ import org.alfresco.repo.audit.model.AuditApplication; import org.alfresco.repo.audit.model.AuditModelRegistry; import org.alfresco.repo.audit.model._3.AuditPath; import org.alfresco.service.cmr.audit.AuditInfo; +import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.repository.NodeRef; import org.aopalliance.intercept.MethodInvocation; @@ -183,45 +184,13 @@ public interface AuditComponent Map recordAuditValues(String rootPath, Map values); /** - * Get the audit entries that match the given criteria. + * Find audit entries using the given parameters * - * @param callback the callback that will handle results - * @param forward true for results to ordered from first to last, - * or false to order from last to first - * @param applicationName if not null, find entries logged against this application - * @param user if not null, find entries logged against this user - * @param from the start search time (null to start at the beginning) - * @param to the end search time (null for no limit) + * @param callback the data callback per entry + * @param parameters the parameters for the query (may not be null) * @param maxResults the maximum number of results to retrieve (zero or negative to ignore) * * @since 3.2 */ - void auditQuery( - AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, - int maxResults); - - /** - * Get the audit entries that match the given criteria. - * - * @param callback the callback that will handle results - * @param forward true for results to ordered from first to last, - * or false to order from last to first - * @param applicationName if not null, find entries logged against this application - * @param user if not null, find entries logged against this user - * @param from the start search time (null to start at the beginning) - * @param to the end search time (null for no limit) - * @param searchKey the audit key path that must exist (null to ignore) - * @param searchValue an audit value that must exist (null to ignore) - * @param maxResults the maximum number of results to retrieve (zero or negative to ignore) - * - * @since 3.2 - */ - void auditQuery( - AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, - String searchKey, Serializable searchValue, - int maxResults); + void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults); } diff --git a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java index 919ed9c85a..f7b2db7fcb 100644 --- a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java +++ b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java @@ -54,6 +54,7 @@ import org.alfresco.service.Auditable; import org.alfresco.service.NotAuditable; import org.alfresco.service.PublicService; import org.alfresco.service.cmr.audit.AuditInfo; +import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; @@ -1321,51 +1322,17 @@ public class AuditComponentImpl implements AuditComponent /** * {@inheritDoc} */ - public void auditQuery( - AuditQueryCallback callback, - boolean forward, - String applicationName, - String user, - Long from, - Long to, - int maxResults) + public void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults) { ParameterCheck.mandatory("callback", callback); + ParameterCheck.mandatory("parameters", parameters); // Shortcuts - if (from != null && to != null && from.compareTo(to) > 0) + if (parameters.isZeroResultQuery()) { - // Time range can't yield results return; } - auditDAO.findAuditEntries( - callback, forward, applicationName, user, from, to, maxResults); - } - - /** - * {@inheritDoc} - */ - public void auditQuery( - AuditQueryCallback callback, - boolean forward, - String applicationName, - String user, - Long from, - Long to, - String searchKey, Serializable searchValue, - 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, forward, applicationName, user, from, to, searchKey, searchValue, maxResults); + auditDAO.findAuditEntries(callback, parameters, maxResults); } } diff --git a/source/java/org/alfresco/repo/audit/AuditComponentTest.java b/source/java/org/alfresco/repo/audit/AuditComponentTest.java index 8c26a3a002..0006a4ddf9 100644 --- a/source/java/org/alfresco/repo/audit/AuditComponentTest.java +++ b/source/java/org/alfresco/repo/audit/AuditComponentTest.java @@ -44,6 +44,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditService; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.repository.NodeRef; @@ -336,9 +337,13 @@ public class AuditComponentTest extends TestCase } }; + AuditQueryParameters params = new AuditQueryParameters(); + params.setForward(true); + params.setApplicationName(APPLICATION_ACTIONS_TEST); + sb.delete(0, sb.length()); rowCount.setValue(0); - auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, null, null, null, -1); + auditComponent.auditQuery(callback, params, -1); assertTrue("Expected some data", rowCount.intValue() > 0); logger.debug(sb.toString()); int allResults = rowCount.intValue(); @@ -346,21 +351,25 @@ public class AuditComponentTest extends TestCase // Limit by count sb.delete(0, sb.length()); rowCount.setValue(0); - auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, null, null, null, 1); + auditComponent.auditQuery(callback, params, 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, true, APPLICATION_ACTIONS_TEST, null, null, beforeTime, -1); + params.setToTime(beforeTime); + auditComponent.auditQuery(callback, params, -1); + params.setToTime(null); 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, true, APPLICATION_ACTIONS_TEST, null, beforeTime, null, -1); + params.setFromTime(beforeTime); + auditComponent.auditQuery(callback, params, -1); + params.setFromTime(null); logger.debug(sb.toString()); int resultsAfter = rowCount.intValue(); @@ -370,13 +379,17 @@ public class AuditComponentTest extends TestCase sb.delete(0, sb.length()); rowCount.setValue(0); - auditComponent.auditQuery(callback, true, APPLICATION_ACTIONS_TEST, user, null, null, -1); + params.setUser(user); + auditComponent.auditQuery(callback, params, -1); + params.setUser(null); 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, true, APPLICATION_ACTIONS_TEST, "Numpty", null, null, -1); + params.setUser("Numpty"); + auditComponent.auditQuery(callback, params, -1); + params.setUser(null); assertTrue("Expected no data for bogus user", rowCount.intValue() == 0); logger.debug(sb.toString()); @@ -454,6 +467,10 @@ public class AuditComponentTest extends TestCase public void testAuditAuthenticationService() throws Exception { + AuditQueryParameters params = new AuditQueryParameters(); + params.setForward(true); + params.setApplicationName(APPLICATION_API_TEST); + // Load in the config for this specific test: alfresco-audit-test-authenticationservice.xml URL testModelUrl = ResourceUtils.getURL("classpath:alfresco/audit/alfresco-audit-test-authenticationservice.xml"); auditModelRegistry.registerModel(testModelUrl); @@ -497,7 +514,7 @@ public class AuditComponentTest extends TestCase auditService.clearAudit(APPLICATION_API_TEST); results.clear(); sb.delete(0, sb.length()); - auditService.auditQuery(auditQueryCallback, true, APPLICATION_API_TEST, null, null, null, -1); + auditService.auditQuery(auditQueryCallback, params, -1); logger.debug(sb.toString()); assertTrue("There should be no audit entries for the API test after a clear", results.isEmpty()); @@ -531,7 +548,7 @@ public class AuditComponentTest extends TestCase // Check that the call was audited results.clear(); sb.delete(0, sb.length()); - auditService.auditQuery(auditQueryCallback, true, APPLICATION_API_TEST, null, null, null, -1); + auditService.auditQuery(auditQueryCallback, params, -1); logger.debug(sb.toString()); assertFalse("Did not get any audit results after successful login", results.isEmpty()); @@ -548,7 +565,7 @@ public class AuditComponentTest extends TestCase } results.clear(); sb.delete(0, sb.length()); - auditService.auditQuery(auditQueryCallback, true, APPLICATION_API_TEST, null, null, null, -1); + auditService.auditQuery(auditQueryCallback, params, -1); logger.debug(sb.toString()); assertFalse("Did not get any audit results after failed login", results.isEmpty()); } diff --git a/source/java/org/alfresco/repo/audit/AuditServiceImpl.java b/source/java/org/alfresco/repo/audit/AuditServiceImpl.java index 5f494dd4cf..9fc16ccb27 100644 --- a/source/java/org/alfresco/repo/audit/AuditServiceImpl.java +++ b/source/java/org/alfresco/repo/audit/AuditServiceImpl.java @@ -31,6 +31,7 @@ import javax.transaction.UserTransaction; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.audit.AuditInfo; +import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; @@ -167,6 +168,15 @@ public class AuditServiceImpl implements AuditService auditComponent.deleteAuditEntries(applicationName, null, now); } + /** + * {@inheritDoc} + * @since 3.3 + */ + public void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults) + { + auditComponent.auditQuery(callback, parameters, maxResults); + } + /** * {@inheritDoc} * @since 3.2 @@ -180,8 +190,14 @@ public class AuditServiceImpl implements AuditService { ParameterCheck.mandatory("callback", callback); - auditComponent.auditQuery( - callback, forward, applicationName, user, from, to, maxResults); + AuditQueryParameters params = new AuditQueryParameters(); + params.setForward(true); + params.setApplicationName(applicationName); + params.setUser(user); + params.setFromTime(from); + params.setToTime(to); + + auditComponent.auditQuery(callback, params, maxResults); } /** @@ -198,7 +214,17 @@ public class AuditServiceImpl implements AuditService { ParameterCheck.mandatory("callback", callback); - auditComponent.auditQuery( - callback, forward, applicationName, user, from, to, searchKey, searchValue, maxResults); + AuditQueryParameters params = new AuditQueryParameters(); + params.setForward(true); + params.setApplicationName(applicationName); + params.setUser(user); + params.setFromTime(from); + params.setToTime(to); + if (searchKey != null || searchValue != null) + { + params.addSearchKey(searchKey, searchValue); + } + + auditComponent.auditQuery(callback, params, maxResults); } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java index 2808904585..7cd37c09f8 100644 --- a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java +++ b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java @@ -29,49 +29,40 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.net.URL; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.audit.AuditComponentImpl; -import org.alfresco.repo.audit.AuditConfiguration; import org.alfresco.repo.audit.AuditState; -import org.alfresco.repo.content.ContentContext; import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.domain.audit.AuditDAO; -import org.alfresco.repo.domain.audit.AuditDAO.AuditApplicationInfo; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.TransactionalDao; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.audit.AuditInfo; +import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.datatype.Duration; -import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.EqualsHelper; import org.alfresco.util.GUID; import org.alfresco.util.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.mapping.Column; import org.springframework.orm.hibernate3.HibernateCallback; -import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.orm.hibernate3.LocalSessionFactoryBean; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; @@ -738,27 +729,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO, * @throws UnsupportedOperationException always * @since 3.2 */ - public void findAuditEntries( - AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, - int maxResults) - { - throw new UnsupportedOperationException(); - } - - /** - * Fallout implementation from new audit DAO - * - * @throws UnsupportedOperationException always - * @since 3.2 - */ - public void findAuditEntries( - AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, - String searchKey, Serializable searchValue, - int maxResults) + public void findAuditEntries(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults) { throw new UnsupportedOperationException(); } diff --git a/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java b/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java index 839a5699f5..bd52bbbebc 100644 --- a/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/audit/AbstractAuditDAOImpl.java @@ -442,28 +442,40 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO public void findAuditEntries( AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, + org.alfresco.service.cmr.audit.AuditQueryParameters parameters, int maxResults) { + String searchKey = null; + Serializable searchValue = null; + if (parameters.getSearchKeyValues().size() > 0) + { + // Only handle one pair for now + Pair searchKeyValue = parameters.getSearchKeyValues().get(0); + searchKey = searchKeyValue.getFirst(); + searchValue = searchKeyValue.getSecond(); + } + AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback); - findAuditEntries(rowHandler, forward, applicationName, user, from, to, maxResults, null, null); - } - - public void findAuditEntries( - AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, - String searchKey, Serializable searchValue, - int maxResults) - { - AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback); - findAuditEntries(rowHandler, forward, applicationName, user, from, to, maxResults, searchKey, searchValue); + findAuditEntries( + rowHandler, + parameters.isForward(), + parameters.getApplicationName(), + parameters.getUser(), + parameters.getFromId(), + parameters.getToId(), + parameters.getFromTime(), + parameters.getToTime(), + maxResults, + searchKey, + searchValue); } protected abstract void findAuditEntries( AuditQueryRowHandler rowHandler, boolean forward, - String applicationName, String user, Long from, Long to, int maxResults, + String applicationName, String user, + Long fromId, Long toId, + Long fromTime, Long toTime, + int maxResults, String searchKey, Serializable searchValue); } diff --git a/source/java/org/alfresco/repo/domain/audit/AuditDAO.java b/source/java/org/alfresco/repo/domain/audit/AuditDAO.java index 9f2e01b9e1..497e3152ef 100644 --- a/source/java/org/alfresco/repo/domain/audit/AuditDAO.java +++ b/source/java/org/alfresco/repo/domain/audit/AuditDAO.java @@ -207,34 +207,11 @@ public interface AuditDAO * Find audit entries using the given parameters, any of which may be null * * @param callback the data callback per entry - * @param forward true for results to ordered from first to last, - * or false to order from last to first - * @param applicationName the name of the application to search against (optional) - * @param user the user to search for (optional) - * @param from the minimum entry time (optional) - * @param to the maximum entry time (optional) + * @param parameters the parameters for the query (may not be null) * @param maxResults the maximum number of results to retrieve */ void findAuditEntries( AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, int maxResults); - - /** - * Find audit entries using the given parameters, any of which may be null. - * - * @param searchKey the audit path key to search for (optional) - * @param searchValue the audit value to search for (optional). This can be - * of any type that is supported by the alf_prop_xxx tables. - * - * @see #findAuditEntries(AuditQueryCallback, String, String, Long, Long, int) - * - * @since 3.2 - */ - void findAuditEntries( - AuditQueryCallback callback, - boolean forward, - String applicationName, String user, Long from, Long to, - String searchKey, Serializable searchValue, + org.alfresco.service.cmr.audit.AuditQueryParameters parameters, int maxResults); } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java b/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java index fd1d6b9007..e82b5414d8 100644 --- a/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java +++ b/source/java/org/alfresco/repo/domain/audit/AuditDAOTest.java @@ -40,6 +40,7 @@ import org.alfresco.repo.domain.contentdata.ContentDataDAO; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.audit.AuditQueryParameters; import org.alfresco.service.cmr.audit.AuditService.AuditQueryCallback; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.transaction.TransactionService; @@ -213,11 +214,14 @@ public class AuditDAOTest extends TestCase } }; + final AuditQueryParameters params = new AuditQueryParameters(); + params.addSearchKey("/a/b/c", null); + RetryingTransactionCallback findCallback = new RetryingTransactionCallback() { public Void execute() throws Throwable { - auditDAO.findAuditEntries(callback, true, null, null, null, null, "/a/b/c", null, 2); + auditDAO.findAuditEntries(callback, params, 2); return null; } }; @@ -240,7 +244,9 @@ public class AuditDAOTest extends TestCase { public Void execute() throws Throwable { - auditDAO.findAuditEntries(callback, false, null, null, null, null, "/a/b/c", null, 2); + params.setForward(false); + auditDAO.findAuditEntries(callback, params, 2); + params.setForward(true); return null; } }; @@ -276,6 +282,9 @@ public class AuditDAOTest extends TestCase // Some entries final String appName = doAuditEntryImpl(1); + + final AuditQueryParameters params = new AuditQueryParameters(); + params.setApplicationName(appName); // Delete the entries RetryingTransactionCallback deletedCallback = new RetryingTransactionCallback() { @@ -284,7 +293,7 @@ public class AuditDAOTest extends TestCase Long appId = auditDAO.getAuditApplication(appName).getId(); auditDAO.deleteAuditEntries(appId, null, null); // There should be no entries - auditDAO.findAuditEntries(noResultsCallback, true, appName, null, null, null, -1); + auditDAO.findAuditEntries(noResultsCallback, params, -1); return null; } }; diff --git a/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java b/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java index 1a6f5adbee..9024db45bd 100644 --- a/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java +++ b/source/java/org/alfresco/repo/domain/audit/AuditQueryParameters.java @@ -37,6 +37,8 @@ public class AuditQueryParameters private boolean forward; private Long auditAppNameId; private Long auditUserId; + private Long auditFromId; + private Long auditToId; private Long auditFromTime; private Long auditToTime; private Long searchKeyId; @@ -54,6 +56,8 @@ public class AuditQueryParameters .append("[ forward=").append(forward) .append(", auditAppNameId=").append(auditAppNameId) .append(", auditUserId=").append(auditUserId) + .append(", auditFromId=").append(auditFromId == null ? null : auditFromId) + .append(", auditToId=").append(auditToId == null ? null : auditToId) .append(", auditFromTime=").append(auditFromTime == null ? null : new Date(auditFromTime)) .append(", auditToTime=").append(auditToTime == null ? null : new Date(auditToTime)) .append(", searchKeyId=").append(searchKeyId) @@ -102,6 +106,26 @@ public class AuditQueryParameters return auditFromTime; } + public Long getAuditFromId() + { + return auditFromId; + } + + public void setAuditFromId(Long auditFromId) + { + this.auditFromId = auditFromId; + } + + public Long getAuditToId() + { + return auditToId; + } + + public void setAuditToId(Long auditToId) + { + this.auditToId = auditToId; + } + public void setAuditFromTime(Long from) { this.auditFromTime = from; diff --git a/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java b/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java index c64ebb19fc..42e9326f94 100644 --- a/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/audit/ibatis/AuditDAOImpl.java @@ -194,7 +194,10 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl protected void findAuditEntries( final AuditQueryRowHandler rowHandler, boolean forward, - String appName, String user, Long from, Long to, int maxResults, + String appName, String user, + Long fromId, Long toId, + Long fromTime, Long toTime, + int maxResults, String searchKey, Serializable searchValue) { AuditQueryParameters params = new AuditQueryParameters(); @@ -220,8 +223,10 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl } params.setAuditUserId(userPair.getFirst()); } - params.setAuditFromTime(from); - params.setAuditToTime(to); + params.setAuditFromId(fromId); + params.setAuditToId(toId); + params.setAuditFromTime(fromTime); + params.setAuditToTime(toTime); if (searchKey != null) { // Look up the ID of the search key diff --git a/source/java/org/alfresco/service/cmr/audit/AuditQueryParameters.java b/source/java/org/alfresco/service/cmr/audit/AuditQueryParameters.java new file mode 100644 index 0000000000..f4628f6754 --- /dev/null +++ b/source/java/org/alfresco/service/cmr/audit/AuditQueryParameters.java @@ -0,0 +1,224 @@ +/* + * 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.service.cmr.audit; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.alfresco.util.Pair; + +/** + * Parameters controlling audit queries. + * + * @author Derek Hulley + * @since 3.3 + */ +public class AuditQueryParameters +{ + private boolean forward; + private String applicationName; + private String user; + private Long fromId; + private Long toId; + private Long fromTime; + private Long toTime; + private List> searchKeyValues; + + /** + * Defaults:
+ *  forward = true;
+ *  searchKeyValues = emptylist
+ *  :others = null + */ + public AuditQueryParameters() + { + forward = true; + searchKeyValues = new ArrayList>(); + } + + /** + * @return Returns true if any query using these parameters will + * necessarily yield no results. + */ + public boolean isZeroResultQuery() + { + if (fromId != null && toId != null && fromId.compareTo(toId) > 0) + { + // Inverted IDs + return true; + } + if (fromTime != null && toTime != null && fromTime.compareTo(toTime) > 0) + { + // Inverted IDs + return true; + } + return false; + } + + /** + * @return Returns true if the results are ordered by increasing ID + */ + public boolean isForward() + { + return forward; + } + + /** + * @param forward true for results to ordered from first to last, + * or false to order from last to first + */ + public void setForward(boolean forward) + { + this.forward = forward; + } + + /** + * @return Returns if not null, find entries logged against this application + */ + public String getApplicationName() + { + return applicationName; + } + + /** + * @param applicationName if not null, find entries logged against this application + */ + public void setApplicationName(String applicationName) + { + this.applicationName = applicationName; + } + + /** + * @return Returns if not null, find entries logged against this user + */ + public String getUser() + { + return user; + } + + /** + * @param user if not null, find entries logged against this user + */ + public void setUser(String user) + { + this.user = user; + } + + /** + * @return Returns the ID to search from (null to start at the beginning) + */ + public Long getFromId() + { + return fromId; + } + + /** + * @param fromId the ID to search from (null to start at the beginning) + */ + public void setFromId(Long fromId) + { + this.fromId = fromId; + } + + /** + * @return Returns the ID to search to (null for no limit) + */ + public Long getToId() + { + return toId; + } + + /** + * @param toId the start ID to search to (null for no limit) + */ + public void setToId(Long toId) + { + this.toId = toId; + } + + /** + * @return Returns the start search time (null to start at the beginning) + */ + public Long getFromTime() + { + return fromTime; + } + + /** + * @param fromTime the start search time (null to start at the beginning) + */ + public void setFromTime(Long fromTime) + { + this.fromTime = fromTime; + } + + /** + * @return Returns the end search time (null for no limit) + */ + public Long getToTime() + { + return toTime; + } + + /** + * @param toTime the end search time (null for no limit) + */ + public void setToTime(Long toTime) + { + this.toTime = toTime; + } + + /** + * + * @return Returns the search keys for the query + */ + public List> getSearchKeyValues() + { + return Collections.unmodifiableList(searchKeyValues); + } + + /** + * Add a search key pair. + * + * @param searchKey the path-value pair. Either the path ({@link Pair#getFirst() first} value) + * or the search value ({@link Pair#getSecond() second} value) may be null, + * but not both. + */ + public void addSearchKey(String searchKey, Serializable searchValue) + { + if (searchKey == null && searchValue == null) + { + throw new IllegalArgumentException("A search key must have a 'searchKey' and/or a 'searchValue'."); + } + if (searchKeyValues.size() > 0) + { + throw new UnsupportedOperationException("Only one search key-value pair is currently supported."); + } + + this.searchKeyValues.add(new Pair(searchKey, searchValue)); + } +} diff --git a/source/java/org/alfresco/service/cmr/audit/AuditService.java b/source/java/org/alfresco/service/cmr/audit/AuditService.java index 037a397538..d83fa468db 100644 --- a/source/java/org/alfresco/service/cmr/audit/AuditService.java +++ b/source/java/org/alfresco/service/cmr/audit/AuditService.java @@ -180,6 +180,17 @@ public interface AuditService boolean handleAuditEntryError(Long entryId, String errorMsg, Throwable error); } + /** + * Issue an audit query using the given parameters and consuming results in the callback. + * + * @param callback the callback that will handle results + * @param parameters the parameters for the query (may not be null) + * @param maxResults the maximum number of results to retrieve (zero or negative to ignore) + * + * @since 3.3 + */ + void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults); + /** * Get the audit entries that match the given criteria. * @@ -193,6 +204,7 @@ public interface AuditService * @param maxResults the maximum number of results to retrieve (zero or negative to ignore) * * @since 3.2 + * @deprecated Use {@link #auditQuery(AuditQueryCallback, AuditQueryParameters)} */ void auditQuery( AuditQueryCallback callback, @@ -215,6 +227,7 @@ public interface AuditService * @param maxResults the maximum number of results to retrieve (zero or negative to ignore) * * @since 3.2 + * @deprecated Use {@link #auditQuery(AuditQueryCallback, AuditQueryParameters)} */ void auditQuery( AuditQueryCallback callback,