diff --git a/config/alfresco/application-context.xml b/config/alfresco/application-context.xml
index 6e9163edc6..c9e73e01af 100644
--- a/config/alfresco/application-context.xml
+++ b/config/alfresco/application-context.xml
@@ -25,6 +25,7 @@
+
diff --git a/config/alfresco/audit-services-context.xml b/config/alfresco/audit-services-context.xml
new file mode 100644
index 0000000000..96ab0a584e
--- /dev/null
+++ b/config/alfresco/audit-services-context.xml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ alfresco/auditConfig.xml
+
+
+
+
+
+
+
+ ${dir.auditcontentstore}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.repo.audit.AuditDAO
+
+
+
+
+
+
+
+
+
+ ${server.transaction.mode.default}, PROPAGATION_REQUIRES_NEW
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/auditConfig.xml b/config/alfresco/auditConfig.xml
index b3408ecb3d..f2e43fbb38 100644
--- a/config/alfresco/auditConfig.xml
+++ b/config/alfresco/auditConfig.xml
@@ -3,7 +3,7 @@
-
+
@@ -174,7 +174,7 @@
-
+
diff --git a/config/alfresco/auditSchema.xsd b/config/alfresco/auditSchema.xsd
index e76db97b11..3c5c74ae82 100644
--- a/config/alfresco/auditSchema.xsd
+++ b/config/alfresco/auditSchema.xsd
@@ -32,7 +32,9 @@
-
+
+
+
-
+
-
+
-
-
+
+
@@ -102,7 +104,7 @@
-
+
@@ -196,6 +198,7 @@
+
diff --git a/config/alfresco/ehcache-default.xml b/config/alfresco/ehcache-default.xml
index 570dc0076b..84eeb38518 100644
--- a/config/alfresco/ehcache-default.xml
+++ b/config/alfresco/ehcache-default.xml
@@ -124,4 +124,21 @@
name="org.alfresco.repo.domain.hibernate.DbAuthorityImpl.externalKeys"
maxElementsInMemory="5000"
/>
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/hibernate-context.xml b/config/alfresco/hibernate-context.xml
index a34fc56428..e2b0deff99 100644
--- a/config/alfresco/hibernate-context.xml
+++ b/config/alfresco/hibernate-context.xml
@@ -41,6 +41,10 @@
org/alfresco/repo/domain/hibernate/VersionCount.hbm.xml
org/alfresco/repo/domain/hibernate/AppliedPatch.hbm.xml
org/alfresco/repo/domain/hibernate/Permission.hbm.xml
+
+
+
+ org/alfresco/repo/audit/hibernate/Audit.hbm.xml
@@ -153,6 +157,10 @@
${cache.strategy}
${cache.strategy}
${cache.strategy}
+
+ ${cache.strategy}
+ ${cache.strategy}
+ ${cache.strategy}
@@ -201,16 +209,19 @@
+
+
+
org.alfresco.repo.node.db.NodeDaoService
@@ -225,4 +236,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml
index 2fe31c568d..d79b6bee73 100644
--- a/config/alfresco/public-services-context.xml
+++ b/config/alfresco/public-services-context.xml
@@ -2,85 +2,100 @@
-
-
+
+
-
- http://www.alfresco.org
-
+
+ http://www.alfresco.org
+
-
-
+
-
+
-
- org.alfresco.service.ServiceRegistry
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.ServiceRegistry
+
+
+
+
+
+
+
+
+
-
+
-
- org.alfresco.service.ServiceRegistry
-
-
- Repository service registry
-
+
+ org.alfresco.service.ServiceRegistry
+
+
+ Repository service registry
+
-
+
-
+
-
+
-
- org.alfresco.service.descriptor.DescriptorService
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.descriptor.DescriptorService
+
+
+
+
+
+
+
+
+
+
-
+
-
- org.alfresco.service.descriptor.DescriptorService
-
-
- Descriptor service
-
+
+ org.alfresco.service.descriptor.DescriptorService
+
+
+ Descriptor service
+
-
-
+
+
+
+
+
+
+
+
+ false
+
+
+
+
-
+
-
- org.alfresco.service.namespace.NamespaceService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.namespace.NamespaceService
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -93,39 +108,40 @@
-
+
-
- org.alfresco.service.namespace.NamespaceService
-
-
- Namespace service
-
+
+ org.alfresco.service.namespace.NamespaceService
+
+
+ Namespace service
+
-
-
+
-
-
-
-
+
+
+
-
+
-
- org.alfresco.service.cmr.dictionary.DictionaryService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.dictionary.DictionaryService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -136,34 +152,39 @@
-
+
-
- org.alfresco.service.cmr.dictionary.DictionaryService
-
-
- Dictionary Service
-
+
+ org.alfresco.service.cmr.dictionary.DictionaryService
+
+
+ Dictionary Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.repository.NodeService
-
-
-
-
-
-
-
-
-
-
+
+
+ org.alfresco.service.ServiceDescriptor
+ org.alfresco.service.cmr.repository.NodeService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -177,36 +198,36 @@
-
+
-
- org.alfresco.service.cmr.repository.NodeService
-
-
- Node Service
-
+
+ org.alfresco.service.cmr.repository.NodeService
+
+
+ Node Service
+
-
-
-
-
+
-
- org.alfresco.service.cmr.repository.ContentService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.repository.ContentService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -217,60 +238,64 @@
-
+
-
- org.alfresco.service.cmr.repository.ContentService
-
-
- Content Service
-
+
+ org.alfresco.service.cmr.repository.ContentService
+
+
+ Content Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.repository.MimetypeService
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.repository.MimetypeService
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
- org.alfresco.service.cmr.repository.MimetypeService
-
-
- Mime Type Service
-
+
+ org.alfresco.service.cmr.repository.MimetypeService
+
+
+ Mime Type Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.search.SearchService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.search.SearchService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -281,34 +306,36 @@
-
+
-
- org.alfresco.service.cmr.search.SearchService
-
-
- Search Service
-
+
+ org.alfresco.service.cmr.search.SearchService
+
+
+ Search Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.search.CategoryService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.search.CategoryService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -319,34 +346,36 @@
-
+
-
- org.alfresco.service.cmr.search.CategoryService
-
-
- Category Service
-
+
+ org.alfresco.service.cmr.search.CategoryService
+
+
+ Category Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.repository.CopyService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.repository.CopyService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -357,34 +386,36 @@
-
+
-
- org.alfresco.service.cmr.repository.CopyService
-
-
- Copy Service
-
+
+ org.alfresco.service.cmr.repository.CopyService
+
+
+ Copy Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.lock.LockService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.lock.LockService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -395,34 +426,36 @@
-
+
-
- org.alfresco.service.cmr.lock.LockService
-
-
- Lock Service
-
+
+ org.alfresco.service.cmr.lock.LockService
+
+
+ Lock Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.version.VersionService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.version.VersionService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -433,34 +466,36 @@
-
+
-
- org.alfresco.service.cmr.version.VersionService
-
-
- Version Service
-
+
+ org.alfresco.service.cmr.version.VersionService
+
+
+ Version Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.coci.CheckOutCheckInService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.coci.CheckOutCheckInService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -471,34 +506,36 @@
-
+
-
- org.alfresco.service.cmr.coci.CheckOutCheckInService
-
-
- Version Service
-
+
+ org.alfresco.service.cmr.coci.CheckOutCheckInService
+
+
+ Version Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.rule.RuleService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.rule.RuleService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -509,34 +546,36 @@
-
+
-
- org.alfresco.service.cmr.rule.RuleService
-
-
- Rule Service
-
+
+ org.alfresco.service.cmr.rule.RuleService
+
+
+ Rule Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.view.ImporterService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.view.ImporterService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -547,32 +586,34 @@
-
+
-
- org.alfresco.service.cmr.view.ImporterService
-
-
- Importer Service
-
+
+ org.alfresco.service.cmr.view.ImporterService
+
+
+ Importer Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.view.ExporterService
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.view.ExporterService
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -583,34 +624,36 @@
-
+
-
- org.alfresco.service.cmr.view.ExporterService
-
-
- Exporter Service
-
+
+ org.alfresco.service.cmr.view.ExporterService
+
+
+ Exporter Service
+
-
-
+
-
+
-
- org.alfresco.service.cmr.action.ActionService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.action.ActionService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -623,32 +666,34 @@
-
- org.alfresco.service.cmr.action.ActionService
-
-
- Action Service
-
+
+ org.alfresco.service.cmr.action.ActionService
+
+
+ Action Service
+
-
-
+
-
- org.alfresco.service.cmr.security.PermissionService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.security.PermissionService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -661,32 +706,34 @@
-
- org.alfresco.service.cmr.security.PermissionService
-
-
- Permission Service
-
+
+ org.alfresco.service.cmr.security.PermissionService
+
+
+ Permission Service
+
-
-
- org.alfresco.service.cmr.security.AuthorityService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.security.AuthorityService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -699,32 +746,34 @@
-
- org.alfresco.service.cmr.security.AuthorityService
-
-
- Authority Service
-
+
+ org.alfresco.service.cmr.security.AuthorityService
+
+
+ Authority Service
+
-
-
- org.alfresco.service.cmr.security.OwnableService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.security.OwnableService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -737,32 +786,34 @@
-
- org.alfresco.service.cmr.security.OwnableService
-
-
- OwnableService Service
-
+
+ org.alfresco.service.cmr.security.OwnableService
+
+
+ OwnableService Service
+
-
-
- org.alfresco.service.cmr.security.PersonService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.security.PersonService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -775,32 +826,34 @@
-
- org.alfresco.service.cmr.security.PersonService
-
-
- PersonService Service
-
+
+ org.alfresco.service.cmr.security.PersonService
+
+
+ PersonService Service
+
-
-
- org.alfresco.service.cmr.security.AuthenticationService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.security.AuthenticationService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -819,32 +872,34 @@
-
- org.alfresco.service.cmr.security.AuthenticationService
-
-
- AuthenticationService Service
-
+
+ org.alfresco.service.cmr.security.AuthenticationService
+
+
+ AuthenticationService Service
+
-
-
- org.alfresco.service.cmr.repository.TemplateService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.repository.TemplateService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -857,32 +912,34 @@
-
- org.alfresco.service.cmr.repository.TemplateService
-
-
- TemplateService Service
-
+
+ org.alfresco.service.cmr.repository.TemplateService
+
+
+ TemplateService Service
+
-
-
- org.alfresco.service.cmr.repository.ScriptService
-
-
-
-
-
-
-
-
-
-
+
+ org.alfresco.service.cmr.repository.ScriptService
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -895,31 +952,34 @@
-
- org.alfresco.service.cmr.repository.ScriptService
-
-
- ScriptService Service
-
+
+ org.alfresco.service.cmr.repository.ScriptService
+
+
+ ScriptService Service
+
-
-
- org.alfresco.service.cmr.model.FileFolderService
-
-
-
+
+ org.alfresco.service.cmr.model.FileFolderService
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
@@ -934,23 +994,36 @@
-
-
-
-
-
-
- org.alfresco.service.cmr.workflow.WorkflowService
-
-
-
-
-
-
-
-
+
+
+
+ org.alfresco.service.cmr.model.FileFolderService
+
+
+ FileFolderService Service
+
-
+
+
+
+
+
+ org.alfresco.service.cmr.workflow.WorkflowService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -961,14 +1034,55 @@
-
+
-
- org.alfresco.service.cmr.workflow.WorkflowService
-
-
- Workflow Service
-
+
+ org.alfresco.service.cmr.workflow.WorkflowService
+
+
+ Workflow Service
+
+
+
+
+
+
+
+
+ org.alfresco.service.cmr.audit.AuditService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${server.transaction.mode.default}
+
+
+
+
+
+
+ org.alfresco.service.cmr.audit.AuditService
+
+
+ Audit Service
+
diff --git a/config/alfresco/public-services-security-context.xml b/config/alfresco/public-services-security-context.xml
index bbe50d57eb..fcf2b92d31 100644
--- a/config/alfresco/public-services-security-context.xml
+++ b/config/alfresco/public-services-security-context.xml
@@ -712,4 +712,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index 221f37747f..f4d4c7020f 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -5,6 +5,8 @@ dir.root=./alf_data
dir.contentstore=${dir.root}/contentstore
dir.contentstore.deleted=${dir.root}/contentstore.deleted
+dir.auditcontentstore=${dir.root}/audit.contentstore
+
# The location for lucene index files
dir.indexes=${dir.root}/lucene-indexes
diff --git a/source/java/org/alfresco/repo/audit/ApplicationAuditModel.java b/source/java/org/alfresco/repo/audit/ApplicationAuditModel.java
new file mode 100644
index 0000000000..496873c201
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/ApplicationAuditModel.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+
+public interface ApplicationAuditModel
+{
+ /**
+ * Report if audit behaviour can be determined before the method call
+ *
+ * @param auditState,
+ * @param mi
+ * @return
+ */
+ public AuditMode beforeExecution(AuditMode auditMode, String application, String description,
+ NodeRef key, Object... args);
+
+ /**
+ * Report if audit behaviour can be determined after the method call
+ *
+ * @param auditState,
+ * @param mi
+ * @return
+ */
+ public AuditMode afterExecution(AuditMode auditMode, String application, String description,
+ NodeRef key, Object... args);
+
+ /**
+ * Report if audit behaviour should be invoked on error. It could be we look at the error and filter - this is not supported at the moment.
+ *
+ * @param auditState,
+ * @param mi
+ * @return
+ */
+ public AuditMode onError(AuditMode auditMode, String application, String description,
+ NodeRef key, Object... args);
+
+ /**
+ * Get the optional parameters that are to be recorded
+ *
+ * @param mi
+ * @return
+ */
+ public RecordOptions getAuditRecordOptions(String application);
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditComponent.java b/source/java/org/alfresco/repo/audit/AuditComponent.java
new file mode 100644
index 0000000000..3b13c7e5f5
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditComponent.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * The audit component.
+ *
+ * Used by the AuditService and AuditMethodInterceptor to insert audit entries.
+ *
+ * @author Andy Hind
+ */
+public interface AuditComponent
+{
+ /**
+ * Audit entry point for method interceptors.
+ *
+ * @param methodInvocation
+ */
+ public Object audit(MethodInvocation methodInvocation) throws Throwable;
+
+ /**
+ *
+ * @param source -
+ * a string that represents the application
+ * @param description -
+ * the audit entry *
+ * @param key -
+ * a node ref to use as the key for filtering etc
+ * @param args -
+ * an arbitrary list of parameters
+ */
+ public void audit(String source, String description, NodeRef key, Object... args);
+
+
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditComponentImpl.java b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java
new file mode 100644
index 0000000000..e476907417
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditComponentImpl.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Date;
+
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
+import org.alfresco.service.Auditable;
+import org.alfresco.service.NotAuditable;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The default audit component implementation. TODO: Implement before, after and exception filtering. At the moment these filters are ignired. TODO: Respect audit internal - at the
+ * moment audit internal is fixed to false.
+ *
+ * @author Andy Hind
+ */
+public class AuditComponentImpl implements AuditComponent
+{
+ /**
+ * The application name to use for audit entries generated by method interception around public services.
+ */
+ private static final String SYSTEM_APPLICATION = "SystemMethodInterceptor";
+
+ /**
+ * Logging
+ */
+ private static Log s_logger = LogFactory.getLog(AuditComponentImpl.class);
+
+ /**
+ * Suspend resume auditing
+ */
+ private static ThreadLocal auditFlag = new ThreadLocal();
+
+ /**
+ * IOC
+ */
+ private PublicServiceIdentifier publicServiceIdentifier;
+
+ private AuditConfiguration auditConfiguration;
+
+ private AuditDAO auditDAO;
+
+ private AuditDAO auditFailedDAO;
+
+ private AuditModel auditModel;
+
+ /**
+ * Keep hold of the host where the audit occurs. TODO: Check that we get the correct address ...
+ */
+
+ private InetAddress auditHost;
+
+ public AuditComponentImpl()
+ {
+ super();
+ // Initialise the host address
+ try
+ {
+ auditHost = InetAddress.getLocalHost();
+ }
+ catch (UnknownHostException e)
+ {
+ s_logger.error("Failed to get local host address", e);
+ }
+ }
+
+ /*
+ * IOC property setters
+ */
+
+ public void setAuditDAO(AuditDAO auditDAO)
+ {
+ this.auditDAO = auditDAO;
+ }
+
+ public void setAuditFailedDAO(AuditDAO auditFailedDAO)
+ {
+ this.auditFailedDAO = auditFailedDAO;
+ }
+
+ public void setAuditConfiguration(AuditConfiguration auditConfiguration)
+ {
+ this.auditConfiguration = auditConfiguration;
+ }
+
+ public void setPublicServiceIdentifier(PublicServiceIdentifier publicServiceIdentifier)
+ {
+ this.publicServiceIdentifier = publicServiceIdentifier;
+ }
+
+ public void setAuditModel(AuditModel auditModel)
+ {
+ this.auditModel = auditModel;
+ }
+
+ public Object audit(MethodInvocation mi) throws Throwable
+ {
+ if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue()))
+ {
+ try
+ {
+ auditFlag.set(Boolean.TRUE);
+
+ Method method = mi.getMethod();
+ String methodName = method.getName();
+ String serviceName = publicServiceIdentifier.getPublicServiceName(mi);
+ if (method.isAnnotationPresent(Auditable.class))
+ {
+
+ if (serviceName != null)
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Auditing - " + serviceName + "." + methodName);
+ }
+ return auditImpl(mi);
+ }
+ else
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("UnknownService." + methodName);
+ }
+ return auditImpl(mi);
+ }
+
+ }
+ else if (method.isAnnotationPresent(NotAuditable.class))
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Not Audited. " + serviceName + "." + methodName);
+ }
+ return mi.proceed();
+ }
+ else
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Unannotated service method " + serviceName + "." + methodName);
+ }
+ throw new RuntimeException("Unannotated service method " + serviceName + "." + methodName);
+ }
+ }
+ finally
+ {
+ auditFlag.set(Boolean.FALSE);
+ }
+ }
+ else
+ {
+ return mi.proceed();
+ }
+ }
+
+ /**
+ * Audit a method invocation
+ */
+ public Object auditImpl(MethodInvocation mi) throws Throwable
+ {
+ AuditInfo auditInfo = new AuditInfo(auditConfiguration);
+ // RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
+ AuditMode auditMode = AuditMode.UNSET;
+ try
+ {
+ auditMode = beforeInvocation(auditMode, auditInfo, mi);
+ Object o = mi.proceed();
+ auditMode = postInvocation(auditMode, auditInfo, mi, o);
+ if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS))
+ {
+ auditDAO.audit(auditInfo);
+ }
+ return o;
+ }
+ catch (Throwable t)
+ {
+ auditMode = onError(auditMode, auditInfo, mi, t);
+ if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL))
+ {
+ try
+ {
+ auditFailedDAO.audit(auditInfo);
+ }
+ catch (Throwable tt)
+ {
+ throw new AuditException("Failed to audit exception", new Object[] { tt }, t);
+ }
+ }
+ throw t;
+ }
+ }
+
+ /**
+ * Helper method to set auditable properties and to determine if auditing is required when an exception is caught in the audited method.
+ *
+ * @param auditMode
+ * @param auditInfo
+ * @param t
+ * @return
+ */
+ private AuditMode onError(AuditMode auditMode, AuditInfo auditInfo, MethodInvocation mi, Throwable t)
+ {
+ if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL))
+ {
+ auditInfo.setFail(true);
+ auditInfo.setThrowable(t);
+ }
+
+ return auditMode;
+ }
+
+ /**
+ * Helper method to set audited information after method invocation and to determine if auditing should take place based on the method return value.
+ *
+ * @param auditMode
+ * @param auditInfo
+ * @param mi
+ * @param returnObject
+ * @return
+ */
+ private AuditMode postInvocation(AuditMode auditMode, AuditInfo auditInfo, MethodInvocation mi, Object returnObject)
+ {
+ if (returnObject == null)
+ {
+ auditInfo.setReturnObject(null);
+ }
+ else if (returnObject instanceof Serializable)
+ {
+ auditInfo.setReturnObject((Serializable) returnObject);
+ }
+ else
+ {
+ auditInfo.setReturnObject(returnObject.toString());
+ }
+ return auditMode;
+ }
+
+ /**
+ * Set auditable information and determine if auditing is required before method invocation. This would normally be based on the method arguments.
+ *
+ * @param auditMode
+ * @param auditInfo
+ * @param mi
+ * @return
+ */
+ private AuditMode beforeInvocation(AuditMode auditMode, AuditInfo auditInfo, MethodInvocation mi)
+ {
+ AuditMode effectiveAuditMode = auditModel.beforeExecution(auditMode, mi);
+
+ if (auditMode != AuditMode.NONE)
+ {
+ String methodName = mi.getMethod().getName();
+ String serviceName = publicServiceIdentifier.getPublicServiceName(mi);
+ auditInfo.setAuditApplication(SYSTEM_APPLICATION);
+ auditInfo.setAuditConfiguration(auditConfiguration);
+ auditInfo.setAuditMethod(methodName);
+ auditInfo.setAuditService(serviceName);
+ auditInfo.setClientAddress(null);
+ auditInfo.setDate(new Date());
+ auditInfo.setFail(false);
+ auditInfo.setFiltered(false);
+ auditInfo.setHostAddress(auditHost);
+ auditInfo.setKeyGUID(null);
+ auditInfo.setKeyPropertiesAfter(null);
+ auditInfo.setKeyPropertiesBefore(null);
+ auditInfo.setKeyStore(null);
+ auditInfo.setMessage(null);
+ if (mi.getArguments() != null)
+ {
+ Serializable[] serArgs = new Serializable[mi.getArguments().length];
+ for (int i = 0; i < mi.getArguments().length; i++)
+ {
+ if (mi.getArguments()[i] == null)
+ {
+ serArgs[i] = null;
+ }
+ else if (mi.getArguments()[i] instanceof Serializable)
+ {
+ serArgs[i] = (Serializable) mi.getArguments()[i];
+ }
+ else
+ {
+ serArgs[i] = mi.getArguments()[i].toString();
+ }
+ }
+ auditInfo.setMethodArguments(serArgs);
+ }
+ auditInfo.setPath(null);
+ auditInfo.setReturnObject(null);
+ auditInfo.setSessionId(null);
+ auditInfo.setThrowable(null);
+ auditInfo.setTxId(AlfrescoTransactionSupport.getTransactionId());
+ auditInfo.setUserIdentifier(AuthenticationUtil.getCurrentUserName());
+ }
+
+ return effectiveAuditMode;
+ }
+
+ /**
+ * A simple audit entry Currently we ignore filtering here.
+ */
+ public void audit(String source, String description, NodeRef key, Object... args)
+ {
+ AuditInfo auditInfo = new AuditInfo(auditConfiguration);
+ // RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
+ AuditMode auditMode = AuditMode.UNSET;
+ try
+ {
+ auditMode = onApplicationAudit(auditMode, auditInfo, source, description, key, args);
+ if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS))
+ {
+ auditDAO.audit(auditInfo);
+ }
+ }
+ catch (Throwable t)
+ {
+ auditMode = onError(auditMode, auditInfo, t, source, description, key, args);
+ if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL))
+ {
+ try
+ {
+ auditFailedDAO.audit(auditInfo);
+ }
+ catch (Throwable tt)
+ {
+ throw new AuditException("Failed to audit exception", new Object[] { tt }, t);
+ }
+ }
+ throw new AuditException("Application audit failed", t);
+ }
+ }
+
+ private AuditMode onApplicationAudit(AuditMode auditMode, AuditInfo auditInfo, String source, String description,
+ NodeRef key, Object... args)
+ {
+ AuditMode effectiveAuditMode = auditModel.beforeExecution(auditMode, source, description, key, args);
+
+ if (auditMode != AuditMode.NONE)
+ {
+ if(source.equals(SYSTEM_APPLICATION))
+ {
+ throw new AuditException("Application audit can not use the reserved identifier "+SYSTEM_APPLICATION);
+ }
+
+ auditInfo.setAuditApplication(source);
+ auditInfo.setAuditConfiguration(auditConfiguration);
+ auditInfo.setAuditMethod(null);
+ auditInfo.setAuditService(null);
+ auditInfo.setClientAddress(null);
+ auditInfo.setDate(new Date());
+ auditInfo.setFail(false);
+ auditInfo.setFiltered(false);
+ auditInfo.setHostAddress(auditHost);
+ auditInfo.setKeyGUID(null);
+ auditInfo.setKeyPropertiesAfter(null);
+ auditInfo.setKeyPropertiesBefore(null);
+ auditInfo.setKeyStore(null);
+ auditInfo.setMessage(description);
+ if (args != null)
+ {
+ Serializable[] serArgs = new Serializable[args.length];
+ for (int i = 0; i < args.length; i++)
+ {
+ if (args[i] == null)
+ {
+ serArgs[i] = null;
+ }
+ else if (args[i] instanceof Serializable)
+ {
+ serArgs[i] = (Serializable) args[i];
+ }
+ else
+ {
+ serArgs[i] = args[i].toString();
+ }
+ }
+ auditInfo.setMethodArguments(serArgs);
+ }
+ auditInfo.setPath(null);
+ auditInfo.setReturnObject(null);
+ auditInfo.setSessionId(null);
+ auditInfo.setThrowable(null);
+ auditInfo.setTxId(AlfrescoTransactionSupport.getTransactionId());
+ auditInfo.setUserIdentifier(AuthenticationUtil.getCurrentUserName());
+ }
+
+ return effectiveAuditMode;
+ }
+
+ private AuditMode onError(AuditMode auditMode, AuditInfo auditInfo, Throwable t, String source, String description,
+ NodeRef key, Object... args)
+ {
+ if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.FAIL))
+ {
+ auditInfo.setFail(true);
+ auditInfo.setThrowable(t);
+ }
+
+ return auditMode;
+
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditConfiguration.java b/source/java/org/alfresco/repo/audit/AuditConfiguration.java
new file mode 100644
index 0000000000..66aba55205
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditConfiguration.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import java.io.InputStream;
+
+/**
+ * An audit configuration is xml content from an input stream.
+ *
+ * @author Andy Hind
+ */
+public interface AuditConfiguration
+{
+
+ /**
+ * Get the XML content for the configuration as a stream.
+ *
+ * @return
+ */
+ public abstract InputStream getInputStream();
+
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/AuditConfigurationImpl.java b/source/java/org/alfresco/repo/audit/AuditConfigurationImpl.java
new file mode 100644
index 0000000000..1b41dfd699
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditConfigurationImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import java.io.InputStream;
+
+import org.springframework.beans.factory.InitializingBean;
+
+/**
+ * A class to read the audit configuration from the class path
+ *
+ * @author Andy Hind
+ */
+public class AuditConfigurationImpl implements InitializingBean, AuditConfiguration
+{
+
+ private String config;
+
+ public AuditConfigurationImpl()
+ {
+ super();
+ }
+
+ public void setConfig(String config)
+ {
+ this.config = config;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.getInputStream#getInputStream()
+ */
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.AuditConfiguration#getInputStream()
+ */
+ public InputStream getInputStream()
+ {
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream(config);
+ return is;
+ }
+
+ public void afterPropertiesSet() throws Exception
+ {
+ // Read and set up the audit configuration
+
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditDAO.java b/source/java/org/alfresco/repo/audit/AuditDAO.java
new file mode 100644
index 0000000000..ef307c5f93
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditDAO.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+/**
+ * The interface to persist audit information.
+ *
+ * @author Andy Hind
+ */
+public interface AuditDAO
+{
+ /**
+ * Create an audit entry.
+ *
+ * @param auditInfo
+ */
+ public void audit(AuditInfo auditInfo);
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditException.java b/source/java/org/alfresco/repo/audit/AuditException.java
new file mode 100644
index 0000000000..c76cac4e55
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+
+/**
+ * Audit related exceptions.
+ *
+ * @author Andy Hind
+ */
+public class AuditException extends AlfrescoRuntimeException
+{
+
+ /**
+ * Comment for serialVersionUID
+ */
+ private static final long serialVersionUID = -7947190775692164588L;
+
+ public AuditException(String msgId)
+ {
+ super(msgId);
+ }
+
+ public AuditException(String msgId, Object[] msgParams)
+ {
+ super(msgId, msgParams);
+ }
+
+ public AuditException(String msgId, Throwable cause)
+ {
+ super(msgId, cause);
+ }
+
+ public AuditException(String msgId, Object[] msgParams, Throwable cause)
+ {
+ super(msgId, msgParams, cause);
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditInfo.java b/source/java/org/alfresco/repo/audit/AuditInfo.java
new file mode 100644
index 0000000000..f62e57a92c
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditInfo.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Date;
+import java.util.Map;
+
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.namespace.QName;
+import org.apache.log4j.Logger;
+
+/**
+ * A class to encapsulate audit information supplied to the DAO layer.
+ *
+ * Null entries should be stored.
+ *
+ * @author Andy Hind
+ */
+public class AuditInfo
+{
+ private static Logger s_logger = Logger.getLogger(AuditInfo.class);
+
+ /**
+ * The user identifier for the person who caused this audit entry
+ */
+ private String userIdentifier;
+
+ /**
+ * The date for this audit entry
+ */
+ private Date date;
+
+ /**
+ * The transaction id in which this entry was made
+ */
+ private String txId;
+
+ /**
+ * The session is for this action
+ */
+ private String sessionId;
+
+ /**
+ * The store in which the action occured.
+ */
+ private StoreRef keyStore;
+
+ /**
+ * For a node ref, the node for the action.
+ */
+ private String keyGUID;
+
+ /**
+ * The path of the key
+ */
+ private String keyPath;
+
+ /**
+ * The audit application
+ * Internal uses the "System" key and will only audit method information.
+ */
+ private String auditApplication;
+
+ /**
+ * The service holding the audited method.
+ */
+ private String auditService;
+
+ /**
+ * The name of the audited method.
+ */
+ private String auditMethod;
+
+ /**
+ * Did this entry passa filter?
+ * If false - all entries were being recorded.
+ */
+ private boolean filtered;
+
+ /**
+ * The audit configuration in use at the time.
+ */
+ private AuditConfiguration auditConfiguration;
+
+ /**
+ * The object returned by the audited method.
+ */
+ private Serializable returnObject;
+
+ /**
+ * The arguments to the audited method.
+ */
+ private Serializable[] methodArguments;
+
+ /**
+ * Any Exception thrown by the audited method.
+ */
+ private Throwable throwable;
+
+ /**
+ * Did the audited method throw an exception?
+ */
+ private boolean fail;
+
+ /**
+ * The host address for where the audit was generated.
+ */
+ private InetAddress hostAddress;
+
+ private static InetAddress s_hostAddress;
+
+ /**
+ * The client address causing the audit
+ */
+ private InetAddress clientAddress;
+
+ /**
+ * The properties of the key node before the method execution.
+ */
+ private Map keyPropertiesBefore;
+
+ /**
+ * The properties of the key node after the method execution.
+ */
+ private Map keyPropertiesAfter;
+
+ /**
+ * For general auditing - the audit message.
+ */
+ private String message;
+
+ static
+ {
+ try
+ {
+ s_hostAddress = InetAddress.getLocalHost();
+ }
+ catch (UnknownHostException e)
+ {
+ s_logger.error(e);
+ s_hostAddress = null;
+ }
+ }
+
+ public AuditInfo(AuditConfiguration auditConfiguration)
+ {
+ super();
+ // Add default information
+ userIdentifier = AuthenticationUtil.getCurrentUserName();
+ date = new Date();
+ txId = AlfrescoTransactionSupport.getTransactionId();
+ sessionId = "Unavailable";
+ hostAddress = s_hostAddress;
+ }
+
+ public String getAuditApplication()
+ {
+ return auditApplication;
+ }
+
+ public void setAuditApplication(String auditApplication)
+ {
+ this.auditApplication = auditApplication;
+ }
+
+ public AuditConfiguration getAuditConfiguration()
+ {
+ return auditConfiguration;
+ }
+
+ public void setAuditConfiguration(AuditConfiguration auditConfiguration)
+ {
+ this.auditConfiguration = auditConfiguration;
+ }
+
+ public String getAuditMethod()
+ {
+ return auditMethod;
+ }
+
+ public void setAuditMethod(String auditMethod)
+ {
+ this.auditMethod = auditMethod;
+ }
+
+ public String getAuditService()
+ {
+ return auditService;
+ }
+
+ public void setAuditService(String auditService)
+ {
+ this.auditService = auditService;
+ }
+
+ public InetAddress getClientAddress()
+ {
+ return clientAddress;
+ }
+
+ public void setClientAddress(InetAddress clientAddress)
+ {
+ this.clientAddress = clientAddress;
+ }
+
+ public Date getDate()
+ {
+ return date;
+ }
+
+ public void setDate(Date date)
+ {
+ this.date = date;
+ }
+
+ public boolean isFail()
+ {
+ return fail;
+ }
+
+ public void setFail(boolean fail)
+ {
+ this.fail = fail;
+ }
+
+ public boolean isFiltered()
+ {
+ return filtered;
+ }
+
+ public void setFiltered(boolean filtered)
+ {
+ this.filtered = filtered;
+ }
+
+ public InetAddress getHostAddress()
+ {
+ return hostAddress;
+ }
+
+ public void setHostAddress(InetAddress hostAddress)
+ {
+ this.hostAddress = hostAddress;
+ }
+
+ public String getKeyGUID()
+ {
+ return keyGUID;
+ }
+
+ public void setKeyGUID(String keyGUID)
+ {
+ this.keyGUID = keyGUID;
+ }
+
+ public Map getKeyPropertiesAfter()
+ {
+ return keyPropertiesAfter;
+ }
+
+ public void setKeyPropertiesAfter(Map keyPropertiesAfter)
+ {
+ this.keyPropertiesAfter = keyPropertiesAfter;
+ }
+
+ public Map getKeyPropertiesBefore()
+ {
+ return keyPropertiesBefore;
+ }
+
+ public void setKeyPropertiesBefore(Map keyPropertiesBefore)
+ {
+ this.keyPropertiesBefore = keyPropertiesBefore;
+ }
+
+ public StoreRef getKeyStore()
+ {
+ return keyStore;
+ }
+
+ public void setKeyStore(StoreRef keyStore)
+ {
+ this.keyStore = keyStore;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public void setMessage(String message)
+ {
+ this.message = message;
+ }
+
+ public Serializable[] getMethodArguments()
+ {
+ return methodArguments;
+ }
+
+ public void setMethodArguments(Serializable[] methodArguments)
+ {
+ this.methodArguments = methodArguments;
+ }
+
+ public String getPath()
+ {
+ return keyPath;
+ }
+
+ public void setPath(String keyPath)
+ {
+ this.keyPath = keyPath;
+ }
+
+ public Serializable getReturnObject()
+ {
+ return returnObject;
+ }
+
+ public void setReturnObject(Serializable returnObject)
+ {
+ this.returnObject = returnObject;
+ }
+
+ public String getSessionId()
+ {
+ return sessionId;
+ }
+
+ public void setSessionId(String sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+ public Throwable getThrowable()
+ {
+ return throwable;
+ }
+
+ public void setThrowable(Throwable throwable)
+ {
+ this.throwable = throwable;
+ }
+
+ public String getTxId()
+ {
+ return txId;
+ }
+
+ public void setTxId(String txId)
+ {
+ this.txId = txId;
+ }
+
+ public String getUserIdentifier()
+ {
+ return userIdentifier;
+ }
+
+ public void setUserIdentifier(String userIdentifier)
+ {
+ this.userIdentifier = userIdentifier;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java b/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java
new file mode 100644
index 0000000000..3ba28246c3
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * A method interceptor to wrap method invocations with auditing.
+ *
+ * A single instance is used to wrap all services. If the single instance is disabled
+ * no auditing will be carried out and there will be minimal overhead.
+ *
+ * @author Andy Hind
+ */
+public class AuditMethodInterceptor implements MethodInterceptor
+{
+ //private static Log s_logger = LogFactory.getLog(AuditMethodInterceptor.class);
+
+ private AuditComponent auditComponent;
+
+ private boolean disabled = false;
+
+ public AuditMethodInterceptor()
+ {
+ super();
+ }
+
+ public void setDisabled(boolean disabled)
+ {
+ this.disabled = disabled;
+ }
+
+ public void setAuditComponent(AuditComponent auditComponent)
+ {
+ this.auditComponent = auditComponent;
+ }
+
+ public Object invoke(MethodInvocation mi) throws Throwable
+ {
+ if(disabled)
+ {
+ return mi.proceed();
+ }
+ else
+ {
+ return auditComponent.audit(mi);
+ }
+
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditMode.java b/source/java/org/alfresco/repo/audit/AuditMode.java
new file mode 100644
index 0000000000..eab99ed6f4
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditMode.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.alfresco.repo.audit.model.AuditModelException;
+
+/**
+ * An enum to specify the audit mode:
+ *
+ *
+ * - ALL - all calls are audited
+ *
- SUCCESS - only successful calls are audited (audited in the same TX)
+ *
- FAIL - only fail calls are audited (in a new transaction)
+ *
- NONE - noting is audited
+ *
- UNSET
+ *
+ *
+ * The mode is inherited from containers if nothing is specified
+ *
+ * @author Andy Hind
+ */
+public enum AuditMode
+{
+ ALL, SUCCESS, FAIL, NONE, UNSET;
+
+ public static AuditMode getAuditMode(String value)
+ {
+ if(value.equalsIgnoreCase("all"))
+ {
+ return AuditMode.ALL;
+ }
+ else if(value.equalsIgnoreCase("success"))
+ {
+ return AuditMode.SUCCESS;
+ }
+ else if(value.equalsIgnoreCase("fail"))
+ {
+ return AuditMode.FAIL;
+ }
+ else if(value.equalsIgnoreCase("none"))
+ {
+ return AuditMode.NONE;
+ }
+ else if(value.equalsIgnoreCase("unset"))
+ {
+ return AuditMode.UNSET;
+ }
+ else
+ {
+ throw new AuditModelException("Invalid audit mode: "+value);
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditModel.java b/source/java/org/alfresco/repo/audit/AuditModel.java
new file mode 100644
index 0000000000..451ae9e12f
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditModel.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+
+/**
+ * API for querying the audit model
+ *
+ * @author Andy Hind
+ */
+public interface AuditModel extends ApplicationAuditModel, MethodAuditModel
+{
+ /**
+ * Constants for reading the xml model definition.
+ */
+
+ /* package */final static String NAME_SPACE = "http://www.alfresco.org/model/audit/1.0";
+
+ /* package */final static String EL_AUDIT = "Audit";
+
+ /* package */final static String EL_RECORD_OPTIONS = "RecordOptions";
+
+ /* package */final static String EL_RECORD_PATH = "recordPath";
+
+ /* package */final static String EL_RECORD_FILTERS = "recordFilters";
+
+ /* package */final static String EL_RECORD_SER_RETURN_VAL = "recordSerializedReturnValue";
+
+ /* package */final static String EL_RECORD_SER_EX = "recordSerializedExceptions";
+
+ /* package */final static String EL_RECORD_SER_ARGS = "recordSerializedMethodArguments";
+
+ /* package */final static String EL_RECORD_SER_PROP_BEFORE = "recordSerializedKeyPropertiesBeforeInvocation";
+
+ /* package */final static String EL_RECORD_SER_PROP_AFTER = "recordSerializedKeyPropertiesAferInvocation";
+
+ /* package */final static String EL_FILTER = "Filter";
+
+ /* package */final static String EL_METHOD = "Method";
+
+ /* package */final static String EL_SERVICE = "Service";
+
+ /* package */final static String EL_APPLICATION = "Application";
+
+ /* package */final static String EL_EXPRESSION = "Expression";
+
+ /* package */final static String EL_PARAMETER_NAME = "ParameterName";
+
+ /* package */final static String AT_MODE = "mode";
+
+ /* package */final static String AT_ENABLED = "enabled";
+
+ /* package */final static String AT_AUDIT_INTERNAL = "auditInternal";
+
+ /* package */final static String AT_NAME = "name";
+
+ /* package */final static String AT_INVERT = "invert";
+
+ /* package */final static String AT_TYPE = "type";
+}
diff --git a/source/java/org/alfresco/repo/audit/AuditServiceImpl.java b/source/java/org/alfresco/repo/audit/AuditServiceImpl.java
new file mode 100644
index 0000000000..b89f855f3c
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/AuditServiceImpl.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import javax.transaction.UserTransaction;
+
+import org.alfresco.service.cmr.audit.AuditService;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.transaction.TransactionService;
+import org.alfresco.util.ApplicationContextHelper;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * The implementation of the AuditService for application auditing.
+ *
+ * @author Andy Hind
+ */
+public class AuditServiceImpl implements AuditService
+{
+ private AuditComponent auditComponent;
+
+ public AuditServiceImpl()
+ {
+ super();
+ }
+
+ public void setAuditComponent(AuditComponent auditComponent)
+ {
+ this.auditComponent = auditComponent;
+ }
+
+ public void audit(String source, String description)
+ {
+ auditComponent.audit(source, description, null, (Object[]) null);
+ }
+
+ public void audit(String source, String description, NodeRef key)
+ {
+ auditComponent.audit(source, description, key, (Object[]) null);
+ }
+
+ public void audit(String source, String description, Object... args)
+ {
+ auditComponent.audit(source, description, null, args);
+ }
+
+ public void audit(String source, String description, NodeRef key, Object... args)
+ {
+ auditComponent.audit(source, description, key, args);
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
+ AuditService as = (AuditService) ctx.getBean("AuditService");
+
+ TransactionService txs = (TransactionService) ctx.getBean("transactionComponent");
+ UserTransaction tx = txs.getUserTransaction();
+ tx.begin();
+ as.audit("AuditedApp", "First");
+ as.audit("AuditedApp", "Second", new NodeRef(new StoreRef("test", "audit"), "id"));
+ as.audit("AuditedApp", "Third", new Object[]{"one", "two", "three"});
+ as.audit("AuditedApp", "Fourth", new NodeRef(new StoreRef("test", "audit"), "id"), new Object[]{"one", "two", "three"});
+
+ as.audit("UnAuditedApp", "First");
+ as.audit("UnAuditedApp", "Second", new NodeRef(new StoreRef("test", "audit"), "id"));
+ as.audit("UnAuditedApp", "Third", new Object[]{"one", "two", "three"});
+ as.audit("UnAuditedApp", "Fourth", new NodeRef(new StoreRef("test", "audit"), "id"), new Object[]{"one", "two", "three"});
+
+ tx.commit();
+
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/MethodAuditModel.java b/source/java/org/alfresco/repo/audit/MethodAuditModel.java
new file mode 100644
index 0000000000..37b1200173
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/MethodAuditModel.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+public interface MethodAuditModel
+{
+ /**
+ * Report if audit behaviour can be determined before the method call
+ *
+ * @param auditState,
+ * @param mi
+ * @return
+ */
+ public AuditMode beforeExecution(AuditMode auditMode, MethodInvocation mi);
+
+ /**
+ * Report if audit behaviour can be determined after the method call
+ *
+ * @param auditState,
+ * @param mi
+ * @return
+ */
+ public AuditMode afterExecution(AuditMode auditMode, MethodInvocation mi);
+
+ /**
+ * Report if audit behaviour should be invoked on error. It could be we look at the error and filter - this is not supported at the moment.
+ *
+ * @param auditState,
+ * @param mi
+ * @return
+ */
+ public AuditMode onError(AuditMode auditMode, MethodInvocation mi);
+
+ /**
+ * Get the optional parameters that are to be recorded
+ *
+ * @param mi
+ * @return
+ */
+ public RecordOptions getAuditRecordOptions(MethodInvocation mi);
+}
diff --git a/source/java/org/alfresco/repo/audit/PublicServiceIdentifier.java b/source/java/org/alfresco/repo/audit/PublicServiceIdentifier.java
new file mode 100644
index 0000000000..072b3a2931
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/PublicServiceIdentifier.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * This defines the API to identify the public service upon which a method invocation has been made.
+ *
+ * @author Andy Hind
+ */
+public interface PublicServiceIdentifier
+{
+ /**
+ * Get the name of the public service for the method invocation.
+ *
+ * @param mi
+ * @return
+ */
+ public String getPublicServiceName(MethodInvocation mi);
+}
diff --git a/source/java/org/alfresco/repo/audit/PublicServiceIdentifierImpl.java b/source/java/org/alfresco/repo/audit/PublicServiceIdentifierImpl.java
new file mode 100644
index 0000000000..d39f3c4881
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/PublicServiceIdentifierImpl.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.alfresco.service.PublicService;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+
+/**
+ * Identify public services by method invocation. Look ups are cached on a thread local as they are quite expensive. All public service names end with "Service" and start with
+ * capital letter. This pattern is used to filter bean names. TODO: Look at pulling out all the mappings at start up.
+ *
+ * @author Andy Hind
+ */
+public class PublicServiceIdentifierImpl implements PublicServiceIdentifier, BeanFactoryPostProcessor
+{
+ private static Log s_logger = LogFactory.getLog(PublicServiceIdentifierImpl.class);
+
+ private static ThreadLocal> methodToServiceMap = new ThreadLocal>();
+
+ private ConfigurableListableBeanFactory beanFactory;
+
+ public PublicServiceIdentifierImpl()
+ {
+ super();
+ }
+
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
+ {
+ this.beanFactory = beanFactory;
+ }
+
+ public String getPublicServiceName(MethodInvocation mi)
+ {
+ return getServiceName(mi);
+ }
+
+ /**
+ * Cache service name look up.
+ *
+ * @param mi
+ * @return
+ * @throws BeansException
+ */
+ private String getServiceName(MethodInvocation mi) throws BeansException
+ {
+ if (methodToServiceMap.get() == null)
+ {
+ methodToServiceMap.set(new HashMap());
+ }
+ Method method = mi.getMethod();
+ String serviceName = methodToServiceMap.get().get(method);
+ if (serviceName == null)
+ {
+ serviceName = getServiceNameImpl(mi);
+ methodToServiceMap.get().put(method, serviceName);
+ }
+ else
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Cached look up for " + serviceName + "." + method.getName());
+ }
+ }
+ return serviceName;
+ }
+
+ /**
+ * Do the look up by interface type.
+ *
+ * @param mi
+ * @return
+ * @throws BeansException
+ */
+
+ private String getServiceNameImpl(MethodInvocation mi) throws BeansException
+ {
+ Class clazz = mi.getThis().getClass();
+ while (clazz != null)
+ {
+ Class[] interfaces = clazz.getInterfaces();
+ for (Class iFace : interfaces)
+ {
+ Class publicServiceInterface = findPublicService(iFace);
+ if (publicServiceInterface != null)
+ {
+ Map beans = beanFactory.getBeansOfType(publicServiceInterface);
+ Iterator iter = beans.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String serviceName = (String) entry.getKey();
+ if ((serviceName.endsWith("Service"))
+ && (Character.isUpperCase(serviceName.charAt(0)))
+ && !serviceName.equals("DescriptorService"))
+ {
+ return serviceName;
+ }
+ }
+ }
+
+ }
+ clazz = clazz.getSuperclass();
+ }
+ return null;
+ }
+
+ /**
+ * We use a marker annotation to identify public interfaces.
+ * The interfaces have to be walked to determine if a public interface is implemented.
+ *
+ * Only one public service interface is expected.
+ *
+ * @param clazz
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ private Class findPublicService(Class clazz)
+ {
+ if (!clazz.isInterface())
+ {
+ return null;
+ }
+
+ if (clazz.isAnnotationPresent(PublicService.class))
+ {
+ return clazz;
+ }
+
+ Class[] classes = clazz.getInterfaces();
+ for(Class implemented: classes)
+ {
+ Class answer = findPublicService(implemented);
+ if(answer != null)
+ {
+ return answer;
+ }
+ }
+ return null;
+
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/RecordOptions.java b/source/java/org/alfresco/repo/audit/RecordOptions.java
new file mode 100644
index 0000000000..f1194bef20
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/RecordOptions.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit;
+
+import org.alfresco.repo.audit.model.TrueFalseUnset;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.dom4j.Element;
+
+public interface RecordOptions
+{
+ public TrueFalseUnset getRecordFilters();
+
+ public TrueFalseUnset getRecordPath();
+
+ public TrueFalseUnset getRecordSerializedExceptions();
+
+ public TrueFalseUnset getRecordSerializedKeyPropertiesAfterEvaluation();
+
+ public TrueFalseUnset getRecordSerializedKeyPropertiesBeforeEvaluation();
+
+ public TrueFalseUnset getRecordSerializedMethodArguments();
+
+ public TrueFalseUnset getRecordSerializedReturnValue();
+}
diff --git a/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml b/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml
new file mode 100644
index 0000000000..17ff8452cd
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ select
+ audit_date
+ from
+ org.alfresco.repo.audit.hibernate.AuditDateImpl as audit_date
+ where
+ audit_date.id = (select max(audit_date_2.id) from org.alfresco.repo.audit.hibernate.AuditDateImpl as audit_date_2)
+
+
+
+ select
+ audit_config
+ from
+ org.alfresco.repo.audit.hibernate.AuditConfigImpl as audit_config
+ where
+ audit_config.id = (select max(audit_config_2.id) from org.alfresco.repo.audit.hibernate.AuditConfigImpl as audit_config_2)
+
+
+
+ select
+ audit_store
+ from
+ org.alfresco.repo.audit.hibernate.AuditSourceImpl as audit_store
+ where
+ audit_store.application = :application and
+ audit_store.service is null and
+ audit_store.method is null
+
+
+
+ select
+ audit_store
+ from
+ org.alfresco.repo.audit.hibernate.AuditSourceImpl as audit_store
+ where
+ audit_store.application = :application and
+ audit_store.service = :service and
+ audit_store.method = :method
+
+
+
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java b/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java
new file mode 100644
index 0000000000..62369dfd4b
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+
+/**
+ * Hibernate interface for audit configuration persistence.
+ *
+ * @author Andy Hind
+ */
+public interface AuditConfig
+{
+ /**
+ * Get the content URL for a copy of the configuration file.
+ *
+ * @return
+ */
+ public abstract String getConfigURL();
+
+ /**
+ * Get the surrogate key for the configuration entry.
+ * The creation is managed by hibernate.
+ *
+ * @return
+ */
+ public abstract long getId();
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java
new file mode 100644
index 0000000000..6e86b0b8ee
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import org.alfresco.util.EqualsHelper;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.springframework.beans.factory.InitializingBean;
+
+public class AuditConfigImpl implements AuditConfig, InitializingBean
+{
+ /**
+ * The hibernate generated internal key.
+ */
+ private long id;
+
+ /**
+ * The URL to the content that contains the configuration file
+ */
+ private String configURL;
+
+ public AuditConfigImpl()
+ {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditContig#getConfigURL()
+ */
+ public String getConfigURL()
+ {
+ return configURL;
+ }
+
+ public void setConfigURL(String configURL)
+ {
+ this.configURL = configURL;
+ }
+
+
+
+ public void afterPropertiesSet() throws Exception
+ {
+ // Read the audit configuration
+
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditContig#getId()
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+ /**
+ * Internal setter for hibernate.
+ *
+ * @param id
+ */
+
+ @SuppressWarnings("unused")
+ private void setId(long id)
+ {
+ this.id = id;
+ }
+
+ /**
+ * Helper method to get the latest audit config
+ */
+ public static AuditConfigImpl getLatestConfig(Session session)
+ {
+ Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_LAST_AUDIT_CONFIG);
+ return (AuditConfigImpl) query.uniqueResult();
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if(!(o instanceof AuditConfigImpl))
+ {
+ return false;
+ }
+ AuditConfigImpl other = (AuditConfigImpl)o;
+ return EqualsHelper.nullSafeEquals(this.configURL, other.configURL);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return configURL == null ? 0 : configURL.hashCode();
+ }
+
+
+}
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java b/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java
new file mode 100644
index 0000000000..74f0b36ee7
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditDate.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import java.util.Date;
+
+/**
+ * Hibernate date dimension for audit roll ups
+ *
+ * @author Andy Hind
+ */
+public interface AuditDate
+{
+
+ /**
+ * Get the date
+ *
+ * @return
+ */
+ public abstract Date getDate();
+
+ /**
+ * Get the day of the year.
+ *
+ * @return
+ */
+ public abstract int getDayOfYear();
+
+ /**
+ * Get the day of the month.
+ *
+ * @return
+ */
+ public abstract int getDayOfMonth();
+
+ /**
+ * Get the day of the week
+ *
+ * @return
+ */
+ public abstract int getDayOfWeek();
+
+ /**
+ * Get the half year;
+ *
+ * @return
+ */
+ public abstract int getHalfYear();
+
+
+ /**
+ * Get the surrogate key
+ *
+ * @return
+ */
+ public abstract long getId();
+
+ /**
+ * Get the month
+ *
+ * @return
+ */
+ public abstract int getMonth();
+
+ /**
+ * Get the quarter
+ *
+ * @return
+ */
+ public abstract int getQuarter();
+
+ /**
+ * Get the week of the month.
+ *
+ * @return
+ */
+ public abstract int getWeekOfMonth();
+
+ /**
+ * Get the week of the year.
+ *
+ * @return
+ */
+ public abstract int getWeekOfYear();
+
+ /**
+ * Get the year.
+ * @return
+ */
+ public abstract int getYear();
+
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java
new file mode 100644
index 0000000000..a15e9c85da
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.alfresco.util.EqualsHelper;
+import org.hibernate.Query;
+import org.hibernate.Session;
+
+/**
+ * Hibernate persistence for a date dimension.
+ *
+ * @author Andy Hind
+ */
+public class AuditDateImpl implements AuditDate
+{
+ /**
+ * Surrogate key
+ */
+ private long id;
+
+ /**
+ * The date
+ */
+ private Date date;
+
+ /**
+ * The day
+ */
+ private int dayOfYear;
+
+ /**
+ * Day of month.
+ */
+ private int dayOfMonth;
+
+ /**
+ * The day of the week
+ */
+ private int dayOfWeek;
+
+ /**
+ * The week in the year
+ */
+ private int weekOfYear;
+
+ /**
+ * The week of the month
+ */
+ private int weekOfMonth;
+
+ /**
+ * The month in the year
+ */
+ private int month;
+
+ /**
+ * The quarter in the year
+ */
+ private int quarter;
+
+ /**
+ * The half year in the year
+ */
+ private int halfYear;
+
+ /**
+ * The year
+ */
+ private int year;
+
+ protected AuditDateImpl()
+ {
+ super();
+ }
+
+ public AuditDateImpl(Date date)
+ {
+ super();
+ setDate(date);
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getDate()
+ */
+ public Date getDate()
+ {
+ return date;
+ }
+
+ public void setDate(Date date)
+ {
+ Calendar cal = GregorianCalendar.getInstance();
+ cal.setTime(date);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ this.date = cal.getTime();
+
+ this.setDayOfYear(cal.get(Calendar.DAY_OF_YEAR));
+ this.setDayOfMonth(cal.get(Calendar.DAY_OF_MONTH));
+ this.setDayOfWeek(cal.get(Calendar.DAY_OF_WEEK));
+ this.setMonth(cal.get(Calendar.MONTH));
+ this.setHalfYear(getMonth() <= Calendar.JUNE ? 0 : 1);
+ this.setQuarter((getMonth()/3));
+ this.setWeekOfMonth(cal.get(Calendar.WEEK_OF_MONTH));
+ this.setWeekOfYear(cal.get(Calendar.WEEK_OF_YEAR));
+ this.setYear(cal.get(Calendar.YEAR));
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getDayOfYear()
+ */
+ public int getDayOfYear()
+ {
+ return dayOfYear;
+ }
+
+ protected void setDayOfYear(int dayOfYear)
+ {
+ this.dayOfYear = dayOfYear;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getDayOfMonth()
+ */
+ public int getDayOfMonth()
+ {
+ return dayOfMonth;
+ }
+
+ protected void setDayOfMonth(int dayOfMonth)
+ {
+ this.dayOfMonth = dayOfMonth;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getDayOfWeek()
+ */
+ public int getDayOfWeek()
+ {
+ return dayOfWeek;
+ }
+
+ protected void setDayOfWeek(int dayOfWeek)
+ {
+ this.dayOfWeek = dayOfWeek;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getHalfYear()
+ */
+ public int getHalfYear()
+ {
+ return halfYear;
+ }
+
+ protected void setHalfYear(int halfYear)
+ {
+ this.halfYear = halfYear;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getId()
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+ protected void setId(long id)
+ {
+ this.id = id;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getMonth()
+ */
+ public int getMonth()
+ {
+ return month;
+ }
+
+ protected void setMonth(int month)
+ {
+ this.month = month;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getQuarter()
+ */
+ public int getQuarter()
+ {
+ return quarter;
+ }
+
+ protected void setQuarter(int quarter)
+ {
+ this.quarter = quarter;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getWeekOfMonth()
+ */
+ public int getWeekOfMonth()
+ {
+ return weekOfMonth;
+ }
+
+ protected void setWeekOfMonth(int weekOfMonth)
+ {
+ this.weekOfMonth = weekOfMonth;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getWeekOfYear()
+ */
+ public int getWeekOfYear()
+ {
+ return weekOfYear;
+ }
+
+ protected void setWeekOfYear(int weekOfYear)
+ {
+ this.weekOfYear = weekOfYear;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.audit.hibernate.AuditDate#getYear()
+ */
+ public int getYear()
+ {
+ return year;
+ }
+
+ protected void setYear(int year)
+ {
+ this.year = year;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(!(o instanceof AuditDateImpl))
+ {
+ return false;
+ }
+ AuditDateImpl that = (AuditDateImpl)o;
+ return EqualsHelper.nullSafeEquals(this.date, that.date);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return this.date.hashCode();
+ }
+
+ /**
+ * Helper method to get the latest audit date
+ */
+ public static AuditDateImpl getLatestDate(Session session)
+ {
+ Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_LAST_AUDIT_DATE);
+ return (AuditDateImpl) query.uniqueResult();
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java b/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java
new file mode 100644
index 0000000000..17d08204d8
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditFact.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import java.util.Date;
+
+public interface AuditFact
+{
+
+ public abstract String getArg1();
+
+ public abstract String getArg2();
+
+ public abstract String getArg3();
+
+ public abstract String getArg4();
+
+ public abstract String getArg5();
+
+ public abstract AuditConfig getAuditConfig();
+
+ public abstract AuditDate getAuditDate();
+
+ public abstract AuditSource getAuditSource();
+
+ public abstract String getClientInetAddress();
+
+ public abstract Date getDate();
+
+ public abstract String getException();
+
+ public abstract boolean isFail();
+
+ public abstract boolean isFiltered();
+
+ public abstract String getHostInetAddress();
+
+ public abstract long getId();
+
+ public abstract String getMessage();
+
+ public abstract String getNodeUUID();
+
+ public abstract String getPath();
+
+ public abstract String getReturnValue();
+
+ public abstract String getSerialisedURL();
+
+ public abstract String getSessionId();
+
+ public abstract String getStoreId();
+
+ public abstract String getStoreProtocol();
+
+ public abstract String getTransactionId();
+
+ public abstract String getUserId();
+
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java
new file mode 100644
index 0000000000..3ec7f4a4ad
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java
@@ -0,0 +1,578 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import java.util.Date;
+
+/**
+ * An Audit fact Rely on standard equals and hash code as they should all be unique.
+ *
+ * @author Andy Hind
+ */
+public class AuditFactImpl implements AuditFact
+{
+ private long id;
+
+ private AuditDate auditDate;
+
+ private AuditConfig auditConfig;
+
+ private AuditSource auditSource;
+
+ private String userId;
+
+ private Date date;
+
+ private String transactionId;
+
+ private String sessionId;
+
+ private String storeProtocol;
+
+ private String storeId;
+
+ private String nodeUUID;
+
+ private String path;
+
+ private boolean filtered;
+
+ private String returnValue;
+
+ private String arg1;
+
+ private String arg2;
+
+ private String arg3;
+
+ private String arg4;
+
+ private String arg5;
+
+ private boolean fail;
+
+ private String serialisedURL;
+
+ private String exception;
+
+ private String hostInetAddress;
+
+ private String clientInetAddress;
+
+ private String message;
+
+ public AuditFactImpl()
+ {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getArg1()
+ */
+ public String getArg1()
+ {
+ return arg1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setArg1(java.lang.String)
+ */
+ public void setArg1(String arg1)
+ {
+ this.arg1 = arg1;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getArg2()
+ */
+ public String getArg2()
+ {
+ return arg2;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setArg2(java.lang.String)
+ */
+ public void setArg2(String arg2)
+ {
+ this.arg2 = arg2;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getArg3()
+ */
+ public String getArg3()
+ {
+ return arg3;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setArg3(java.lang.String)
+ */
+ public void setArg3(String arg3)
+ {
+ this.arg3 = arg3;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getArg4()
+ */
+ public String getArg4()
+ {
+ return arg4;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setArg4(java.lang.String)
+ */
+ public void setArg4(String arg4)
+ {
+ this.arg4 = arg4;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getArg5()
+ */
+ public String getArg5()
+ {
+ return arg5;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setArg5(java.lang.String)
+ */
+ public void setArg5(String arg5)
+ {
+ this.arg5 = arg5;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getAuditConfig()
+ */
+ public AuditConfig getAuditConfig()
+ {
+ return auditConfig;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setAuditConfig(org.alfresco.repo.audit.hibernate.AuditConfig)
+ */
+ public void setAuditConfig(AuditConfig auditConfig)
+ {
+ this.auditConfig = auditConfig;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getAuditDate()
+ */
+ public AuditDate getAuditDate()
+ {
+ return auditDate;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setAuditDate(org.alfresco.repo.audit.hibernate.AuditDate)
+ */
+ public void setAuditDate(AuditDate auditDate)
+ {
+ this.auditDate = auditDate;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getAuditSource()
+ */
+ public AuditSource getAuditSource()
+ {
+ return auditSource;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setAuditSource(org.alfresco.repo.audit.hibernate.AuditSource)
+ */
+ public void setAuditSource(AuditSource auditSource)
+ {
+ this.auditSource = auditSource;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getClientInetAddress()
+ */
+ public String getClientInetAddress()
+ {
+ return clientInetAddress;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setClientInetAddress(java.net.InetAddress)
+ */
+ public void setClientInetAddress(String clientInetAddress)
+ {
+ this.clientInetAddress = clientInetAddress;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getDate()
+ */
+ public Date getDate()
+ {
+ return date;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setDate(java.util.Date)
+ */
+ public void setDate(Date date)
+ {
+ this.date = date;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getException()
+ */
+ public String getException()
+ {
+ return exception;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setException(java.lang.String)
+ */
+ public void setException(String exception)
+ {
+ this.exception = exception;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#isFail()
+ */
+ public boolean isFail()
+ {
+ return fail;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setFail(boolean)
+ */
+ public void setFail(boolean fail)
+ {
+ this.fail = fail;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#isFiltered()
+ */
+ public boolean isFiltered()
+ {
+ return filtered;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setFiltered(boolean)
+ */
+ public void setFiltered(boolean filtered)
+ {
+ this.filtered = filtered;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getHostInetAddress()
+ */
+ public String getHostInetAddress()
+ {
+ return hostInetAddress;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setHostInetAddress(java.net.InetAddress)
+ */
+ public void setHostInetAddress(String hostInetAddress)
+ {
+ this.hostInetAddress = hostInetAddress;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getId()
+ */
+ public long getId()
+ {
+ return id;
+ }
+
+ protected void setId(long id)
+ {
+ this.id = id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getMessage()
+ */
+ public String getMessage()
+ {
+ return message;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setMessage(java.lang.String)
+ */
+ public void setMessage(String message)
+ {
+ this.message = message;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getNodeGUID()
+ */
+ public String getNodeUUID()
+ {
+ return nodeUUID;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setNodeGUID(java.lang.String)
+ */
+ public void setNodeUUID(String nodeUUID)
+ {
+ this.nodeUUID = nodeUUID;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getPath()
+ */
+ public String getPath()
+ {
+ return path;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setPath(java.lang.String)
+ */
+ public void setPath(String path)
+ {
+ this.path = path;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getReturnValue()
+ */
+ public String getReturnValue()
+ {
+ return returnValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setReturnValue(java.lang.String)
+ */
+ public void setReturnValue(String returnValue)
+ {
+ this.returnValue = returnValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getSerialisedURL()
+ */
+ public String getSerialisedURL()
+ {
+ return serialisedURL;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setSerialisedURL(java.lang.String)
+ */
+ public void setSerialisedURL(String serialisedURL)
+ {
+ this.serialisedURL = serialisedURL;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getSessionId()
+ */
+ public String getSessionId()
+ {
+ return sessionId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setSessionId(java.lang.String)
+ */
+ public void setSessionId(String sessionId)
+ {
+ this.sessionId = sessionId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getStoreId()
+ */
+ public String getStoreId()
+ {
+ return storeId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setStoreId(java.lang.String)
+ */
+ public void setStoreId(String storeId)
+ {
+ this.storeId = storeId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getStoreProtocol()
+ */
+ public String getStoreProtocol()
+ {
+ return storeProtocol;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setStoreProtocol(java.lang.String)
+ */
+ public void setStoreProtocol(String storeProtocol)
+ {
+ this.storeProtocol = storeProtocol;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getTransactionId()
+ */
+ public String getTransactionId()
+ {
+ return transactionId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setTransactionId(java.lang.String)
+ */
+ public void setTransactionId(String transactionId)
+ {
+ this.transactionId = transactionId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#getUserId()
+ */
+ public String getUserId()
+ {
+ return userId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.alfresco.repo.audit.hibernate.AuditFact#setUserId(java.lang.String)
+ */
+ public void setUserId(String userId)
+ {
+ this.userId = userId;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java b/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java
new file mode 100644
index 0000000000..17ac1c2ef0
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditSource.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+public interface AuditSource
+{
+ public String getApplication();
+
+ public long getId();
+
+ public String getMethod();
+
+ public String getService();
+
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java b/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java
new file mode 100644
index 0000000000..927d042317
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import org.alfresco.util.EqualsHelper;
+import org.hibernate.Query;
+import org.hibernate.Session;
+
+public class AuditSourceImpl implements AuditSource
+{
+ /**
+ * The surrogate key
+ */
+ private long id;
+
+ /**
+ * The auditing application (System for method audits)
+ */
+ private String application;
+
+ /**
+ * The audited service
+ */
+ private String service;
+
+ /**
+ * The audited method
+ */
+ private String method;
+
+ public AuditSourceImpl()
+ {
+ super();
+ }
+
+ public String getApplication()
+ {
+ return application;
+ }
+
+ public void setApplication(String application)
+ {
+ this.application = application;
+ }
+
+ public long getId()
+ {
+ return id;
+ }
+
+ protected void setId(long id)
+ {
+ this.id = id;
+ }
+
+ public String getMethod()
+ {
+ return method;
+ }
+
+ public void setMethod(String method)
+ {
+ this.method = method;
+ }
+
+ public String getService()
+ {
+ return service;
+ }
+
+ public void setService(String service)
+ {
+ this.service = service;
+ }
+
+ public static AuditSourceImpl getApplicationSource(Session session, String application)
+ {
+ Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE);
+ query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_APP, application);
+ return (AuditSourceImpl) query.uniqueResult();
+ }
+
+ public static AuditSourceImpl getApplicationSource(Session session, String application, String service,
+ String method)
+ {
+ Query query = session.getNamedQuery(HibernateAuditDAO.QUERY_AUDIT_METHOD_SOURCE);
+ query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_APP, application);
+ query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_SER, service);
+ query.setParameter(HibernateAuditDAO.QUERY_AUDIT_APP_SOURCE_MET, method);
+ return (AuditSourceImpl) query.uniqueResult();
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (!(o instanceof AuditSourceImpl))
+ {
+ return false;
+ }
+ AuditSourceImpl other = (AuditSourceImpl) o;
+ return EqualsHelper.nullSafeEquals(this.application, other.application)
+ && EqualsHelper.nullSafeEquals(this.service, other.service)
+ && EqualsHelper.nullSafeEquals(this.method, other.method);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = application.hashCode();
+ if(service != null)
+ {
+ hash = (hash * 37) + service.hashCode();
+ }
+ if(method != null)
+ {
+ hash = (hash * 37) + method.hashCode();
+ }
+ return hash;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java
new file mode 100644
index 0000000000..b4bf563e18
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.hibernate;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+import org.alfresco.repo.audit.AuditConfiguration;
+import org.alfresco.repo.audit.AuditDAO;
+import org.alfresco.repo.audit.AuditInfo;
+import org.alfresco.repo.content.AbstractContentStore;
+import org.alfresco.repo.content.ContentStore;
+import org.alfresco.repo.content.MimetypeMap;
+import org.alfresco.repo.transaction.TransactionalDao;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.cmr.repository.datatype.Duration;
+import org.alfresco.util.EqualsHelper;
+import org.alfresco.util.GUID;
+import org.hibernate.Session;
+import org.springframework.orm.hibernate3.HibernateCallback;
+import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
+
+/**
+ * Assumes mimetype and encoding sent to the content store (we are not saving this anywhere)
+ *
+ * @author Andy Hind
+ */
+public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO, TransactionalDao
+{
+ public static final String QUERY_LAST_AUDIT_DATE = "audit.GetLatestAuditDate";
+
+ public static final String QUERY_LAST_AUDIT_CONFIG = "audit.GetLatestAuditConfig";
+
+ public static final String QUERY_AUDIT_APP_SOURCE = "audit.GetAuditSourceByApplication";
+
+ public static final String QUERY_AUDIT_METHOD_SOURCE = "audit.GetAuditSourceByApplicationServiceMethod";
+
+ public static final String QUERY_AUDIT_APP_SOURCE_APP = "application";
+
+ public static final String QUERY_AUDIT_APP_SOURCE_SER = "service";
+
+ public static final String QUERY_AUDIT_APP_SOURCE_MET = "method";
+
+ /** a uuid identifying this unique instance */
+ private String uuid;
+
+ private ContentStore contentStore;
+
+ private ThreadLocal auditConfiguration = new ThreadLocal();
+
+ private ThreadLocal auditConfigImplId = new ThreadLocal();
+
+ private ThreadLocal auditDateImplId = new ThreadLocal();
+
+ private ThreadLocal> sourceIds = new ThreadLocal>();
+
+ public HibernateAuditDAO()
+ {
+ super();
+ this.uuid = GUID.generate();
+ }
+
+ public ContentStore getContentStore()
+ {
+ return contentStore;
+ }
+
+ public void setContentStore(ContentStore contentStore)
+ {
+ this.contentStore = contentStore;
+ }
+
+ public void audit(AuditInfo auditInfo)
+ {
+ // Find/Build the configuraton entry
+ AuditConfigImpl auditConfig = getAuditConfig(auditInfo);
+
+ // Find/Build any dates
+ AuditDateImpl auditDate = getAuditDate(auditInfo);
+
+ // Find/Build the source
+ AuditSourceImpl auditSource = getAuditSource(auditInfo);
+
+ // Build the new audit fact information
+ AuditFactImpl auditFact = new AuditFactImpl();
+ auditFact.setAuditConfig(auditConfig);
+ auditFact.setAuditDate(auditDate);
+ auditFact.setAuditSource(auditSource);
+
+ // Properties
+
+ Serializable[] args = auditInfo.getMethodArguments();
+
+ if (args != null)
+ {
+ switch (args.length)
+ {
+ default:
+ case 5:
+ auditFact.setArg5(getStringOrNull(args[4]));
+ case 4:
+ auditFact.setArg4(getStringOrNull(args[3]));
+ case 3:
+ auditFact.setArg3(getStringOrNull(args[2]));
+ case 2:
+ auditFact.setArg2(getStringOrNull(args[1]));
+ case 1:
+ auditFact.setArg1(getStringOrNull(args[0]));
+ case 0:
+ }
+ }
+
+ auditFact.setClientInetAddress(auditInfo.getClientAddress() == null ? null : auditInfo.getClientAddress()
+ .toString());
+ auditFact.setDate(auditInfo.getDate());
+ auditFact.setException(auditInfo.getThrowable() == null ? null : auditInfo.getThrowable().getMessage());
+ auditFact.setFail(auditInfo.isFail());
+ auditFact.setFiltered(auditInfo.isFiltered());
+ auditFact.setHostInetAddress(auditInfo.getHostAddress() == null ? null : auditInfo.getHostAddress().toString());
+ auditFact.setMessage(auditInfo.getMessage());
+ auditFact.setNodeUUID(auditInfo.getKeyGUID());
+ auditFact.setPath(auditInfo.getPath());
+ auditFact.setReturnValue(auditInfo.getReturnObject() == null ? null : auditInfo.getReturnObject().toString());
+ // auditFact.setSerialisedURL()
+ auditFact.setSessionId(auditInfo.getSessionId());
+ if (auditInfo.getKeyStore() != null)
+ {
+ auditFact.setStoreId(auditInfo.getKeyStore().getIdentifier());
+ auditFact.setStoreProtocol(auditInfo.getKeyStore().getProtocol());
+ }
+ auditFact.setTransactionId(auditInfo.getTxId());
+ auditFact.setUserId(auditInfo.getUserIdentifier());
+
+ // Save
+ getSession().save(auditFact);
+
+ }
+
+ private String getStringOrNull(Object o)
+ {
+ if (o == null)
+ {
+ return null;
+ }
+ else
+ {
+ return o.toString();
+ }
+ }
+
+ private AuditSourceImpl getAuditSource(AuditInfo auditInfo)
+ {
+ AuditSourceImpl auditSourceImpl;
+
+ SourceKey sourceKey = new SourceKey(auditInfo.getAuditApplication(), auditInfo.getAuditService(), auditInfo.getAuditMethod());
+ if(sourceIds.get() == null)
+ {
+ sourceIds.set(new HashMap());
+ }
+ Long id = sourceIds.get().get(sourceKey);
+ if(id != null)
+ {
+ auditSourceImpl = (AuditSourceImpl) getSession().get(AuditSourceImpl.class, id.longValue());
+ if(auditSourceImpl != null)
+ {
+ return auditSourceImpl;
+ }
+ }
+
+ if ((auditInfo.getAuditService() != null)
+ && (auditInfo.getAuditService().length() > 0) && (auditInfo.getAuditMethod() != null)
+ && (auditInfo.getAuditMethod().length() > 0))
+ {
+ auditSourceImpl = AuditSourceImpl.getApplicationSource(getSession(), auditInfo.getAuditApplication(),
+ auditInfo.getAuditService(), auditInfo.getAuditMethod());
+ if (auditSourceImpl == null)
+ {
+ auditSourceImpl = new AuditSourceImpl();
+ auditSourceImpl.setApplication(auditInfo.getAuditApplication());
+ auditSourceImpl.setService(auditInfo.getAuditService());
+ auditSourceImpl.setMethod(auditInfo.getAuditMethod());
+ getSession().save(auditSourceImpl);
+ }
+ }
+ else
+ {
+ auditSourceImpl = AuditSourceImpl.getApplicationSource(getSession(), auditInfo.getAuditApplication());
+ if (auditSourceImpl == null)
+ {
+ auditSourceImpl = new AuditSourceImpl();
+ auditSourceImpl.setApplication(auditInfo.getAuditApplication());
+ getSession().save(auditSourceImpl);
+ }
+ }
+ sourceIds.get().put(sourceKey, Long.valueOf(auditSourceImpl.getId()));
+ return auditSourceImpl;
+ }
+
+ private AuditDateImpl getAuditDate(AuditInfo auditInfo)
+ {
+ Calendar cal = GregorianCalendar.getInstance();
+ cal.setTime(auditInfo.getDate());
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ Date required = cal.getTime();
+
+ AuditDateImpl auditDate;
+ if (auditDateImplId.get() == null)
+ {
+ auditDate = AuditDateImpl.getLatestDate(getSession());
+ if (auditDate == null)
+ {
+ // The first entry ever so we just make it
+ auditDate = new AuditDateImpl(auditInfo.getDate());
+ getSession().save(auditDate);
+ }
+ auditDateImplId.set(Long.valueOf(auditDate.getId()));
+ }
+ else
+ {
+ auditDate = (AuditDateImpl) getSession().get(AuditDateImpl.class, auditDateImplId.get().longValue());
+ if ((auditDate == null) || (!required.equals(auditDate.getDate())))
+ {
+ auditDate = AuditDateImpl.getLatestDate(getSession());
+ if (auditDate == null)
+ {
+ // The first entry ever so we just make it
+ auditDate = new AuditDateImpl(auditInfo.getDate());
+ getSession().save(auditDate);
+ }
+ auditDateImplId.set(Long.valueOf(auditDate.getId()));
+ }
+ }
+ while (!required.equals(auditDate.getDate()))
+ {
+ Date nextDate = Duration.add(auditDate.getDate(), new Duration("P1D"));
+ auditDate = new AuditDateImpl(nextDate);
+ getSession().save(auditDate);
+ auditDateImplId.set(Long.valueOf(auditDate.getId()));
+ }
+ return auditDate;
+ }
+
+ private AuditConfigImpl getAuditConfig(AuditInfo auditInfo)
+ {
+ AuditConfigImpl auditConfig;
+ if ((auditConfiguration.get() == null) || (auditConfiguration.get() != auditInfo.getAuditConfiguration()))
+ {
+ auditConfig = AuditConfigImpl.getLatestConfig(getSession());
+ if (auditConfig == null)
+ {
+ auditConfig = createNewAuditConfigImpl(auditInfo);
+ }
+ else
+ {
+ InputStream current = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
+ ContentReader reader = contentStore.getReader(auditConfig.getConfigURL());
+ reader.setMimetype(MimetypeMap.MIMETYPE_XML);
+ reader.setEncoding("UTF-8");
+ InputStream last = new BufferedInputStream(reader.getContentInputStream());
+ int currentValue = -2;
+ int lastValue = -2;
+ try
+ {
+ while ((currentValue != -1) && (lastValue != -1) && (currentValue == lastValue))
+ {
+ currentValue = current.read();
+ lastValue = last.read();
+
+ }
+ }
+ catch (IOException e)
+ {
+ throw new AlfrescoRuntimeException(
+ "Failed to read and validate current audit configuration against the last", e);
+ }
+ if (currentValue != lastValue)
+ {
+ // Files are different - require a new entry
+ auditConfig = createNewAuditConfigImpl(auditInfo);
+ }
+ else
+ {
+ // No change
+ }
+ }
+ auditConfigImplId.set(Long.valueOf(auditConfig.getId()));
+ auditConfiguration.set(auditInfo.getAuditConfiguration());
+ }
+ else
+ {
+ auditConfig = (AuditConfigImpl) getSession()
+ .get(AuditConfigImpl.class, auditConfigImplId.get().longValue());
+ if (auditConfig == null)
+ {
+ auditConfig = createNewAuditConfigImpl(auditInfo);
+ }
+ }
+ return auditConfig;
+ }
+
+ private AuditConfigImpl createNewAuditConfigImpl(AuditInfo auditInfo)
+ {
+ AuditConfigImpl auditConfig = new AuditConfigImpl();
+ InputStream is = new BufferedInputStream(auditInfo.getAuditConfiguration().getInputStream());
+ String url = AbstractContentStore.createNewUrl();
+ ContentWriter writer = contentStore.getWriter(null, url);
+ writer.setMimetype(MimetypeMap.MIMETYPE_XML);
+ writer.setEncoding("UTF-8");
+ writer.putContent(is);
+ auditConfig.setConfigURL(url);
+ getSession().save(auditConfig);
+ return auditConfig;
+ }
+
+ /**
+ * Checks equality by type and uuid
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ else if (!(obj instanceof HibernateAuditDAO))
+ {
+ return false;
+ }
+ HibernateAuditDAO that = (HibernateAuditDAO) obj;
+ return this.uuid.equals(that.uuid);
+ }
+
+ /**
+ * @see #uuid
+ */
+ public int hashCode()
+ {
+ return uuid.hashCode();
+ }
+
+ /**
+ * Does this Session contain any changes which must be synchronized with the store?
+ *
+ * @return true => changes are pending
+ */
+ public boolean isDirty()
+ {
+ // create a callback for the task
+ HibernateCallback callback = new HibernateCallback()
+ {
+ public Object doInHibernate(Session session)
+ {
+ return session.isDirty();
+ }
+ };
+ // execute the callback
+ return ((Boolean) getHibernateTemplate().execute(callback)).booleanValue();
+ }
+
+ /**
+ * Just flushes the session
+ */
+ public void flush()
+ {
+ getSession().flush();
+ }
+
+ static class SourceKey
+ {
+ String application;
+
+ String service;
+
+ String method;
+
+ SourceKey(String application, String service, String method)
+ {
+ this.application = application;
+ this.service = service;
+ this.method = method;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (!(this instanceof SourceKey))
+ {
+ return false;
+ }
+ SourceKey other = (SourceKey) o;
+ return EqualsHelper.nullSafeEquals(this.application, other.application)
+ && EqualsHelper.nullSafeEquals(this.service, other.service)
+ && EqualsHelper.nullSafeEquals(this.method, other.method);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = application.hashCode();
+ if (service != null)
+ {
+ hash = (hash * 37) + service.hashCode();
+ }
+ if (method != null)
+ {
+ hash = (hash * 37) + method.hashCode();
+ }
+ return hash;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/model/AbstractAuditEntry.java b/source/java/org/alfresco/repo/audit/model/AbstractAuditEntry.java
new file mode 100644
index 0000000000..7349e44be0
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/AbstractAuditEntry.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc. Licensed under the Mozilla Public License version 1.1 with a permitted attribution clause. You may obtain a copy of the License at
+ * http://www.alfresco.org/legal/license.txt Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditMode;
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.repo.audit.PublicServiceIdentifier;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+
+public abstract class AbstractAuditEntry
+{
+ private static Log s_logger = LogFactory.getLog(AbstractAuditEntry.class);
+
+ private RecordOptionsImpl recordOptions = null;
+
+ private AbstractFilter filter = null;
+
+ private AuditMode auditMode = AuditMode.UNSET;
+
+ private TrueFalseUnset enabled = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset auditInternal = TrueFalseUnset.UNSET;
+
+ private AbstractAuditEntry parent;
+
+ private PublicServiceIdentifier publicServiceIdentifier;
+
+ public AbstractAuditEntry()
+ {
+ super();
+ }
+
+ PublicServiceIdentifier getPublicServiceIdentifier()
+ {
+ return publicServiceIdentifier;
+ }
+
+ public void setPublicServiceIdentifier(PublicServiceIdentifier publicServiceIdentifier)
+ {
+ this.publicServiceIdentifier = publicServiceIdentifier;
+ }
+
+ void configure(AbstractAuditEntry parent, Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ this.parent = parent;
+
+ Attribute auditModeAttribute = element.attribute(AuditModel.AT_MODE);
+ if (auditModeAttribute != null)
+ {
+ auditMode = AuditMode.getAuditMode(auditModeAttribute.getValue());
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Audit Mode = "+auditMode);
+ }
+
+
+ Attribute enabledAttribute = element.attribute(AuditModel.AT_ENABLED);
+ if (enabledAttribute != null)
+ {
+ enabled = TrueFalseUnset.getTrueFalseUnset(enabledAttribute.getValue());
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Enabled = "+enabled);
+ }
+
+ Attribute auditInternalAttribute = element.attribute(AuditModel.AT_AUDIT_INTERNAL);
+ if (auditInternalAttribute != null)
+ {
+ auditInternal = TrueFalseUnset.getTrueFalseUnset(auditInternalAttribute.getValue());
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Audit Internal = "+auditInternal);
+ }
+
+ // Make record options
+ Element recordOptionElement = element.element(AuditModel.EL_RECORD_OPTIONS);
+ if (recordOptionElement != null)
+ {
+ recordOptions = new RecordOptionsImpl();
+ recordOptions.configure(recordOptionElement, namespacePrefixResolver);
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Record Options = "+recordOptions);
+ }
+
+ // Make filters
+ Element filterElement = element.element(AuditModel.EL_FILTER);
+ if (filterElement != null)
+ {
+ filter = AbstractFilter.createFilter(filterElement, namespacePrefixResolver);
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Filter = "+filter);
+ }
+
+ }
+
+ /* package */TrueFalseUnset getAuditInternal()
+ {
+ return auditInternal;
+ }
+
+ /* package */AuditMode getAuditMode()
+ {
+ return auditMode;
+ }
+
+ /* package */TrueFalseUnset getEnabled()
+ {
+ return enabled;
+ }
+
+ /* package */AbstractFilter getFilter()
+ {
+ return filter;
+ }
+
+ /* package */AbstractAuditEntry getParent()
+ {
+ return parent;
+ }
+
+ /* package */RecordOptionsImpl getRecordOptions()
+ {
+ return recordOptions;
+ }
+
+ protected AuditMode getEffectiveAuditMode()
+ {
+ AuditMode auditMode;
+ if (checkEnabled() == TrueFalseUnset.TRUE)
+ {
+ auditMode = getAuditModeOrParentAuditMode();
+ }
+ else
+ {
+ auditMode = AuditMode.NONE;
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("... Effective audit mode is = "+auditMode);
+ }
+ return auditMode;
+ }
+
+ private AuditMode getAuditModeOrParentAuditMode()
+ {
+ AuditMode auditMode = getAuditMode();
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("... ... audit mode is = "+auditMode);
+ }
+ if (auditMode == AuditMode.UNSET)
+ {
+ if (getParent() == null)
+ {
+ return AuditMode.UNSET;
+ }
+ else
+ {
+ return getParent().getAuditModeOrParentAuditMode();
+ }
+ }
+ else
+ {
+ return auditMode;
+ }
+
+ }
+
+ private TrueFalseUnset checkEnabled()
+ {
+ TrueFalseUnset effective = getEnabled();
+ if (getParent() != null)
+ {
+ if ((getParent().checkEnabled() == TrueFalseUnset.TRUE) && (effective != TrueFalseUnset.FALSE))
+ {
+ return TrueFalseUnset.TRUE;
+ }
+ }
+ else
+ {
+ if (effective == TrueFalseUnset.TRUE)
+ {
+ return TrueFalseUnset.TRUE;
+ }
+ }
+ return TrueFalseUnset.FALSE;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/AbstractFilter.java b/source/java/org/alfresco/repo/audit/model/AbstractFilter.java
new file mode 100644
index 0000000000..1ee1ac0f38
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/AbstractFilter.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+
+/**
+ * The base class for filtering.
+ *
+ * This supports negating the filter, ie NOT.
+ *
+ * @author Andy Hind
+ */
+public abstract class AbstractFilter implements XMLModelElement
+{
+ private static Log s_logger = LogFactory.getLog(AbstractFilter.class);
+
+ private boolean invert = false;
+
+ public AbstractFilter()
+ {
+ super();
+ }
+
+ public static AbstractFilter createFilter(Element filterElement, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ AbstractFilter filter;
+
+ Attribute typeAttribute = filterElement.attribute(AuditModel.AT_TYPE);
+ if (typeAttribute == null)
+ {
+ throw new AuditModelException("A filter must specify it concrete type using xsi:type");
+ }
+ if (typeAttribute.getStringValue().endsWith("FilterSet"))
+ {
+ filter = new FilterSet();
+ }
+ else if (typeAttribute.getStringValue().endsWith("KeyFilter"))
+ {
+ filter = new KeyFilter();
+ }
+ else if (typeAttribute.getStringValue().endsWith("ParameterFilter"))
+ {
+ filter = new ParameterFilter();
+ }
+ else
+ {
+ throw new AuditModelException(
+ "Invalid filter type. It must be one of: FilterSet, KeyFilter, ParameterFilter ");
+ }
+
+ filter.configure(filterElement, namespacePrefixResolver);
+ return filter;
+ }
+
+ public void configure(Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ Attribute invertAttribute = element.attribute(AuditModel.AT_INVERT);
+ if (invertAttribute != null)
+ {
+ invert = Boolean.valueOf(invertAttribute.getStringValue()).booleanValue();
+ }
+ else
+ {
+ invert = false;
+ }
+ }
+
+ /* package */boolean isInvert()
+ {
+ return invert;
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/model/AbstractNamedAuditEntry.java b/source/java/org/alfresco/repo/audit/model/AbstractNamedAuditEntry.java
new file mode 100644
index 0000000000..aa200227ab
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/AbstractNamedAuditEntry.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+
+public abstract class AbstractNamedAuditEntry extends AbstractAuditEntry
+{
+ private static Log s_logger = LogFactory.getLog(AbstractNamedAuditEntry.class);
+
+ private String name;
+
+ public AbstractNamedAuditEntry()
+ {
+ super();
+ }
+
+ @Override
+ void configure(AbstractAuditEntry parent, Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ Attribute nameAttribute = element.attribute(AuditModel.AT_NAME);
+ if (nameAttribute != null)
+ {
+ name = nameAttribute.getStringValue();
+ }
+ else
+ {
+ throw new AuditModelException("The name attribute is mandatory");
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Name = "+name);
+ }
+
+ super.configure(parent, element, namespacePrefixResolver);
+
+ }
+
+ /* package */String getName()
+ {
+ return name;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/ApplicationAuditEntry.java b/source/java/org/alfresco/repo/audit/model/ApplicationAuditEntry.java
new file mode 100644
index 0000000000..fb67f825b2
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/ApplicationAuditEntry.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.ApplicationAuditModel;
+import org.alfresco.repo.audit.AuditMode;
+import org.alfresco.repo.audit.RecordOptions;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class ApplicationAuditEntry extends AbstractNamedAuditEntry implements ApplicationAuditModel
+{
+ private static Log s_logger = LogFactory.getLog(ApplicationAuditEntry.class);
+
+ public ApplicationAuditEntry()
+ {
+ super();
+ }
+
+ public AuditMode beforeExecution(AuditMode auditMode, String application, String description, NodeRef key, Object... args)
+ {
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Evaluating if application is audited ..."+application);
+ }
+ return getEffectiveAuditMode();
+ }
+
+ public AuditMode afterExecution(AuditMode auditMode, String application, String description, NodeRef key, Object... args)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public AuditMode onError(AuditMode auditMode, String application, String description, NodeRef key, Object... args)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public RecordOptions getAuditRecordOptions(String application)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/AuditEntry.java b/source/java/org/alfresco/repo/audit/model/AuditEntry.java
new file mode 100644
index 0000000000..68678d200c
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/AuditEntry.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.alfresco.repo.audit.AuditConfiguration;
+import org.alfresco.repo.audit.AuditMode;
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.repo.audit.RecordOptions;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.InitializingBean;
+
+public class AuditEntry extends AbstractAuditEntry implements InitializingBean, AuditModel
+{
+ private static Log s_logger = LogFactory.getLog(AuditEntry.class);
+
+ private Map services = new HashMap();
+
+ private Map applications = new HashMap();
+
+ private AuditConfiguration auditConfiguration;
+
+ private NamespacePrefixResolver namespacePrefixResolver;
+
+ public AuditEntry()
+ {
+ super();
+ }
+
+ public AuditConfiguration getAuditConfiguration()
+ {
+ return auditConfiguration;
+ }
+
+ public void setAuditConfiguration(AuditConfiguration auditConfiguration)
+ {
+ this.auditConfiguration = auditConfiguration;
+ }
+
+ public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
+ {
+ this.namespacePrefixResolver = namespacePrefixResolver;
+ }
+
+ public void afterPropertiesSet() throws Exception
+ {
+ Document document = createDocument();
+ Element root = document.getRootElement();
+ // Check it is the correct thing
+ configure(null, root, namespacePrefixResolver);
+ }
+
+
+
+ @Override
+ void configure(AbstractAuditEntry parent, Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ if (!element.getNamespaceURI().equals(AuditModel.NAME_SPACE))
+ {
+ throw new AuditModelException("Audit model has incorrect name space");
+ }
+ if (!element.getName().equals(AuditModel.EL_AUDIT))
+ {
+ throw new AuditModelException("Audit model has incorrect root node");
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Audit configuration");
+ }
+ super.configure(parent, element, namespacePrefixResolver);
+
+ // Add services
+
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Adding services ...");
+ }
+ for (Iterator nsit = element.elementIterator(AuditModel.EL_SERVICE); nsit.hasNext(); /**/)
+ {
+ Element serviceElement = (Element) nsit.next();
+ ServiceAuditEntry service = new ServiceAuditEntry();
+ service.configure(this, serviceElement, namespacePrefixResolver);
+ services.put(service.getName(), service);
+ }
+
+ // Add Applications
+
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Adding applications ...");
+ }
+ for (Iterator nsit = element.elementIterator(AuditModel.EL_APPLICATION); nsit.hasNext(); /**/)
+ {
+ Element applicationElement = (Element) nsit.next();
+ ApplicationAuditEntry application = new ApplicationAuditEntry();
+ application.configure(this, applicationElement, namespacePrefixResolver);
+ applications.put(application.getName(), application);
+ }
+ }
+
+ public AuditMode beforeExecution(AuditMode auditMode, MethodInvocation mi)
+ {
+ String serviceName = getPublicServiceIdentifier().getPublicServiceName(mi);
+ ServiceAuditEntry service = services.get(serviceName);
+ if(service != null)
+ {
+ return service.beforeExecution(auditMode, mi);
+ }
+ else
+ {
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("No specific audit entry for service "+serviceName);
+ }
+ return getEffectiveAuditMode();
+
+ }
+ }
+
+ public AuditMode afterExecution(AuditMode auditMode, MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public RecordOptions getAuditRecordOptions(MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public AuditMode onError(AuditMode auditMode, MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ private Document createDocument()
+ {
+ InputStream is = auditConfiguration.getInputStream();
+ if (is == null)
+ {
+ throw new AuditModelException("Audit configuration could not be opened");
+ }
+ SAXReader reader = new SAXReader();
+ try
+ {
+ Document document = reader.read(is);
+ is.close();
+ return document;
+ }
+ catch (DocumentException e)
+ {
+ throw new AuditModelException("Failed to create audit model document ", e);
+ }
+ catch (IOException e)
+ {
+ throw new AuditModelException("Failed to close audit model document ", e);
+ }
+
+ }
+
+ public AuditMode beforeExecution(AuditMode auditMode, String application, String description, NodeRef key, Object... args)
+ {
+ ApplicationAuditEntry aae = applications.get(application);
+ if(aae != null)
+ {
+ return aae.beforeExecution(auditMode, application, description, key, args);
+ }
+ else
+ {
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("No specific audit entry for application "+application);
+ }
+ return getEffectiveAuditMode();
+
+ }
+ }
+
+ public AuditMode afterExecution(AuditMode auditMode, String application, String description, NodeRef key, Object... args)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public AuditMode onError(AuditMode auditMode, String application, String description, NodeRef key, Object... args)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public RecordOptions getAuditRecordOptions(String application)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/AuditModelException.java b/source/java/org/alfresco/repo/audit/model/AuditModelException.java
new file mode 100644
index 0000000000..7c72529429
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/AuditModelException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+
+/**
+ * Exceptions from the audit model package.
+ *
+ * @author Andy Hind
+ */
+public class AuditModelException extends AlfrescoRuntimeException
+{
+
+ /**
+ * Comment for serialVersionUID
+ */
+ private static final long serialVersionUID = -2527034441058184109L;
+
+ public AuditModelException(String msgId)
+ {
+ super(msgId);
+ }
+
+ public AuditModelException(String msgId, Object[] msgParams)
+ {
+ super(msgId, msgParams);
+ }
+
+ public AuditModelException(String msgId, Throwable cause)
+ {
+ super(msgId, cause);
+ }
+
+ public AuditModelException(String msgId, Object[] msgParams, Throwable cause)
+ {
+ super(msgId, msgParams, cause);
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/FilterSet.java b/source/java/org/alfresco/repo/audit/model/FilterSet.java
new file mode 100644
index 0000000000..d30b52fb84
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/FilterSet.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+
+/**
+ * This groups a set of filters together using AND or OR. They are evaluated in definition order with short cut evaluation if possible. The default beahviour is to or Filters
+ * together.
+ *
+ * @author Andy Hind
+ */
+public class FilterSet extends AbstractFilter implements XMLModelElement
+{
+ private static Log s_logger = LogFactory.getLog(FilterSet.class);
+
+ private List filters = new ArrayList();
+
+ private FilterSetMode mode = FilterSetMode.OR;
+
+ public FilterSet()
+ {
+ super();
+ }
+
+ @Override
+ public void configure(Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ super.configure(element, namespacePrefixResolver);
+
+ // Mode
+ Attribute modeAttribute = element.attribute(AuditModel.AT_MODE);
+ if (modeAttribute != null)
+ {
+ mode = FilterSetMode.getFilterSetMode(modeAttribute.getStringValue());
+ }
+
+ // Filters
+
+ for (Iterator nsit = element.elementIterator(AuditModel.EL_FILTER); nsit.hasNext(); /**/)
+ {
+ Element filterElement = (Element) nsit.next();
+ AbstractFilter filter = AbstractFilter.createFilter(filterElement, namespacePrefixResolver);
+ filters.add(filter);
+ }
+
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/FilterSetMode.java b/source/java/org/alfresco/repo/audit/model/FilterSetMode.java
new file mode 100644
index 0000000000..57dc90ee63
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/FilterSetMode.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+/**
+ * The enum to define if elements of a filter set are combined using AND or OR.
+ *
+ * @author Andy Hind
+ */
+public enum FilterSetMode
+{
+ AND, OR;
+
+ public static FilterSetMode getFilterSetMode(String value)
+ {
+ if(value.equalsIgnoreCase("or"))
+ {
+ return FilterSetMode.OR;
+ }
+ else if(value.equalsIgnoreCase("or"))
+ {
+ return FilterSetMode.AND;
+ }
+ else
+ {
+ throw new AuditModelException("Invalid FilterSetMode: "+value);
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/model/KeyFilter.java b/source/java/org/alfresco/repo/audit/model/KeyFilter.java
new file mode 100644
index 0000000000..ddacc9f5e9
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/KeyFilter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+
+public class KeyFilter extends AbstractFilter
+{
+ private static Log s_logger = LogFactory.getLog(KeyFilter.class);
+
+ private String expression;
+
+ private KeyFilterMode keyFilterMode;
+
+ public KeyFilter()
+ {
+ super();
+ }
+
+ @Override
+ public void configure(Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ super.configure(element, namespacePrefixResolver);
+
+ // Filter mode
+ Attribute keyFilterTypeAttribute = element.attribute(AuditModel.AT_MODE);
+ if(keyFilterTypeAttribute != null)
+ {
+ keyFilterMode = KeyFilterMode.getKeyFilterMode(keyFilterTypeAttribute.getStringValue());
+ }
+ else
+ {
+ keyFilterMode = KeyFilterMode.ALL;
+ }
+
+ // Expression
+
+ Element expressionElement = element.element(AuditModel.EL_EXPRESSION);
+ if(expressionElement == null)
+ {
+ throw new AuditModelException("An expression is mandatory for a key filter");
+ }
+ else
+ {
+ expression = expressionElement.getText();
+ }
+ }
+
+
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/KeyFilterMode.java b/source/java/org/alfresco/repo/audit/model/KeyFilterMode.java
new file mode 100644
index 0000000000..23ef6d6e39
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/KeyFilterMode.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+/**
+ * This enum defines the type of restriction to apply to filter based on the key node ref.
+ *
+ * This restriction can be based upon:
+ *
+ *
+ * - The path to the node
+ *
- The type of the node
+ *
- The presence of an aspect
+ *
- The NodeRef of the node
+ *
- An XPATH expression evaluated in the context of the node with the return tested for the node.
+ * e.g. ".[@cm:content = 'woof']"
+ *
- A simple value for equality tests given a non node argument
+ *
- The protocol of the store containing the node
+ *
- The identifier of the store containing the node
+ *
- Or no restriction
+ *
+ *
+ * @author Andy Hind
+ */
+public enum KeyFilterMode
+{
+ PATH, TYPE, ASPECT, NODE_REF, ALL, XPATH, VALUE, STORE_PROTOCOL, STORE_IDENTIFIER;
+
+ public static KeyFilterMode getKeyFilterMode(String value)
+ {
+ if(value.equalsIgnoreCase("path"))
+ {
+ return KeyFilterMode.PATH;
+ }
+ else if(value.equalsIgnoreCase("type"))
+ {
+ return KeyFilterMode.TYPE;
+ }
+ else if(value.equalsIgnoreCase("aspect"))
+ {
+ return KeyFilterMode.ASPECT;
+ }
+ else if(value.equalsIgnoreCase("node_ref"))
+ {
+ return KeyFilterMode.NODE_REF;
+ }
+ else if(value.equalsIgnoreCase("all"))
+ {
+ return KeyFilterMode.ALL;
+ }
+ else if(value.equalsIgnoreCase("xpath"))
+ {
+ return KeyFilterMode.XPATH;
+ }
+ else if(value.equalsIgnoreCase("value"))
+ {
+ return KeyFilterMode.VALUE;
+ }
+ else if(value.equalsIgnoreCase("store_protocol"))
+ {
+ return KeyFilterMode.STORE_PROTOCOL;
+ }
+ else if(value.equalsIgnoreCase("store_identifier"))
+ {
+ return KeyFilterMode.STORE_IDENTIFIER;
+ }
+ else
+ {
+ throw new AuditModelException("Unknown KeyFilterMode: "+value);
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/model/MethodAuditEntry.java b/source/java/org/alfresco/repo/audit/model/MethodAuditEntry.java
new file mode 100644
index 0000000000..a59d6b7a72
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/MethodAuditEntry.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditMode;
+import org.alfresco.repo.audit.MethodAuditModel;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class MethodAuditEntry extends AbstractNamedAuditEntry implements MethodAuditModel
+{
+ private static Log s_logger = LogFactory.getLog(MethodAuditEntry.class);
+
+ public MethodAuditEntry()
+ {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public AuditMode beforeExecution(AuditMode auditMode, MethodInvocation mi)
+ {
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Evaluating if method is audited ..."+((ServiceAuditEntry)getParent()).getName()+"."+getName());
+ }
+ return getEffectiveAuditMode();
+ }
+
+ public AuditMode afterExecution(AuditMode auditMode, MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public AuditMode onError(AuditMode auditMode, MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public RecordOptionsImpl getAuditRecordOptions(MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/ParameterFilter.java b/source/java/org/alfresco/repo/audit/model/ParameterFilter.java
new file mode 100644
index 0000000000..6bfe56d70a
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/ParameterFilter.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.alfresco.service.namespace.QName;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Element;
+
+public class ParameterFilter extends KeyFilter implements XMLModelElement
+{
+ private static Log s_logger = LogFactory.getLog(ParameterFilter.class);
+
+ private QName parameterName;
+
+ public ParameterFilter()
+ {
+ super();
+ }
+
+ @Override
+ public void configure(Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ super.configure(element, namespacePrefixResolver);
+
+ Element parameterNameElement = element.element(AuditModel.EL_PARAMETER_NAME);
+ if(parameterNameElement == null)
+ {
+ throw new AuditModelException("A parameter is mandatory for a parameter filter");
+ }
+ else
+ {
+ String stringQName = parameterNameElement.getStringValue();
+ if (stringQName.charAt(1) == '{')
+ {
+ parameterName = QName.createQName(stringQName);
+ }
+ else
+ {
+ parameterName = QName.createQName(stringQName);
+ }
+ }
+ }
+
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/RecordOptionsImpl.java b/source/java/org/alfresco/repo/audit/model/RecordOptionsImpl.java
new file mode 100644
index 0000000000..5b9de6ec7a
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/RecordOptionsImpl.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.repo.audit.RecordOptions;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Element;
+
+public class RecordOptionsImpl implements XMLModelElement, RecordOptions
+{
+ private static Log s_logger = LogFactory.getLog(RecordOptionsImpl.class);
+
+ private TrueFalseUnset recordPath = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset recordFilters = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset recordSerializedReturnValue = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset recordSerializedExceptions = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset recordSerializedMethodArguments = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset recordSerializedKeyPropertiesBeforeEvaluation = TrueFalseUnset.UNSET;
+
+ private TrueFalseUnset recordSerializedKeyPropertiesAfterEvaluation = TrueFalseUnset.UNSET;
+
+ public RecordOptionsImpl()
+ {
+ super();
+ }
+
+ public static RecordOptionsImpl mergeRecordOptions(RecordOptions primary, RecordOptions secondary)
+ {
+ RecordOptionsImpl answer = new RecordOptionsImpl();
+ setOptions(answer, primary, true);
+ setOptions(answer, secondary, false);
+ return answer;
+ }
+
+ private static void setOptions(RecordOptionsImpl on, RecordOptions from, boolean force)
+ {
+ if(force || on.recordFilters.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordFilters = from.getRecordFilters();
+ }
+ if(force || on.recordPath.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordPath = from.getRecordPath();
+ }
+ if(force || on.recordSerializedExceptions.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordSerializedExceptions = from.getRecordSerializedExceptions();
+ }
+ if(force || on.recordSerializedKeyPropertiesAfterEvaluation.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordSerializedKeyPropertiesAfterEvaluation = from.getRecordSerializedKeyPropertiesAfterEvaluation();
+ }
+ if(force || on.recordSerializedKeyPropertiesBeforeEvaluation.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordSerializedKeyPropertiesBeforeEvaluation = from.getRecordSerializedKeyPropertiesBeforeEvaluation();
+ }
+ if(force || on.recordSerializedMethodArguments.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordSerializedMethodArguments = from.getRecordSerializedMethodArguments();
+ }
+ if(force || on.recordSerializedReturnValue.equals( TrueFalseUnset.UNSET))
+ {
+ on.recordSerializedReturnValue = from.getRecordSerializedReturnValue();
+ }
+ }
+
+ public TrueFalseUnset getRecordFilters()
+ {
+ return recordFilters;
+ }
+
+ public TrueFalseUnset getRecordPath()
+ {
+ return recordPath;
+ }
+
+ public TrueFalseUnset getRecordSerializedExceptions()
+ {
+ return recordSerializedExceptions;
+ }
+
+ public TrueFalseUnset getRecordSerializedKeyPropertiesAfterEvaluation()
+ {
+ return recordSerializedKeyPropertiesAfterEvaluation;
+ }
+
+ public TrueFalseUnset getRecordSerializedKeyPropertiesBeforeEvaluation()
+ {
+ return recordSerializedKeyPropertiesBeforeEvaluation;
+ }
+
+ public TrueFalseUnset getRecordSerializedMethodArguments()
+ {
+ return recordSerializedMethodArguments;
+ }
+
+ public TrueFalseUnset getRecordSerializedReturnValue()
+ {
+ return recordSerializedReturnValue;
+ }
+
+ public void configure(Element recordOptionElement, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ Element recordFiltersElement = recordOptionElement.element(AuditModel.EL_RECORD_FILTERS);
+ if (recordFiltersElement != null)
+ {
+ recordFilters = TrueFalseUnset.getTrueFalseUnset(recordFiltersElement.getStringValue());
+ }
+
+ Element recordPathElement = recordOptionElement.element(AuditModel.EL_RECORD_PATH);
+ if (recordPathElement != null)
+ {
+ recordPath = TrueFalseUnset.getTrueFalseUnset(recordPathElement.getStringValue());
+ }
+
+ Element recordSerAgrsElement = recordOptionElement.element(AuditModel.EL_RECORD_SER_ARGS);
+ if (recordSerAgrsElement != null)
+ {
+ recordSerializedMethodArguments = TrueFalseUnset.getTrueFalseUnset(recordSerAgrsElement.getStringValue());
+ }
+
+ Element recordSerExElement = recordOptionElement.element(AuditModel.EL_RECORD_SER_EX);
+ if (recordSerExElement != null)
+ {
+ recordSerializedExceptions = TrueFalseUnset.getTrueFalseUnset(recordSerExElement.getStringValue());
+ }
+
+ Element recordSerPropAfterElement = recordOptionElement.element(AuditModel.EL_RECORD_SER_PROP_AFTER);
+ if (recordSerPropAfterElement != null)
+ {
+ recordSerializedKeyPropertiesAfterEvaluation = TrueFalseUnset.getTrueFalseUnset(recordSerPropAfterElement
+ .getStringValue());
+ }
+
+ Element recordSerPropBeforeElement = recordOptionElement.element(AuditModel.EL_RECORD_SER_PROP_BEFORE);
+ if (recordSerPropBeforeElement != null)
+ {
+ recordSerializedKeyPropertiesBeforeEvaluation = TrueFalseUnset.getTrueFalseUnset(recordSerPropBeforeElement
+ .getStringValue());
+ }
+
+ Element recordSerRetElement = recordOptionElement.element(AuditModel.EL_RECORD_SER_RETURN_VAL);
+ if (recordSerRetElement != null)
+ {
+ recordSerializedReturnValue = TrueFalseUnset.getTrueFalseUnset(recordSerRetElement.getStringValue());
+ }
+
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Record Options(");
+ builder.append("Filters=").append(getRecordFilters());
+ builder.append(",Path=").append(getRecordPath());
+ builder.append(",Exception=").append(getRecordSerializedExceptions());
+ builder.append(",PropertiesBefore=").append(getRecordSerializedKeyPropertiesAfterEvaluation());
+ builder.append(",PropertiesAfter=").append(getRecordSerializedKeyPropertiesBeforeEvaluation());
+ builder.append(",Args=").append(getRecordSerializedMethodArguments());
+ builder.append(",Return=").append(getRecordSerializedReturnValue());
+ builder.append(")");
+ return builder.toString();
+ }
+
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/ServiceAuditEntry.java b/source/java/org/alfresco/repo/audit/model/ServiceAuditEntry.java
new file mode 100644
index 0000000000..764f004044
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/ServiceAuditEntry.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.alfresco.repo.audit.AuditMode;
+import org.alfresco.repo.audit.AuditModel;
+import org.alfresco.repo.audit.MethodAuditModel;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Element;
+
+public class ServiceAuditEntry extends AbstractNamedAuditEntry implements MethodAuditModel
+{
+ private static Log s_logger = LogFactory.getLog(ServiceAuditEntry.class);
+
+ private Map methods = new HashMap();
+
+ public ServiceAuditEntry()
+ {
+ super();
+ }
+
+ @Override
+ void configure(AbstractAuditEntry parent, Element element, NamespacePrefixResolver namespacePrefixResolver)
+ {
+ super.configure(parent, element, namespacePrefixResolver);
+
+ // Add Methods
+
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Adding methods to service "+getName());
+ }
+ for (Iterator nsit = element.elementIterator(AuditModel.EL_METHOD); nsit.hasNext(); /**/)
+ {
+ Element methodElement = (Element) nsit.next();
+ MethodAuditEntry method = new MethodAuditEntry();
+ method.configure(this, methodElement, namespacePrefixResolver);
+ methods.put(method.getName(), method);
+ }
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("...added methods for service "+getName());
+ }
+ }
+
+ public AuditMode beforeExecution(AuditMode auditMode, MethodInvocation mi)
+ {
+ String methodName = mi.getMethod().getName();
+ MethodAuditEntry method = methods.get(methodName);
+ if (method != null)
+ {
+ return method.beforeExecution(auditMode, mi);
+ }
+ else
+ {
+ if(s_logger.isDebugEnabled())
+ {
+ s_logger.debug("Evaluating if service is audited (no specific setting) for "+getName()+"."+methodName);
+ }
+ return getEffectiveAuditMode();
+ }
+ }
+
+ public AuditMode afterExecution(AuditMode auditMode, MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public AuditMode onError(AuditMode auditMode, MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public RecordOptionsImpl getAuditRecordOptions(MethodInvocation mi)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/audit/model/TrueFalseUnset.java b/source/java/org/alfresco/repo/audit/model/TrueFalseUnset.java
new file mode 100644
index 0000000000..6f2eb54368
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/TrueFalseUnset.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+/**
+ * An enum for the values
+ *
+ * - TRUE
+ *
- FALSE
+ *
- UNSET
+ *
+ *
+ * @author Andy Hind
+ */
+public enum TrueFalseUnset
+{
+ TRUE, FALSE, UNSET;
+
+ public static TrueFalseUnset getTrueFalseUnset(String value)
+ {
+ if(value.equalsIgnoreCase("true"))
+ {
+ return TrueFalseUnset.TRUE;
+ }
+ else if(value.equalsIgnoreCase("false"))
+ {
+ return TrueFalseUnset.FALSE;
+ }
+ else if(value.equalsIgnoreCase("unset"))
+ {
+ return TrueFalseUnset.UNSET;
+ }
+ else
+ {
+ throw new AuditModelException("Invalid value for TrueFalseUnset: "+value);
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/audit/model/XMLModelElement.java b/source/java/org/alfresco/repo/audit/model/XMLModelElement.java
new file mode 100644
index 0000000000..11c3293232
--- /dev/null
+++ b/source/java/org/alfresco/repo/audit/model/XMLModelElement.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.audit.model;
+
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.dom4j.Element;
+
+public interface XMLModelElement
+{
+ void configure(Element element, NamespacePrefixResolver namespacePrefixResolver );
+}
diff --git a/source/java/org/alfresco/service/AnnotationTestInterface.java b/source/java/org/alfresco/service/AnnotationTestInterface.java
index 495e8c12bb..1d6eb34cc5 100644
--- a/source/java/org/alfresco/service/AnnotationTestInterface.java
+++ b/source/java/org/alfresco/service/AnnotationTestInterface.java
@@ -21,6 +21,7 @@ package org.alfresco.service;
*
* @author Andy Hind
*/
+@PublicService
public interface AnnotationTestInterface
{
@Auditable()
diff --git a/source/java/org/alfresco/service/PublicService.java b/source/java/org/alfresco/service/PublicService.java
new file mode 100644
index 0000000000..7fc7359cda
--- /dev/null
+++ b/source/java/org/alfresco/service/PublicService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.service;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifically indicate that an interface defines a public service.
+ *
+ * This is a marker annotation.
+ *
+ * @author Andy Hind
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PublicService
+{
+
+}
diff --git a/source/java/org/alfresco/service/ServiceRegistry.java b/source/java/org/alfresco/service/ServiceRegistry.java
index 3fc80541da..7e893e3789 100644
--- a/source/java/org/alfresco/service/ServiceRegistry.java
+++ b/source/java/org/alfresco/service/ServiceRegistry.java
@@ -52,6 +52,7 @@ import org.alfresco.service.transaction.TransactionService;
*
* @author David Caruana
*/
+@PublicService
public interface ServiceRegistry
{
// Service Bean Names
diff --git a/source/java/org/alfresco/service/cmr/action/ActionService.java b/source/java/org/alfresco/service/cmr/action/ActionService.java
index cbfe96ccfd..171051fc94 100644
--- a/source/java/org/alfresco/service/cmr/action/ActionService.java
+++ b/source/java/org/alfresco/service/cmr/action/ActionService.java
@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
/**
@@ -28,6 +29,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
*
* @author Roy Wetherall
*/
+@PublicService
public interface ActionService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/admin/AdminService.java b/source/java/org/alfresco/service/cmr/admin/AdminService.java
index f9ca1e90d7..fdbbb262b5 100644
--- a/source/java/org/alfresco/service/cmr/admin/AdminService.java
+++ b/source/java/org/alfresco/service/cmr/admin/AdminService.java
@@ -18,12 +18,15 @@ package org.alfresco.service.cmr.admin;
import java.util.List;
+import org.alfresco.service.PublicService;
+
/**
* General administration tasks and system information.
*
* @since 1.2
* @author Derek Hulley
*/
+@PublicService
public interface AdminService
{
// public List getPatches();
diff --git a/source/java/org/alfresco/service/cmr/audit/AuditService.java b/source/java/org/alfresco/service/cmr/audit/AuditService.java
new file mode 100644
index 0000000000..8ad7456d87
--- /dev/null
+++ b/source/java/org/alfresco/service/cmr/audit/AuditService.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.service.cmr.audit;
+
+import org.alfresco.service.NotAuditable;
+import org.alfresco.service.PublicService;
+import org.alfresco.service.cmr.repository.NodeRef;
+
+/**
+ * The public API by which applications can create audit entries.
+ * This does not affect auditing using method interceptors.
+ * The information recorded can not be confused between the two.
+ *
+ * This API could be used by an audit action.
+ *
+ * @author Andy Hind
+ */
+@PublicService
+public interface AuditService
+{
+
+ /**
+ * Add an application audit entry.
+ *
+ * @param source -
+ * a string that represents the application
+ * @param description -
+ * the audit entry
+ */
+ @NotAuditable
+ public void audit(String source, String description);
+
+ /**
+ *
+ * @param source -
+ * a string that represents the application
+ * @param description -
+ * the audit entry
+ * @param key -
+ * a node ref to use as the key for filtering etc
+ */
+ @NotAuditable
+ public void audit(String source, String description, NodeRef key);
+
+ /**
+ *
+ * @param source -
+ * a string that represents the application
+ * @param description -
+ * the audit entry
+ * @param args -
+ * an arbitrary list of parameters
+ */
+ @NotAuditable
+ public void audit(String source, String description, Object... args);
+
+ /**
+ *
+ * @param source -
+ * a string that represents the application
+ * @param description -
+ * the audit entry *
+ * @param key -
+ * a node ref to use as the key for filtering etc
+ * @param args -
+ * an arbitrary list of parameters
+ */
+ @NotAuditable
+ public void audit(String source, String description, NodeRef key, Object... args);
+
+}
diff --git a/source/java/org/alfresco/service/cmr/coci/CheckOutCheckInService.java b/source/java/org/alfresco/service/cmr/coci/CheckOutCheckInService.java
index 64b58437fd..c6549ae507 100644
--- a/source/java/org/alfresco/service/cmr/coci/CheckOutCheckInService.java
+++ b/source/java/org/alfresco/service/cmr/coci/CheckOutCheckInService.java
@@ -20,6 +20,7 @@ import java.io.Serializable;
import java.util.Map;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -29,6 +30,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Roy Wetherall
*/
+@PublicService
public interface CheckOutCheckInService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java b/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java
index b939d3c72f..33053ed4cb 100644
--- a/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java
+++ b/source/java/org/alfresco/service/cmr/dictionary/DictionaryService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.dictionary;
import java.util.Collection;
import org.alfresco.service.NotAuditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.namespace.QName;
@@ -35,6 +36,7 @@ import org.alfresco.service.namespace.QName;
*
* @author David Caruana
*/
+@PublicService
public interface DictionaryService
{
diff --git a/source/java/org/alfresco/service/cmr/lock/LockService.java b/source/java/org/alfresco/service/cmr/lock/LockService.java
index 7687e2b072..fdab4e49e9 100644
--- a/source/java/org/alfresco/service/cmr/lock/LockService.java
+++ b/source/java/org/alfresco/service/cmr/lock/LockService.java
@@ -20,6 +20,7 @@ import java.util.Collection;
import java.util.List;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -29,6 +30,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
*
* @author Roy Wetherall
*/
+@PublicService
public interface LockService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/model/FileFolderService.java b/source/java/org/alfresco/service/cmr/model/FileFolderService.java
index 2b939f4fe2..6dcbfbd4bf 100644
--- a/source/java/org/alfresco/service/cmr/model/FileFolderService.java
+++ b/source/java/org/alfresco/service/cmr/model/FileFolderService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.model;
import java.util.List;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -32,6 +33,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Derek Hulley
*/
+@PublicService
public interface FileFolderService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/repository/ContentService.java b/source/java/org/alfresco/service/cmr/repository/ContentService.java
index c1c032a6ab..f13f66192e 100644
--- a/source/java/org/alfresco/service/cmr/repository/ContentService.java
+++ b/source/java/org/alfresco/service/cmr/repository/ContentService.java
@@ -18,6 +18,7 @@ package org.alfresco.service.cmr.repository;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.namespace.QName;
@@ -42,6 +43,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Derek Hulley
*/
+@PublicService
public interface ContentService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/repository/CopyService.java b/source/java/org/alfresco/service/cmr/repository/CopyService.java
index 62e365d10f..801071df37 100644
--- a/source/java/org/alfresco/service/cmr/repository/CopyService.java
+++ b/source/java/org/alfresco/service/cmr/repository/CopyService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.repository;
import java.util.List;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.namespace.QName;
/**
@@ -29,6 +30,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Roy Wetherall
*/
+@PublicService
public interface CopyService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/repository/MimetypeService.java b/source/java/org/alfresco/service/cmr/repository/MimetypeService.java
index 6475373993..9f5d791d86 100644
--- a/source/java/org/alfresco/service/cmr/repository/MimetypeService.java
+++ b/source/java/org/alfresco/service/cmr/repository/MimetypeService.java
@@ -21,6 +21,7 @@ import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.NotAuditable;
+import org.alfresco.service.PublicService;
/**
@@ -29,6 +30,7 @@ import org.alfresco.service.NotAuditable;
* @author Derek Hulley
*
*/
+@PublicService
public interface MimetypeService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/repository/NodeService.java b/source/java/org/alfresco/service/cmr/repository/NodeService.java
index 96b192cf52..130e67f4ab 100644
--- a/source/java/org/alfresco/service/cmr/repository/NodeService.java
+++ b/source/java/org/alfresco/service/cmr/repository/NodeService.java
@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.namespace.QName;
@@ -32,6 +33,7 @@ import org.alfresco.service.namespace.QNamePattern;
*
* @author Derek Hulley
*/
+@PublicService
public interface NodeService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/repository/ScriptService.java b/source/java/org/alfresco/service/cmr/repository/ScriptService.java
index 3c6b9dcc88..ad742600f5 100644
--- a/source/java/org/alfresco/service/cmr/repository/ScriptService.java
+++ b/source/java/org/alfresco/service/cmr/repository/ScriptService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.repository;
import java.util.Map;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.namespace.QName;
/**
@@ -36,6 +37,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Kevin Roast
*/
+@PublicService
public interface ScriptService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/repository/TemplateService.java b/source/java/org/alfresco/service/cmr/repository/TemplateService.java
index 5ba59bba24..55a4824f2e 100644
--- a/source/java/org/alfresco/service/cmr/repository/TemplateService.java
+++ b/source/java/org/alfresco/service/cmr/repository/TemplateService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.repository;
import java.io.Writer;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
/**
* Template Service.
@@ -34,6 +35,7 @@ import org.alfresco.service.Auditable;
*
* @author Kevin Roast
*/
+@PublicService
public interface TemplateService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/rule/RuleService.java b/source/java/org/alfresco/service/cmr/rule/RuleService.java
index f14c871ee0..09ecd3b6af 100644
--- a/source/java/org/alfresco/service/cmr/rule/RuleService.java
+++ b/source/java/org/alfresco/service/cmr/rule/RuleService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.rule;
import java.util.List;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -27,6 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
*
* @author Roy Wetherall
*/
+@PublicService
public interface RuleService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/search/CategoryService.java b/source/java/org/alfresco/service/cmr/search/CategoryService.java
index 7651b93f19..2f07a53a37 100644
--- a/source/java/org/alfresco/service/cmr/search/CategoryService.java
+++ b/source/java/org/alfresco/service/cmr/search/CategoryService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.search;
import java.util.Collection;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -37,6 +38,7 @@ import org.alfresco.service.namespace.QName;
* @author Andy Hind
*
*/
+@PublicService
public interface CategoryService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/search/SearchService.java b/source/java/org/alfresco/service/cmr/search/SearchService.java
index 9f5a90998e..8387c4ff44 100644
--- a/source/java/org/alfresco/service/cmr/search/SearchService.java
+++ b/source/java/org/alfresco/service/cmr/search/SearchService.java
@@ -20,6 +20,7 @@ import java.io.Serializable;
import java.util.List;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
@@ -38,6 +39,7 @@ import org.alfresco.service.namespace.QName;
* @author Andy hind
*
*/
+@PublicService
public interface SearchService
{
public static final String LANGUAGE_LUCENE = "lucene";
diff --git a/source/java/org/alfresco/service/cmr/security/AuthenticationService.java b/source/java/org/alfresco/service/cmr/security/AuthenticationService.java
index 65420fe4bb..de4177e5e6 100644
--- a/source/java/org/alfresco/service/cmr/security/AuthenticationService.java
+++ b/source/java/org/alfresco/service/cmr/security/AuthenticationService.java
@@ -20,6 +20,7 @@ import java.util.Set;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
/**
* The authentication service defines the API for managing authentication information
@@ -28,6 +29,7 @@ import org.alfresco.service.Auditable;
* @author Andy Hind
*
*/
+@PublicService
public interface AuthenticationService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/security/AuthorityService.java b/source/java/org/alfresco/service/cmr/security/AuthorityService.java
index 0febd7b08d..5cf6172715 100644
--- a/source/java/org/alfresco/service/cmr/security/AuthorityService.java
+++ b/source/java/org/alfresco/service/cmr/security/AuthorityService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.security;
import java.util.Set;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
/**
* The service that encapsulates authorities granted to users.
@@ -34,6 +35,7 @@ import org.alfresco.service.Auditable;
*
* @author Andy Hind
*/
+@PublicService
public interface AuthorityService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/security/OwnableService.java b/source/java/org/alfresco/service/cmr/security/OwnableService.java
index 1c77740e86..6bdc685062 100644
--- a/source/java/org/alfresco/service/cmr/security/OwnableService.java
+++ b/source/java/org/alfresco/service/cmr/security/OwnableService.java
@@ -17,6 +17,7 @@
package org.alfresco.service.cmr.security;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
/**
@@ -24,6 +25,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
*
* @author Andy Hind
*/
+@PublicService
public interface OwnableService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/security/PermissionService.java b/source/java/org/alfresco/service/cmr/security/PermissionService.java
index ea772ca324..6a4f385774 100644
--- a/source/java/org/alfresco/service/cmr/security/PermissionService.java
+++ b/source/java/org/alfresco/service/cmr/security/PermissionService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.security;
import java.util.Set;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -29,6 +30,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Andy Hind
*/
+@PublicService
public interface PermissionService
{
public static final String ROLE_PREFIX = "ROLE_";
diff --git a/source/java/org/alfresco/service/cmr/security/PersonService.java b/source/java/org/alfresco/service/cmr/security/PersonService.java
index c985085742..2f7665c41d 100644
--- a/source/java/org/alfresco/service/cmr/security/PersonService.java
+++ b/source/java/org/alfresco/service/cmr/security/PersonService.java
@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -36,6 +37,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Andy Hind
*/
+@PublicService
public interface PersonService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/version/VersionService.java b/source/java/org/alfresco/service/cmr/version/VersionService.java
index 07baf95e42..b9fb010268 100644
--- a/source/java/org/alfresco/service/cmr/version/VersionService.java
+++ b/source/java/org/alfresco/service/cmr/version/VersionService.java
@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Map;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.AspectMissingException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -31,6 +32,7 @@ import org.alfresco.service.namespace.QName;
*
* @author Roy Wetherall
*/
+@PublicService
public interface VersionService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/view/ExporterService.java b/source/java/org/alfresco/service/cmr/view/ExporterService.java
index 9c91198d75..6a8f7c1437 100644
--- a/source/java/org/alfresco/service/cmr/view/ExporterService.java
+++ b/source/java/org/alfresco/service/cmr/view/ExporterService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.view;
import java.io.OutputStream;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
/**
@@ -26,6 +27,7 @@ import org.alfresco.service.Auditable;
*
* @author David Caruana
*/
+@PublicService
public interface ExporterService
{
/**
diff --git a/source/java/org/alfresco/service/cmr/view/ImporterService.java b/source/java/org/alfresco/service/cmr/view/ImporterService.java
index 5c9e22c6db..f0d3e0faaf 100644
--- a/source/java/org/alfresco/service/cmr/view/ImporterService.java
+++ b/source/java/org/alfresco/service/cmr/view/ImporterService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.view;
import java.io.Reader;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
/**
@@ -27,6 +28,7 @@ import org.alfresco.service.Auditable;
* @author David Caruana
*
*/
+@PublicService
public interface ImporterService
{
diff --git a/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java b/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java
index ab027f3013..3d13b38873 100644
--- a/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java
+++ b/source/java/org/alfresco/service/cmr/view/RepositoryExporterService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.cmr.view;
import java.io.File;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -28,6 +29,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
*
* @author davidc
*/
+@PublicService
public interface RepositoryExporterService
{
diff --git a/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java b/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
index fe46a1c143..d1c22d461d 100644
--- a/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
+++ b/source/java/org/alfresco/service/cmr/workflow/WorkflowService.java
@@ -21,6 +21,8 @@ import java.io.Serializable;
import java.util.List;
import java.util.Map;
+import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -32,6 +34,7 @@ import org.alfresco.service.namespace.QName;
*
* @author davidc
*/
+@PublicService
public interface WorkflowService
{
//
@@ -46,6 +49,7 @@ public interface WorkflowService
* @param mimetype the mimetype of the workflow definition
* @return workflow deployment descriptor
*/
+ @Auditable(parameters = {"engineId", "workflowDefinition", "mimetype"})
public WorkflowDeployment deployDefinition(String engineId, InputStream workflowDefinition, String mimetype);
/**
@@ -57,6 +61,7 @@ public interface WorkflowService
* @param workflowDefinition the content object containing the definition
* @return workflow deployment descriptor
*/
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"workflowDefinition"})
public WorkflowDeployment deployDefinition(NodeRef workflowDefinition);
/**
@@ -70,6 +75,7 @@ public interface WorkflowService
* @param mimetype the mimetype of the definition
* @return true => already deployed
*/
+ @Auditable(parameters = {"engineId", "workflowDefinition", "mimetype"})
public boolean isDefinitionDeployed(String engineId, InputStream workflowDefinition, String mimetype);
/**
@@ -79,6 +85,7 @@ public interface WorkflowService
*
* @param workflowDefinitionId the id of the definition to undeploy
*/
+ @Auditable(parameters = {"workflowDefinitionId"})
public void undeployDefinition(String workflowDefinitionId);
/**
@@ -86,6 +93,7 @@ public interface WorkflowService
*
* @return the deployed workflow definitions
*/
+ @Auditable
public List getDefinitions();
/**
@@ -94,6 +102,7 @@ public interface WorkflowService
* @param workflowDefinitionId the workflow definition id
* @return the deployed workflow definition
*/
+ @Auditable(parameters = {"workflowDefinitionId"})
public WorkflowDefinition getDefinitionById(String workflowDefinitionId);
/**
@@ -117,6 +126,7 @@ public interface WorkflowService
* @param parameters the initial set of parameters used to populate the "Start Task" properties
* @return the initial workflow path
*/
+ @Auditable(parameters = {"workflowDefinitionId", "parameters"})
public WorkflowPath startWorkflow(String workflowDefinitionId, Map parameters);
/**
@@ -126,6 +136,7 @@ public interface WorkflowService
* @param templateDefinition the node representing the Start Task properties
* @return the initial workflow path
*/
+ @Auditable(parameters = {"templateDefinition"})
public WorkflowPath startWorkflowFromTemplate(NodeRef templateDefinition);
/**
@@ -134,6 +145,7 @@ public interface WorkflowService
* @param workflowDefinitionId the workflow definition id
* @return the list of "in-fligth" workflow instances
*/
+ @Auditable(parameters = {"workflowDefinitionId"})
public List getActiveWorkflows(String workflowDefinitionId);
/**
@@ -142,6 +154,7 @@ public interface WorkflowService
* @param workflowId workflow instance id
* @return the list of workflow paths
*/
+ @Auditable(parameters = {"workflowId"})
public List getWorkflowPaths(String workflowId);
/**
@@ -150,6 +163,7 @@ public interface WorkflowService
* @param workflowId the workflow instance to cancel
* @return an updated representation of the workflow instance
*/
+ @Auditable(parameters = {"workflowId"})
public WorkflowInstance cancelWorkflow(String workflowId);
/**
@@ -159,6 +173,7 @@ public interface WorkflowService
* @param transition the transition to follow (or null, for the default transition)
* @return the updated workflow path
*/
+ @Auditable(parameters = {"pathId", "transitionId"})
public WorkflowPath signal(String pathId, String transitionId);
/**
@@ -167,6 +182,7 @@ public interface WorkflowService
* @param pathId the path id
* @return the list of associated tasks
*/
+ @Auditable(parameters = {"pathId"})
public List getTasksForWorkflowPath(String pathId);
@@ -180,6 +196,7 @@ public interface WorkflowService
* @param taskId the task id
* @return the task
*/
+ @Auditable(parameters = {"taskId"})
public WorkflowTask getTaskById(String taskId);
/**
@@ -189,6 +206,7 @@ public interface WorkflowService
* @param state filter by specified workflow task state
* @return the list of assigned tasks
*/
+ @Auditable(parameters = {"authority", "state"})
public List getAssignedTasks(String authority, WorkflowTaskState state);
/**
@@ -197,6 +215,7 @@ public interface WorkflowService
* @param authority the authority
* @return the list of pooled tasks
*/
+ @Auditable(parameters = {"authority"})
public List getPooledTasks(String authority);
/**
@@ -208,6 +227,7 @@ public interface WorkflowService
* @param remove the map of items to dis-associate with the task (or null, if none to remove)
* @return the update task
*/
+ @Auditable(parameters = {"taskId", "properties", "add", "remove"})
public WorkflowTask updateTask(String taskId, Map properties, Map> add, Map> remove);
/**
@@ -217,6 +237,7 @@ public interface WorkflowService
* @param transition the task transition to take on completion (or null, for the default transition)
* @return the updated task
*/
+ @Auditable(parameters = {"taskId", "transitionId"})
public WorkflowTask endTask(String taskId, String transitionId);
/**
@@ -227,6 +248,7 @@ public interface WorkflowService
* @param container (optional) a pre-created container (e.g. folder, versioned folder or layered folder)
* @return the workflow package
*/
+ @Auditable(key = Auditable.Key.ARG_0, parameters = {"container"})
public NodeRef createPackage(NodeRef container);
}
diff --git a/source/java/org/alfresco/service/descriptor/DescriptorService.java b/source/java/org/alfresco/service/descriptor/DescriptorService.java
index 75c3af7be7..148f292706 100644
--- a/source/java/org/alfresco/service/descriptor/DescriptorService.java
+++ b/source/java/org/alfresco/service/descriptor/DescriptorService.java
@@ -26,6 +26,7 @@ import org.alfresco.service.license.LicenseDescriptor;
* @author David Caruana
*
*/
+// This is not a public service in the normal sense
public interface DescriptorService
{
/**
diff --git a/source/java/org/alfresco/service/license/LicenseService.java b/source/java/org/alfresco/service/license/LicenseService.java
index f325ac73c5..15cdaf405e 100644
--- a/source/java/org/alfresco/service/license/LicenseService.java
+++ b/source/java/org/alfresco/service/license/LicenseService.java
@@ -17,6 +17,7 @@
package org.alfresco.service.license;
import org.alfresco.service.NotAuditable;
+import org.alfresco.service.PublicService;
/**
@@ -24,6 +25,7 @@ import org.alfresco.service.NotAuditable;
*
* @author davidc
*/
+@PublicService
public interface LicenseService
{
diff --git a/source/java/org/alfresco/service/namespace/NamespacePrefixResolver.java b/source/java/org/alfresco/service/namespace/NamespacePrefixResolver.java
index ea94b5e3d3..ee460349f3 100644
--- a/source/java/org/alfresco/service/namespace/NamespacePrefixResolver.java
+++ b/source/java/org/alfresco/service/namespace/NamespacePrefixResolver.java
@@ -19,6 +19,7 @@ package org.alfresco.service.namespace;
import java.util.Collection;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
/**
* The NamespacePrefixResolver
provides a mapping between
@@ -26,6 +27,7 @@ import org.alfresco.service.Auditable;
*
* @author David Caruana
*/
+@PublicService
public interface NamespacePrefixResolver
{
/**
diff --git a/source/java/org/alfresco/service/namespace/NamespaceService.java b/source/java/org/alfresco/service/namespace/NamespaceService.java
index 2d2cf70c32..7bac210a62 100644
--- a/source/java/org/alfresco/service/namespace/NamespaceService.java
+++ b/source/java/org/alfresco/service/namespace/NamespaceService.java
@@ -17,6 +17,7 @@
package org.alfresco.service.namespace;
import org.alfresco.service.Auditable;
+import org.alfresco.service.PublicService;
@@ -28,6 +29,7 @@ import org.alfresco.service.Auditable;
*
* @author David Caruana
*/
+@PublicService
public interface NamespaceService extends NamespacePrefixResolver
{
/** Default Namespace URI */
diff --git a/source/java/org/alfresco/service/transaction/TransactionService.java b/source/java/org/alfresco/service/transaction/TransactionService.java
index b1ee1d7c6f..61d5f9d60c 100644
--- a/source/java/org/alfresco/service/transaction/TransactionService.java
+++ b/source/java/org/alfresco/service/transaction/TransactionService.java
@@ -19,6 +19,7 @@ package org.alfresco.service.transaction;
import javax.transaction.UserTransaction;
import org.alfresco.service.NotAuditable;
+import org.alfresco.service.PublicService;
/**
* Contract for retrieving access to a user transaction.
@@ -29,6 +30,7 @@ import org.alfresco.service.NotAuditable;
*
* @author David Caruana
*/
+@PublicService
public interface TransactionService
{
/**
diff --git a/source/java/org/alfresco/tools/Tool.java b/source/java/org/alfresco/tools/Tool.java
index 903dd9a97f..ae0fb5112f 100644
--- a/source/java/org/alfresco/tools/Tool.java
+++ b/source/java/org/alfresco/tools/Tool.java
@@ -183,6 +183,7 @@ public abstract class Tool
*/
public final void start(String[] args)
{
+ long startTime = System.nanoTime();
int status = -1;
try
@@ -202,7 +203,11 @@ public abstract class Tool
logInfo(getToolName());
initialiseRepository();
login();
+ long loginTime = System.nanoTime();
+ logInfo("Time to login "+((loginTime - startTime)/1000000000f)+" seconds");
status = execute();
+ long executeTime = System.nanoTime();
+ logInfo("Time to execute "+((executeTime - loginTime)/1000000000f)+" seconds");
logInfo(getToolName() + " successfully completed.");
}
}