From e75b18d742279fa7fc38cffba16c4ccb065ddefd Mon Sep 17 00:00:00 2001 From: Andrew Hind Date: Thu, 31 Aug 2006 16:56:50 +0000 Subject: [PATCH] Audit - working without filters git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3646 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/application-context.xml | 1 + config/alfresco/audit-services-context.xml | 87 ++ config/alfresco/auditConfig.xml | 4 +- config/alfresco/auditSchema.xsd | 15 +- config/alfresco/ehcache-default.xml | 17 + config/alfresco/hibernate-context.xml | 21 + config/alfresco/public-services-context.xml | 1246 +++++++++-------- .../public-services-security-context.xml | 16 + config/alfresco/repository.properties | 2 + .../repo/audit/ApplicationAuditModel.java | 60 + .../alfresco/repo/audit/AuditComponent.java | 52 + .../repo/audit/AuditComponentImpl.java | 425 ++++++ .../repo/audit/AuditConfiguration.java | 36 + .../repo/audit/AuditConfigurationImpl.java | 61 + .../org/alfresco/repo/audit/AuditDAO.java | 32 + .../alfresco/repo/audit/AuditException.java | 54 + .../org/alfresco/repo/audit/AuditInfo.java | 385 +++++ .../repo/audit/AuditMethodInterceptor.java | 65 + .../org/alfresco/repo/audit/AuditMode.java | 67 + .../org/alfresco/repo/audit/AuditModel.java | 74 + .../alfresco/repo/audit/AuditServiceImpl.java | 88 ++ .../alfresco/repo/audit/MethodAuditModel.java | 57 + .../repo/audit/PublicServiceIdentifier.java | 35 + .../audit/PublicServiceIdentifierImpl.java | 165 +++ .../alfresco/repo/audit/RecordOptions.java | 38 + .../repo/audit/hibernate/Audit.hbm.xml | 158 +++ .../repo/audit/hibernate/AuditConfig.java | 41 + .../repo/audit/hibernate/AuditConfigImpl.java | 118 ++ .../repo/audit/hibernate/AuditDate.java | 106 ++ .../repo/audit/hibernate/AuditDateImpl.java | 289 ++++ .../repo/audit/hibernate/AuditFact.java | 74 + .../repo/audit/hibernate/AuditFactImpl.java | 578 ++++++++ .../repo/audit/hibernate/AuditSource.java | 29 + .../repo/audit/hibernate/AuditSourceImpl.java | 139 ++ .../audit/hibernate/HibernateAuditDAO.java | 439 ++++++ .../repo/audit/model/AbstractAuditEntry.java | 203 +++ .../repo/audit/model/AbstractFilter.java | 92 ++ .../audit/model/AbstractNamedAuditEntry.java | 63 + .../audit/model/ApplicationAuditEntry.java | 60 + .../alfresco/repo/audit/model/AuditEntry.java | 220 +++ .../repo/audit/model/AuditModelException.java | 54 + .../alfresco/repo/audit/model/FilterSet.java | 72 + .../repo/audit/model/FilterSetMode.java | 43 + .../alfresco/repo/audit/model/KeyFilter.java | 70 + .../repo/audit/model/KeyFilterMode.java | 86 ++ .../repo/audit/model/MethodAuditEntry.java | 59 + .../repo/audit/model/ParameterFilter.java | 62 + .../repo/audit/model/RecordOptionsImpl.java | 189 +++ .../repo/audit/model/ServiceAuditEntry.java | 100 ++ .../repo/audit/model/TrueFalseUnset.java | 52 + .../repo/audit/model/XMLModelElement.java | 25 + .../service/AnnotationTestInterface.java | 1 + .../org/alfresco/service/PublicService.java | 36 + .../org/alfresco/service/ServiceRegistry.java | 1 + .../service/cmr/action/ActionService.java | 2 + .../service/cmr/admin/AdminService.java | 3 + .../service/cmr/audit/AuditService.java | 85 ++ .../cmr/coci/CheckOutCheckInService.java | 2 + .../cmr/dictionary/DictionaryService.java | 2 + .../service/cmr/lock/LockService.java | 2 + .../service/cmr/model/FileFolderService.java | 2 + .../cmr/repository/ContentService.java | 2 + .../service/cmr/repository/CopyService.java | 2 + .../cmr/repository/MimetypeService.java | 2 + .../service/cmr/repository/NodeService.java | 2 + .../service/cmr/repository/ScriptService.java | 2 + .../cmr/repository/TemplateService.java | 2 + .../service/cmr/rule/RuleService.java | 2 + .../service/cmr/search/CategoryService.java | 2 + .../service/cmr/search/SearchService.java | 2 + .../cmr/security/AuthenticationService.java | 2 + .../cmr/security/AuthorityService.java | 2 + .../service/cmr/security/OwnableService.java | 2 + .../cmr/security/PermissionService.java | 2 + .../service/cmr/security/PersonService.java | 2 + .../service/cmr/version/VersionService.java | 2 + .../service/cmr/view/ExporterService.java | 2 + .../service/cmr/view/ImporterService.java | 2 + .../cmr/view/RepositoryExporterService.java | 2 + .../service/cmr/workflow/WorkflowService.java | 22 + .../service/descriptor/DescriptorService.java | 1 + .../service/license/LicenseService.java | 2 + .../namespace/NamespacePrefixResolver.java | 2 + .../service/namespace/NamespaceService.java | 2 + .../transaction/TransactionService.java | 2 + source/java/org/alfresco/tools/Tool.java | 5 + 86 files changed, 6158 insertions(+), 574 deletions(-) create mode 100644 config/alfresco/audit-services-context.xml create mode 100644 source/java/org/alfresco/repo/audit/ApplicationAuditModel.java create mode 100644 source/java/org/alfresco/repo/audit/AuditComponent.java create mode 100644 source/java/org/alfresco/repo/audit/AuditComponentImpl.java create mode 100644 source/java/org/alfresco/repo/audit/AuditConfiguration.java create mode 100644 source/java/org/alfresco/repo/audit/AuditConfigurationImpl.java create mode 100644 source/java/org/alfresco/repo/audit/AuditDAO.java create mode 100644 source/java/org/alfresco/repo/audit/AuditException.java create mode 100644 source/java/org/alfresco/repo/audit/AuditInfo.java create mode 100644 source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java create mode 100644 source/java/org/alfresco/repo/audit/AuditMode.java create mode 100644 source/java/org/alfresco/repo/audit/AuditModel.java create mode 100644 source/java/org/alfresco/repo/audit/AuditServiceImpl.java create mode 100644 source/java/org/alfresco/repo/audit/MethodAuditModel.java create mode 100644 source/java/org/alfresco/repo/audit/PublicServiceIdentifier.java create mode 100644 source/java/org/alfresco/repo/audit/PublicServiceIdentifierImpl.java create mode 100644 source/java/org/alfresco/repo/audit/RecordOptions.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/Audit.hbm.xml create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditConfig.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditConfigImpl.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditDate.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditDateImpl.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditFact.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditFactImpl.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditSource.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/AuditSourceImpl.java create mode 100644 source/java/org/alfresco/repo/audit/hibernate/HibernateAuditDAO.java create mode 100644 source/java/org/alfresco/repo/audit/model/AbstractAuditEntry.java create mode 100644 source/java/org/alfresco/repo/audit/model/AbstractFilter.java create mode 100644 source/java/org/alfresco/repo/audit/model/AbstractNamedAuditEntry.java create mode 100644 source/java/org/alfresco/repo/audit/model/ApplicationAuditEntry.java create mode 100644 source/java/org/alfresco/repo/audit/model/AuditEntry.java create mode 100644 source/java/org/alfresco/repo/audit/model/AuditModelException.java create mode 100644 source/java/org/alfresco/repo/audit/model/FilterSet.java create mode 100644 source/java/org/alfresco/repo/audit/model/FilterSetMode.java create mode 100644 source/java/org/alfresco/repo/audit/model/KeyFilter.java create mode 100644 source/java/org/alfresco/repo/audit/model/KeyFilterMode.java create mode 100644 source/java/org/alfresco/repo/audit/model/MethodAuditEntry.java create mode 100644 source/java/org/alfresco/repo/audit/model/ParameterFilter.java create mode 100644 source/java/org/alfresco/repo/audit/model/RecordOptionsImpl.java create mode 100644 source/java/org/alfresco/repo/audit/model/ServiceAuditEntry.java create mode 100644 source/java/org/alfresco/repo/audit/model/TrueFalseUnset.java create mode 100644 source/java/org/alfresco/repo/audit/model/XMLModelElement.java create mode 100644 source/java/org/alfresco/service/PublicService.java create mode 100644 source/java/org/alfresco/service/cmr/audit/AuditService.java 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: + * + *
    + *
  1. ALL - all calls are audited + *
  2. SUCCESS - only successful calls are audited (audited in the same TX) + *
  3. FAIL - only fail calls are audited (in a new transaction) + *
  4. NONE - noting is audited + *
  5. 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: + * + *
    + *
  1. The path to the node + *
  2. The type of the node + *
  3. The presence of an aspect + *
  4. The NodeRef of the node + *
  5. An XPATH expression evaluated in the context of the node with the return tested for the node. + * e.g. ".[@cm:content = 'woof']" + *
  6. A simple value for equality tests given a non node argument + *
  7. The protocol of the store containing the node + *
  8. The identifier of the store containing the node + *
  9. 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 + *
    + *
  1. TRUE + *
  2. FALSE + *
  3. 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."); } }