From f01f727e5e5a6a4e9c3605a08b7281914d820ced Mon Sep 17 00:00:00 2001 From: Erik Winlof Date: Wed, 3 Sep 2014 11:57:51 +0000 Subject: [PATCH] Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud) 78392: Merged EOL (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud) 75693: ACE-2149 Remove AVM/WCM - first round, based on the following Sparta commits 08f1ff556cf3e8eb370e433b69b634026c848af1: SlimRepo: comment-out AVM schema bootstrap and wcm-services-context - plus associated bootstrap/startup fallout - note: disabling/removing WCM/AVM will be a work-in-progress due to tight code coupling :-( cdb78eeae53522cc2d78feb94be49d11648fa582; SlimRepo: comment-out AVM schema bootstrap and wcm-services-context - follow-on to fix "regenerate_renditions" fallout error (in Alfresco Explorer web client) 33337ad4239df91b9a8dc7a00be43e55ffef5bef: SlimRepo: remove WCM/AVM - round 1 (wip) - removal of some of the AVM code and tests (including core impl such as AVMServiceImpl, AVMRepository, AVMSyncServiceImpl, underlying DAOs etc) - fix Spring config (major impact) and any obvious compile-time fallout - ensured repo starts and ran (some of the) repo unit tests - also check basic Explorer access 47e50847bbbbdda5fd64a27c212dfbdd625cbfdb: Jenkins build/test repo - minor: disable/remove repo tests - disabled unused tests, removed remaining AVM* tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@82537 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/action-services-context.xml | 1630 ++-- config/alfresco/application-context-core.xml | 2 + config/alfresco/avm-services-context.xml | 532 +- config/alfresco/bootstrap-context.xml | 8 + config/alfresco/content-services-context.xml | 2 + config/alfresco/core-services-context.xml | 4 + config/alfresco/dao/dao-context.xml | 12 +- .../alfresco/patch/patch-services-context.xml | 7612 +++++++++-------- config/alfresco/public-services-context.xml | 3093 +++---- .../Search/common-search-context.xml | 2 + .../Search/lucene/bootstrap-context.xml | 3 +- .../Search/lucene/index-recovery-context.xml | 8 +- .../Search/lucene/lucene-search-context.xml | 20 +- .../Search/lucene/opencmis-context.xml | 4 + .../default/network-protocol-context.xml | 5 + config/alfresco/version.properties | 2 +- .../repo/admin/ConfigurationChecker.java | 592 +- .../admin/IndexConfigurationCheckerImpl.java | 8 +- .../patch/impl/ContentUrlConverterPatch.java | 15 +- .../MoveWCMToGroupBasedPermissionsPatch.java | 426 - .../ResetWCMToGroupBasedPermissionsPatch.java | 1107 --- .../admin/patch/impl/WCMFoldersPatch.java | 364 - .../impl/WCMPostPermissionSnapshotPatch.java | 158 - .../java/org/alfresco/repo/avm/AVMDAOs.java | 157 - .../java/org/alfresco/repo/avm/AVMNode.java | 260 - .../org/alfresco/repo/avm/AVMNodeDAO.java | 131 - .../org/alfresco/repo/avm/AVMNodeImpl.java | 603 -- .../org/alfresco/repo/avm/AVMNodeService.java | 4177 ++++----- .../alfresco/repo/avm/AVMNodeUnwrapper.java | 44 - .../org/alfresco/repo/avm/AVMRepository.java | 3472 -------- .../org/alfresco/repo/avm/AVMServiceImpl.java | 1706 ---- .../alfresco/repo/avm/AVMServiceNOOPImpl.java | 735 ++ .../java/org/alfresco/repo/avm/AVMStore.java | 537 -- .../org/alfresco/repo/avm/AVMStoreDAO.java | 78 - .../org/alfresco/repo/avm/AVMStoreImpl.java | 2016 ----- .../alfresco/repo/avm/AVMStoreProperty.java | 67 - .../repo/avm/AVMStorePropertyDAO.java | 87 - .../repo/avm/AVMStorePropertyImpl.java | 149 - .../alfresco/repo/avm/AVMSyncServiceImpl.java | 1516 ---- .../repo/avm/AVMSyncServiceNOOPImpl.java | 77 + .../org/alfresco/repo/avm/AvmBootstrap.java | 89 - .../org/alfresco/repo/avm/ChildEntry.java | 50 - .../org/alfresco/repo/avm/ChildEntryDAO.java | 91 - .../org/alfresco/repo/avm/ChildEntryImpl.java | 122 - .../java/org/alfresco/repo/avm/ChildKey.java | 117 - .../org/alfresco/repo/avm/DeletedNode.java | 32 - .../alfresco/repo/avm/DeletedNodeImpl.java | 223 - .../org/alfresco/repo/avm/DirectoryNode.java | 168 - .../alfresco/repo/avm/DirectoryNodeImpl.java | 100 - .../java/org/alfresco/repo/avm/FileNode.java | 40 - .../org/alfresco/repo/avm/FileNodeImpl.java | 43 - .../java/org/alfresco/repo/avm/Layered.java | 54 - .../repo/avm/LayeredDirectoryNode.java | 114 - .../repo/avm/LayeredDirectoryNodeImpl.java | 1275 --- .../alfresco/repo/avm/LayeredFileNode.java | 38 - .../repo/avm/LayeredFileNodeImpl.java | 367 - source/java/org/alfresco/repo/avm/Lookup.java | 580 -- .../org/alfresco/repo/avm/LookupCache.java | 56 - .../alfresco/repo/avm/LookupComponent.java | 131 - .../alfresco/repo/avm/NOOPLookupCache.java | 176 - .../org/alfresco/repo/avm/OrphanReaper.java | 531 -- .../alfresco/repo/avm/OrphanReaperJob.java | 40 - .../alfresco/repo/avm/PlainDirectoryNode.java | 28 - .../repo/avm/PlainDirectoryNodeImpl.java | 530 -- .../org/alfresco/repo/avm/PlainFileNode.java | 51 - .../alfresco/repo/avm/PlainFileNodeImpl.java | 472 - .../repo/avm/TransactionalLookupCache.java | 334 - .../repo/avm/VersionLayeredNodeEntry.java | 48 - .../repo/avm/VersionLayeredNodeEntryDAO.java | 48 - .../repo/avm/VersionLayeredNodeEntryImpl.java | 134 - .../org/alfresco/repo/avm/VersionRoot.java | 111 - .../org/alfresco/repo/avm/VersionRootDAO.java | 110 - .../alfresco/repo/avm/VersionRootImpl.java | 254 - .../avm/actions/SimpleAVMSubmitAction.java | 155 - .../repo/avm/ibatis/AVMNodeDAOIbatis.java | 483 -- .../repo/avm/ibatis/AVMStoreDAOIbatis.java | 181 - .../avm/ibatis/AVMStorePropertyDAOIbatis.java | 130 - .../repo/avm/ibatis/ChildEntryDAOIbatis.java | 183 - .../VersionLayeredNodeEntryDAOIbatis.java | 75 - .../repo/avm/ibatis/VersionRootDAOIbatis.java | 223 - .../alfresco/repo/avm/util/RawServices.java | 173 - .../repo/avm/wf/AVMClearSubmittedHandler.java | 49 - .../repo/avm/wf/AVMDeployHandler.java | 198 - .../avm/wf/AVMReleaseTestServerHandler.java | 141 - .../avm/wf/AVMRemoveAllSrcWebappsHandler.java | 102 - .../repo/avm/wf/AVMRemoveWFStoreHandler.java | 85 - .../repo/avm/wf/AVMSubmitHandler.java | 90 - .../repo/avm/wf/AVMSubmitPackageHandler.java | 195 - .../avm/wf/AVMSubmitTransactionListener.java | 147 - .../content/cleanup/ContentStoreCleaner.java | 863 +- .../permissions/ADMAccessControlListDAO.java | 73 +- .../permissions/AVMAccessControlListDAO.java | 1216 --- .../permissions/AbstractAclCrudDAOImpl.java | 5 +- .../index/AVMFullIndexRecoveryComponent.java | 351 - .../node/index/AVMRemoteSnapshotTracker.java | 137 - ...hotTriggeredIndexingMethodInterceptor.java | 159 - ...riggeredIndexingMethodInterceptorImpl.java | 600 -- .../search/impl/lucene/AVMLuceneIndexer.java | 102 - .../AVMLuceneIndexerAndSearcherFactory.java | 213 - .../impl/lucene/AVMLuceneIndexerImpl.java | 2521 ------ .../impl/PermissionServiceImpl.java | 5 +- .../index/FullIndexRecoveryComponentTest.java | 14 - 102 files changed, 10194 insertions(+), 36653 deletions(-) delete mode 100644 source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java delete mode 100644 source/java/org/alfresco/repo/admin/patch/impl/ResetWCMToGroupBasedPermissionsPatch.java delete mode 100644 source/java/org/alfresco/repo/admin/patch/impl/WCMFoldersPatch.java delete mode 100644 source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMDAOs.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMNode.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMNodeDAO.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMRepository.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMServiceImpl.java create mode 100644 source/java/org/alfresco/repo/avm/AVMServiceNOOPImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMStore.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMStoreDAO.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMStoreImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMStoreProperty.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMStorePropertyDAO.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMStorePropertyImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java create mode 100644 source/java/org/alfresco/repo/avm/AVMSyncServiceNOOPImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/AvmBootstrap.java delete mode 100644 source/java/org/alfresco/repo/avm/ChildEntry.java delete mode 100644 source/java/org/alfresco/repo/avm/ChildEntryDAO.java delete mode 100644 source/java/org/alfresco/repo/avm/ChildEntryImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/ChildKey.java delete mode 100644 source/java/org/alfresco/repo/avm/DeletedNode.java delete mode 100644 source/java/org/alfresco/repo/avm/DeletedNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/DirectoryNode.java delete mode 100644 source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/FileNode.java delete mode 100644 source/java/org/alfresco/repo/avm/FileNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/Layered.java delete mode 100644 source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java delete mode 100644 source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/LayeredFileNode.java delete mode 100644 source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/Lookup.java delete mode 100644 source/java/org/alfresco/repo/avm/LookupCache.java delete mode 100644 source/java/org/alfresco/repo/avm/LookupComponent.java delete mode 100644 source/java/org/alfresco/repo/avm/NOOPLookupCache.java delete mode 100644 source/java/org/alfresco/repo/avm/OrphanReaper.java delete mode 100644 source/java/org/alfresco/repo/avm/OrphanReaperJob.java delete mode 100644 source/java/org/alfresco/repo/avm/PlainDirectoryNode.java delete mode 100644 source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/PlainFileNode.java delete mode 100644 source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/TransactionalLookupCache.java delete mode 100644 source/java/org/alfresco/repo/avm/VersionLayeredNodeEntry.java delete mode 100644 source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryDAO.java delete mode 100644 source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/VersionRoot.java delete mode 100644 source/java/org/alfresco/repo/avm/VersionRootDAO.java delete mode 100644 source/java/org/alfresco/repo/avm/VersionRootImpl.java delete mode 100644 source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java delete mode 100644 source/java/org/alfresco/repo/avm/ibatis/AVMNodeDAOIbatis.java delete mode 100644 source/java/org/alfresco/repo/avm/ibatis/AVMStoreDAOIbatis.java delete mode 100644 source/java/org/alfresco/repo/avm/ibatis/AVMStorePropertyDAOIbatis.java delete mode 100644 source/java/org/alfresco/repo/avm/ibatis/ChildEntryDAOIbatis.java delete mode 100644 source/java/org/alfresco/repo/avm/ibatis/VersionLayeredNodeEntryDAOIbatis.java delete mode 100644 source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java delete mode 100644 source/java/org/alfresco/repo/avm/util/RawServices.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMDeployHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMReleaseTestServerHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMRemoveAllSrcWebappsHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMSubmitHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java delete mode 100644 source/java/org/alfresco/repo/avm/wf/AVMSubmitTransactionListener.java delete mode 100644 source/java/org/alfresco/repo/domain/permissions/AVMAccessControlListDAO.java delete mode 100644 source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java delete mode 100644 source/java/org/alfresco/repo/node/index/AVMRemoteSnapshotTracker.java delete mode 100644 source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java delete mode 100644 source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptorImpl.java delete mode 100644 source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java delete mode 100644 source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerAndSearcherFactory.java delete mode 100644 source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml index 9852aeea3d..6bde8c757e 100644 --- a/config/alfresco/action-services-context.xml +++ b/config/alfresco/action-services-context.xml @@ -1,855 +1,775 @@ - - - - - - - - - - - - - defaultAsyncAction - - - ${default.async.action.corePoolSize} - - - ${default.async.action.maximumPoolSize} - - - ${default.async.action.threadPriority} - - - - - - - deploymentAsyncAction - - - ${deployment.service.corePoolSize} - - - ${deployment.service.maximumPoolSize} - - - ${deployment.service.threadPriority} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - actionTrackingService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - alfresco.messages.action-service - alfresco.messages.action-config - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ftl - - - - - - - - - - - - - - - js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - - - - false - - - - - - - - - - - - - - - - - - false - - - - - - - - - false - - - - - - - - - - - - false - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - - {http://www.alfresco.org/model/content/1.0}content - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - {http://www.alfresco.org/model/content/1.0}content - - - - - - - - - - - - - - {http://www.alfresco.org/model/content/1.0}content - - - - - - - - - - - - org.alfresco.repo.action.executer.ActionExecuter - org.alfresco.repo.action.executer.TestModeable - - - - - - - false - - - - - - - - - - - org.springframework.mail.javamail.JavaMailSender - - - - - - - - true - - - - - - false - - - - - - - - - - - - - - - - - - - {http://www.alfresco.org/model/content/1.0}content - - - - true - - - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - ${spaces.store} - - - /${spaces.company_home.childname} - - - - - - - - - - - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - false - - - - - - - - - - false - - - - - - - - - - false - - - - - - - - - - false - - - - - - - - - - false - - - - - - - - - - - - - false - - - - - - - - - deployment - - - - - - - - - - - - - - - false - - - admin - - - admin - - - ${alfresco.rmi.services.port} - - - 44100 - - - default - - - 30 - - - - - - - - - false - - - - - - - - - - - - false - - - - - - - - - - - - false - - - - - - - - - - - - false - - - - - - - - - - - - false - - - - - - - - - - - - true - - - false - - - - - - - - - - - - false - - - false - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + defaultAsyncAction + + + ${default.async.action.corePoolSize} + + + ${default.async.action.maximumPoolSize} + + + ${default.async.action.threadPriority} + + + + + + + deploymentAsyncAction + + + ${deployment.service.corePoolSize} + + + ${deployment.service.maximumPoolSize} + + + ${deployment.service.threadPriority} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + actionTrackingService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + alfresco.messages.action-service + alfresco.messages.action-config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ftl + + + + + + + + + + + + + + + js + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}content + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}content + + + + + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}content + + + + + + + + + + + + org.alfresco.repo.action.executer.ActionExecuter + org.alfresco.repo.action.executer.TestModeable + + + + + + + false + + + + + + + + + + + org.springframework.mail.javamail.JavaMailSender + + + + + + + + true + + + + + + false + + + + + + + + + + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}content + + + + true + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + ${spaces.store} + + + /${spaces.company_home.childname} + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + deployment + + + + + + + + + + + + + + + false + + + admin + + + admin + + + ${alfresco.rmi.services.port} + + + 44100 + + + default + + + 30 + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + true + + + false + + + + + + + + + + + + false + + + false + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/application-context-core.xml b/config/alfresco/application-context-core.xml index c5a5783e10..ad699fc394 100644 --- a/config/alfresco/application-context-core.xml +++ b/config/alfresco/application-context-core.xml @@ -37,8 +37,10 @@ + diff --git a/config/alfresco/avm-services-context.xml b/config/alfresco/avm-services-context.xml index 1cfd4ac630..a50b7967fd 100644 --- a/config/alfresco/avm-services-context.xml +++ b/config/alfresco/avm-services-context.xml @@ -1,265 +1,267 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1000 - - - 50 - - - - - - - - - ${orphanReaper.lockRefreshTime} - - - ${orphanReaper.lockTimeOut} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .*/#[^/]* - - - - - - - - .o - .bak - .tmp - ~ - - - - - - - - - - - - - - - - - admin - - - jbpm$wcmwf:changerequest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - workspace://SpacesStore - - - - - - - - - - - - - - - - - - - - ${wcm.rename.max.time.milliseconds} - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1000 + + + 50 + + + + + + + + + ${orphanReaper.lockRefreshTime} + + + ${orphanReaper.lockTimeOut} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .*/#[^/]* + + + + + + + + .o + .bak + .tmp + ~ + + + + + + + + + + + + + + + + + admin + + + jbpm$wcmwf:changerequest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + workspace://SpacesStore + + + + + + + + + + + + + + + + + + + + ${wcm.rename.max.time.milliseconds} + + + + diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index 86b376ac27..a2f776f22e 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -101,10 +101,12 @@ + @@ -122,6 +124,8 @@ + + @@ -186,7 +191,10 @@ --> + + diff --git a/config/alfresco/content-services-context.xml b/config/alfresco/content-services-context.xml index a1bd531143..31e93c2f1f 100644 --- a/config/alfresco/content-services-context.xml +++ b/config/alfresco/content-services-context.xml @@ -108,9 +108,11 @@ + diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 16d0a2e3d0..a121a37b1d 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -1240,6 +1240,7 @@ + @@ -1342,6 +1344,7 @@ + diff --git a/config/alfresco/dao/dao-context.xml b/config/alfresco/dao/dao-context.xml index ebdb7b3a4f..830ba0763b 100644 --- a/config/alfresco/dao/dao-context.xml +++ b/config/alfresco/dao/dao-context.xml @@ -225,6 +225,8 @@ + @@ -270,11 +273,15 @@ + + @@ -312,12 +320,14 @@ + diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 9d77fcc169..44b6f644f9 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -1,3802 +1,3810 @@ - - - - - - - - org.alfresco.repo.admin.patch.PatchService - - - - - - - - - - - - - - - - PROPAGATION_NOT_SUPPORTED - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${system.workflow.deployWorkflowsInTenant} - - - - - - Sample01 - A NO-OP sample patch - 0 - 1000 - 1001 - - - Sample02 - A NO-OP sample patch - 0 - 1000 - 1001 - - - - - - - - Sample03 - A NO-OP sample patch - 0 - 1000 - 1001 - false - - - - - - - - - - alfresco/messages/bootstrap-spaces - - - - - - - - - - patch.savedSearchesFolder - patch.savedSearchesFolder.description - 0 - 1 - 2 - - 3.3 - - - - patch.savedSearchesPermission - patch.savedSearchesPermission.description - 0 - 4 - 5 - - 3.3 - - - - patch.updatePermissionData - patch.updatePermissionData.description - 0 - 2 - 3 - - 3.3 - - - - patch.guestUser - patch.guestUser.description - 0 - 2 - 3 - - 3.3 - - - - patch.fixNodeSerializableValues - patch.fixNodeSerializableValues.description - 0 - 3 - 4 - - 3.2 - - - - patch.updateGuestPermission - patch.updateGuestPermission.description - 0 - 5 - 6 - - 3.3 - - - - patch.guestPersonPermission - patch.guestPersonPermission.description - 0 - 5 - 6 - - - patch.spacesRootPermission - patch.spacesRootPermission.description - 0 - 5 - 6 - - 3.3 - - - - patch.categoryRootPermission - patch.categoryRootPermission.description - 0 - 5 - 6 - - 3.3 - - - - patch.contentPermission - patch.contentPermission.description - 0 - 6 - 7 - - 3.3 - - - - patch.forumsIcons - patch.forumsIcons.description - 0 - 12 - 13 - - 3.3 - - - - patch.emailTemplatesFolder - patch.emailTemplatesFolder.description - 0 - 12 - 13 - - 3.3 - - - - patch.emailTemplatesContent - patch.emailTemplatesContent.description - 0 - 12 - 13 - - 3.3 - - - - patch.descriptorUpdate - patch.descriptorUpdate.description - 0 - 11 - 12 - - 3.3 - - - - patch.scriptsFolder - patch.scriptsFolder.description - 0 - 12 - 13 - - 3.3 - - - - patch.topLevelGroupParentChildAssociationTypePatch - patch.topLevelGroupParentChildAssociationTypePatch.description - 0 - 13 - 14 - - 3.3 - - - - patch.actionRuleDecouplingPatch - patch.actionRuleDecouplingPatch.description - 0 - 14 - 15 - - 3.3 - - - - patch.systemWorkflowFolderPatch - patch.systemWorkflowFolder.description - 0 - 15 - 16 - - 3.3 - - - - patch.rssFolder - patch.rssTemplatesFolder.description - 0 - 16 - 17 - - 3.3 - - - - patch.uifacetsTemplates - patch.uifacetsAspectRemovalPatch.description - 0 - 17 - 18 - - 3.3 - - - - patch.guestPersonPermission2 - patch.guestPersonPermission2.description - 0 - 18 - 19 - - 3.3 - - - - patch.schemaUpdateScript-V1.4-1 - patch.schemaUpgradeScript.description - 0 - 19 - 20 - - 3.3.x - - - - patch.uniqueChildName - patch.uniqueChildName.description - 0 - 19 - 20 - - 2.1.4 - - - - patch.schemaUpdateScript-V1.4-2 - patch.schemaUpgradeScript.description - 0 - 20 - 21 - - 3.3.x - - - - patch.InvalidNameEnding - patch.invalidNameEnding.description - 0 - 21 - 22 - - 3.3.x - - - - patch.systemDescriptorContent - patch.systemDescriptorContent.description - 0 - 22 - 23 - - 3.3 - - - - patch.versionHistoryPerformance - patch.versionHistoryPerformance.description - 0 - 38 - 39 - - 3.3 - - - - patch.multilingualBootstrap - patch.multilingualBootstrap.description - 0 - 29 - 30 - - 3.3 - - - - patch.LinkNodeFileExtension - patch.linkNodeExtension.description - 0 - 33 - 34 - - 3.3 - - - - patch.systemRegistryBootstrap - patch.systemRegistryBootstrap.description - 0 - 34 - 35 - - 3.3 - - - - patch.userAndPersonUserNamesAsIdentifiers - patch.userAndPersonUserNamesAsIdentifiers.description - 0 - 35 - 36 - - 3.3 - - - - patch.contentFormFolderType - patch.contentFormFolderType.description - 0 - 36 - 37 - - 3.3 - - - - patch.db-V2.1-JBPMUpdate - patch.schemaUpgradeScript.description - 0 - 51 - 52 - - 3.3 - - - - patch.db-V2.1-NotNullColumns - patch.schemaUpgradeScript.description - 0 - 51 - 52 - - 3.3 - - - - patch.groupNamesAsIdentifiers - patch.groupNamesAsIdentifiers.description - 0 - 51 - 52 - - 3.3 - - - - patch.invalidUserPersonAndGroup - patch.invalidUserPersonAndGroup.description - 0 - 51 - 52 - - 3.3 - - - - patch.AVMGuidPatch - patch.AVMGuidPatch.description - 0 - 51 - 52 - - 3.3 - - - - patch.webscripts - patch.webscripts.description - 0 - 50 - 51 - - 3.3 - - - - patch.webscriptsExtension - patch.webscriptsExtension.description - 0 - 54 - 55 - - 3.3 - - - - patch.AVMLayeredSnapshot - patch.AVMLayeredSnapshot.description - 0 - 55 - 56 - - 3.3 - - - - patch.groupMembersAsIdentifiers - patch.groupMembersAsIdentifiers.description - 0 - 56 - 57 - - 3.3 - - - - patch.redeploySubmitProcess - patch.redeploySubmitProcess.description - 0 - 57 - 58 - - 3.3 - - - - patch.ReadmeTemplate - patch.ReadmeTemplate.description - 0 - 59 - 60 - - 3.3 - - - - patch.webScriptsReadme - patch.webScriptsReadme.description - 0 - 59 - 60 - - 3.3 - - - - patch.db-V2.1-JBPMProcessKey - patch.schemaUpgradeScript.description - 0 - 62 - 63 - - 3.3 - - - - patch.db-V2.1-VersionColumns2 - patch.schemaUpgradeScript.description - 0 - 63 - 64 - - 3.3 - - - - patch.db-V1.4-TxnCommitTimeIndex - patch.schemaUpgradeScript.description - 0 - 110 - 111 - - 3.3.x - - - - patch.db-V2.0-ContentUrls - patch.schemaUpgradeScript.description - 0 - 123 - 124 - - 3.3.x - - - - patch.webscripts2 - patch.webscripts2.description - 0 - 100 - 101 - - 3.4.x - - - - patch.customModels - patch.customModels.description - 0 - 101 - 102 - - 3.4.x - - - - patch.customMessages - patch.customMessages.description - 0 - 101 - 102 - - 3.4.x - - - - patch.customWebClientExtension - patch.customWebClientExtension.description - 0 - 101 - 102 - - 3.4.x - - - - patch.redeploySubmitProcess - patch.redeploySubmitProcess.description - 0 - 102 - 103 - - 3.4.x - - - - patch.db-V2.1-RemoveWcmSubmittedAspect - patch.schemaUpgradeScript.description - 0 - 103 - 104 - - 3.4.x - - - - patch.webscripts3 - patch.webscripts3.description - 0 - 104 - 105 - - 3.4.x - - - - patch.customWorkflowDefs - patch.customWorkflowDefs.description - 0 - 105 - 106 - - 3.4.x - - - - patch.avmStoreAsIdentifier - patch.avmStoreAsIdentifier.description - 0 - 109 - 110 - - 3.4.x - - - - patch.avmFormPropertyIdentifier - patch.avmFormPropertyIdentifier.description - 0 - 111 - 112 - - 3.4.x - - - - patch.formsFolder - patch.formsFolder.description - 0 - 112 - 113 - - 3.4.x - - - - patch.tagRootCategory - patch.tagRootCategory.description - 0 - 113 - 114 - - 3.4.x - - - - patch.db-V3.4-UsageTables - patch.schemaUpgradeScript.description - 0 - 113 - 114 - - 3.4.x - - - - patch.deploymentMigration - patch.deploymentMigration.description - 0 - 116 - 117 - - 3.4.x - - - - patch.redeploySubmitProcess - patch.redeploySubmitProcess.description - 0 - 117 - 118 - - 3.4.x - - - - - - - - - patch.db-V2.2-ACL-From-2.1-A - patch.schemaUpgradeScript.description - 0 - ${V2.1-A.fixes.to.schema} - 120 - - - - - - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-2.1-A--to--2.2-ACL.sql - - - - - patch.db-V2.2-ACL - patch.schemaUpgradeScript.description - 0 - 119 - 120 - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-2.2-ACL.sql - - - - - patch.updateAvmPermissionData - patch.updateAvmPermissionData.description - 0 - 119 - 120 - - - - - - - - - - - - patch.db-V2.2-CleanNodeStatuses - patch.schemaUpgradeScript.description - 0 - 89 - 90 - - - - - - - - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-2.2-CleanNodeStatuses.sql - - - - patch.db-V2.2-0-CreateMissingTables - patch.schemaUpgradeScript.description - 0 - 120 - 121 - - - - - - - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/upgrade-0-create-missing-tables.sql - - - - patch.db-V2.2-2-MoveQNames - patch.noOpPatch.description - 0 - 120 - 121 - - - patch.db-V2.2-Upgrade-From-2.1 - patch.schemaUpgradeScript.description - 0 - 120 - 135 - - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/upgrade-from-2.1.sql - - - - patch.db-V2.2-Upgrade-From-2.2SP1 - patch.schemaUpgradeScript.description - 0 - 134 - 135 - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/upgrade-from-2.2SP1.sql - - - - - patch.avmWebProjectInheritPermissions02 - patch.avmWebProjectInheritPermissions.description - 0 - 122 - 123 - - - - - - - - - - - - - - - patch.updateDmPermissions - patch.updateDmPermissions.description - 0 - 124 - 125 - - - - - - - - - - - - - - - - - - patch.db-V3.0-0-CreateActivitiesExtras - patch.db-V3.0-0-CreateActivitiesExtras.description - 0 - 125 - 126 - - - - - - - - patch.db-V3.0-ActivityTables - patch.schemaUpgradeScript.description - 0 - 125 - 126 - - - - - - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-ActivityTables.sql - - - - - patch.createSiteStore - patch.noOpPatch.description - 0 - 126 - 127 - - - - patch.sitesFolder - patch.sitesFolder.description - 0 - 127 - 128 - - - - - - - - - - /${spaces.company_home.childname}/st:sites - - - - /${spaces.company_home.childname} - alfresco/bootstrap/sitesSpace.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.sitePermissionRefactorPatch - patch.sitePermissionRefactorPatch.description - 0 - 128 - 129 - - - - - - - - - - - - - - - - - - - patch.migrateVersionStore - patch.migrateVersionStore.description - 0 - 129 - 130 - - - - - - - - - - - - - - - - - - - ${version.store.migrateVersionStore.threadCount} - - - ${version.store.migrateVersionStore.batchSize} - - - ${version.store.migrateVersionStore.runAsScheduledJob} - - - ${version.store.migrateVersionStore.limitPerJobCycle} - - - false - - - - - patch.inviteEmailTemplate - patch.inviteEmailTemplate.description - 0 - 130 - 131 - - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} - alfresco/bootstrap/invite/invite-email.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.calendarNamespaceUri - patch.calendarModelNamespacePatch.description - 0 - 131 - 132 - - - - - - - - - - - - - - - - - - - - - patch.db-V2.1-AuditPathIndex - patch.schemaUpgradeScript.description - 0 - 132 - 133 - - - - patch.spacesStoreGuestPermission - patch.spacesStoreGuestPermission.description - 0 - 133 - 134 - - - - - - - - - - - - - - - - patch.redeploySubmitProcess4 - patch.redeploySubmitProcess.description - 0 - 1000 - 1001 - - - - - - - - - - - jbpm - alfresco/workflow/submit_processdefinition.xml - text/xml - - - - - - - patch.redeploySubmitProcess5 - patch.redeploySubmitProcess.description - 0 - 2000 - 2001 - - - - - - - - - - jbpm - alfresco/workflow/submit_processdefinition.xml - text/xml - - - - - - - patch.deploySubmitDirectProcess - patch.deploySubmitDirectProcess.description - 0 - 2000 - 2001 - - - - - - - - - - jbpm - alfresco/workflow/submitdirect_processdefinition.xml - text/xml - - - - - - - patch.resetWCMToGroupBasedPermissionsPatch - patch.resetWCMToGroupBasedPermissionsPatch.description - 0 - 2001 - 2002 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ContentManager - - - - - - patch.wcmPostPermissionSnapshotPatch3 - patch.wcmPostPermissionSnapshotPatch.description - 0 - 2001 - 2002 - - - - - - - - - - - - - - - - - - - - - - - - - patch.moveWCMToGroupBasedPermissionsPatch - patch.noOpPatch.description - 0 - 2001 - 2002 - - - - - - - - - - patch.wcmPostPermissionSnapshotPatch2 - patch.noOpPatch.description - 0 - 2001 - 2002 - - - - - - - - - - patch.redeploySubmitProcess6 - patch.redeploySubmitProcess.description - 0 - 2002 - 2003 - - - - - - - - - jbpm - alfresco/workflow/submit_processdefinition.xml - text/xml - - - jbpm - alfresco/workflow/submitdirect_processdefinition.xml - text/xml - - - - - - - patch.redeploySubmitProcess7 - patch.redeploySubmitProcess.description - 0 - 2003 - 2004 - - - - - - - - - jbpm - alfresco/workflow/submit_processdefinition.xml - text/xml - - - jbpm - alfresco/workflow/submitdirect_processdefinition.xml - text/xml - - - - - - - patch.db-V2.2-Person-3 - patch.schemaUpgradeScript.description - 0 - 3002 - 3003 - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-Person.sql - - - - - patch.webSiteAddModerated - patch.webSiteAddModerated.description - 0 - 2006 - 2007 - - - - - - - - - - - - - - - - - - patch.invitationMigration - patch.invitationMigration.description - 0 - 2006 - 2007 - - - - - - - - - - - - - - - patch.db-V3.2-Remove-AVM-Issuer - patch.schemaUpgradeScript.description - 0 - 2007 - 2008 - - classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/remove-AVM-issuer.sql - - - - - patch.mtShareExistingTenants - patch.mtShareExistingTenants.description - 0 - 2008 - 2009 - true - - - - - - - - - - - - - - - jbpm - alfresco/workflow/invitation-nominated_processdefinition.xml - text/xml - - - jbpm - alfresco/workflow/invitation-moderated_processdefinition.xml - text/xml - - - - - - - patch.redeployInvitationProcess - patch.redeployInvitationProcess.description - 0 - 2009 - 2010 - - - - - - - - - jbpm - alfresco/workflow/invitation-moderated_processdefinition.xml - text/xml - - - jbpm - alfresco/workflow/invitation-nominated_processdefinition.xml - text/xml - - - - - - - patch.db-V3.2-LockTables - patch.schemaUpgradeScript.description - 0 - 2010 - 2011 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-LockTables.sql - - - - - patch.zonedAuthorities - patch.zonedAuthorities.description - 0 - 2011 - 2012 - - - - - - - - - - /${system.system_container.childname}/${system.authorities_container.childname} - - - - /${system.system_container.childname} - alfresco/bootstrap/alfrescoAuthorityStore.xml - - - - - - patch.authorityMigration - patch.authorityMigration.description - 0 - 2012 - 2013 - - - - - - - - - - - - - - - - - - - - patch.authorityDefaultZonesPatch - patch.authorityDefaultZonesPatch.description - 0 - 2013 - 2014 - - - - - - - - - - - - - - - - - - - - patch.db-V3.2-ContentTables - patch.schemaUpgradeScript.description - 0 - 2015 - 2016 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-ContentTables.sql - - - - - patch.db-V3.2-Modify-AVM-MimeType - patch.schemaUpgradeScript.description - 0 - 2016 - 2017 - - classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/modify-AVM-mimetype.sql - - - - - patch.imapFolders - patch.imapFolders.description - 0 - 2018 - 2019 - - - - - - - - - - - - - - - alfresco/templates/imap/imap_config_space.acp - alfresco/templates/imap/email_actions_space.acp - alfresco/templates/imap/command_processor_scripts.acp - - - - patch.db-V3.2-PropertyValueTables - patch.schemaUpgradeScript.description - 0 - 3000 - 3001 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-PropertyValueTables.sql - - - - - patch.db-V3.2-AuditTables - patch.schemaUpgradeScript.description - 0 - 3001 - 3002 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-AuditTables.sql - - - - - patch.db-V3.1-Allow-IPv6 - patch.schemaUpgradeScript.description - 0 - 3003 - 3004 - - classpath:alfresco/dbscripts/upgrade/3.1/${db.script.dialect}/IPv6-patch.sql - - - - - patch.personUsagePatch - patch.personUsagePatch.description - 0 - 3004 - 3005 - - - - - - - patch.db-V3.2-Child-Assoc-QName-CRC - patch.schemaUpgradeScript.description - 0 - 3005 - 3006 - - classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/child-assoc-qname-crc.sql - - - - - patch.fixNameCrcValues-2 - patch.fixNameCrcValues.description - 0 - 3006 - 3007 - false - - - - - - - - - - - - - - - - - - - patch.redeployNominatedInvitationProcessWithPropsForShare - patch.redeployNominatedInvitationProcessWithPropsForShare.description - 0 - 4000 - 4001 - - - - - - - - - jbpm - alfresco/workflow/invitation-nominated_processdefinition.xml - text/xml - - - - - - - patch.redeployJbpmAdhocWorkflow - patch.redeployJbpmAdhocWorkflow.description - 0 - 4204 - 4205 - - - - - - - - - jbpm - alfresco/workflow/adhoc_processdefinition.xml - text/xml - - - - - - - patch.db-V3.2-ContentTables2 - patch.schemaUpgradeScript.description - 0 - 4001 - 4002 - - - - - - - classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/AlfrescoSchemaUpdate-3.2-ContentTables2.sql - - - - - patch.db-V3.3-Remove-VersionCount - patch.schemaUpgradeScript.description - 0 - 4002 - 4003 - - classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/remove-VersionCount.sql - - - - - patch.rendition.rendering_actions - patch.rendition.rendering_actions.description - 0 - 4003 - 4004 - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.rendition.rendering_actions.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname} - alfresco/bootstrap/renderingActionSpace.xml - alfresco/messages/bootstrap-spaces - - - - - - - patch.thumbnailsAssocQName - patch.thumbnailsAssocQName.description - 0 - 4004 - 4005 - - - - - - - - - - - - - - {http://www.alfresco.org/model/content/1.0}thumbnails - - - {http://www.alfresco.org/model/rendition/1.0}rendition - - - - - - patch.emailInviteAndNotifyTemplatesFolder - patch.emailInviteAndNotifyTemplatesFolder.description - 0 - 4006 - 4007 - - - - - - - - - - - - - - - patch.transferServiceFolder - patch.transferDefinitions.description - 0 - 4008 - 4009 - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.transfers.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname} - alfresco/bootstrap/transferSpaces.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.convertContentUrls - patch.convertContentUrls.description - 0 - 4007 - 4008 - false - - - - - - - - - - - - - - - - - - patch.db-V3.4-authority-unique-idx - patch.schemaUpgradeScript.description - 0 - 4099 - 4100 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/authority-unique-idx.sql - - - - - patch.fixAuthoritiesCrcValues - patch.fixAuthoritiesCrcValues.description - 0 - 4100 - 4101 - false - - - - - - - - - - - - - patch.updateMimetypes1 - patch.updateMimetypes1.description - 0 - 4101 - 4102 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - patch.db-V3.3-modify-index-permission_id - patch.schemaUpgradeScript.description - 0 - 4102 - 4103 - - classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/modify-index-permission_id.sql - - - - - patch.db-V3.2-AddFKIndexes - patch.schemaUpgradeScript.description - 3007 - 4103 - 4104 - - classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AddFKIndexes.sql - - - - - patch.db-V3.3-Fix-Repo-Seqs - patch.schemaUpgradeScript.description - 0 - 4104 - 4105 - - classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/fix-Repo-seqs.sql - - - - - patch.db-V3.3-Fix-AVM-Seqs - patch.schemaUpgradeScript.description - 0 - 4104 - 4105 - - classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/fix-AVM-seqs.sql - - - - - patch.db-V3.4-property-unique-ctx-value - patch.schemaUpgradeScript.description - 0 - 4104 - 4105 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/property-unique-ctx-value.sql - - - - patch.db-V3.4-property-unique-ctx-idx - patch.schemaUpgradeScript.description - 0 - 4104 - 4105 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/property-unique-ctx-idx.sql - - - - - - - - - - patch.db-V3.4-child-assoc-indexes - patch.schemaUpgradeScript.description - 0 - 4104 - 4105 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/child-assoc-indexes.sql - - - - - patch.db-V3.3-JBPM-Extra - patch.schemaUpgradeScript.description - 0 - 4105 - 4106 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoPostCreate-JBPM-Extra.sql - - - - - patch.db-V3.3-Node-Prop-Serializable - patch.schemaUpgradeScript.description - 0 - 4105 - 4106 - - classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/node-prop-serializable.sql - - - - - - patch.migrateAttrTenants - patch.migrateAttrTenants.description - 0 - 0 - 1 - false - - - - - - - - - - - - - - patch.migrateAttrAVMLocks - patch.migrateAttrAVMLocks.description - 0 - 4106 - 4107 - false - - - - - - - - - - - - - - - patch.migrateAttrPropBackedBeans - patch.migrateAttrPropBackedBeans.description - 0 - 4106 - 4107 - false - - - - - - - - - - - - - - patch.migrateAttrChainingURS - patch.migrateAttrChainingURS.description - 0 - 4106 - 4107 - false - - - - - - - - - - - - - - patch.migrateAttrDelete - patch.noOpPatch.description - 0 - 4106 - 4107 - - - patch.migrateAttrDropOldTables - patch.migrateAttrDropOldTables.description - 0 - 5006 - 5007 - false - - - - - - - - - - - - - - - patch.replication.replication_actions - patch.replication.replication_actions.description - 0 - 4107 - 4108 - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.replication.replication_actions.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname} - alfresco/bootstrap/replicationActionSpace.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.transfer.targetrulefolder - patch.transfer.targetrulefolder.description - 0 - 4108 - 4109 - - - - - - - - - - - /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default/rule:ruleFolder - - - - /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default - alfresco/bootstrap/transferTargetRuleFolder.xml - - - - - - patch.transfer.targetrule - patch.transfer.targetrule.description - 0 - 4108 - 4109 - - - - - - - - - - - /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default/rule:ruleFolder/rule:rules3245de8b-2cfe-42ed-8f8b-44089f99b265 - - - - /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default/rule:ruleFolder - alfresco/bootstrap/transferTargetRule.xml - - - - - - patch.actions.scheduledfolder - patch.actions.scheduledfolder.description - 0 - 4109 - 4110 - - - - - - - - - - /app:company_home/app:dictionary/cm:Scheduled_x0020_Actions - - - - /app:company_home/app:dictionary - alfresco/bootstrap/scheduledActionsFolder.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.publishing.root - patch.publishing.root.description - 0 - 5013 - 5014 - - - - - - - - - - ${publishing.root} - - - - ${publishing.root.path} - alfresco/bootstrap/publishingRootFolder.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.updateMimetypes2 - patch.updateMimetypes2.description - 0 - 4110 - 4111 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - patch.db-V3.2-AddFKIndexes-2 - patch.schemaUpgradeScript.description - 0 - 4111 - 4112 - - classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/AlfrescoSchemaUpdate-3.2-AddFKIndexes-2.sql - - - - - - - - - - - - - - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/link-validation-metadata-removing.sql - - - - - patch.mtFixAdminExistingTenants - patch.mtFixAdminExistingTenants.description - - - - - - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.models.childname} - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.workflow.definitions.childname} - - - - - - patch.fixUserQNames - patch.fixUserQNames.description - - - - - - - - - - - - - - - - - - - - - - patch.db-V3.2-Upgrade-JBPM - patch.noOpPatch.description - 0 - 2017 - 2018 - - - - - - - - - patch.db-V3.4-AVM-rename-dupes - patch.schemaUpgradeScript.description - 0 - 5005 - 5006 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/AVM-rename-dupes.sql - - - - - patch.activitiesEmailTemplate - patch.activitiesEmailTemplate.description - 0 - 5005 - 5006 - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.activities.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} - alfresco/templates/activities-email-templates.xml - alfresco/messages/bootstrap-spaces - - - - - - - patch.activitiesTemplatesUpdate - - - patch.activitiesTemplatesUpdate.description - - - - - - - - - - - - - - - - patch.followingMailTemplates - patch.followingMailTemplates.description - 0 - 5010 - 5011 - - - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} - alfresco/templates/following-email-templates.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.newUserEmailTemplates - patch.newUserEmailTemplates.description - 0 - 5005 - 5006 - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} - alfresco/templates/new-user-templates.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.inviteEmailTemplates - patch.inviteEmailTemplates.description - 0 - 5005 - 5006 - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} - alfresco/templates/invite-email-templates.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.htmlNotificationMailTemplates - patch.htmlNotificationMailTemplates.description - 0 - 5005 - 5006 - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.notify.childname} - alfresco/templates/notify_email_templates.xml - alfresco/messages/bootstrap-spaces - - - - - - - patch.imapSpacesLocaleTemplates - patch.noOpPatch.description - 0 - 4302 - 4305 - - - - - patch.siteLoadPatch.swsdp - patch.siteLoadPatch.description - 0 - ${version.schema} - 10000 - ${sample.site.disabled} - - - - - - - - - - - - - swsdp - - - - - - alfresco/bootstrap/team-sample-sites/swsdp/Users.acp - - - - - alfresco/bootstrap/team-sample-sites/swsdp/People.acp - - - - - alfresco/bootstrap/team-sample-sites/swsdp/Groups.txt - - - - - alfresco/bootstrap/team-sample-sites/swsdp/Contents.acp - - - - - - - - patch.exampleJavaScript - patch.exampleJavaScript.description - 0 - ${version.schema} - 10000 - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname} - alfresco/bootstrap/example_javascripts2.acp - alfresco/messages/bootstrap-spaces - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/varchar-field-sizes-quadruple-increasing.sql - - - - - patch.fixAclInheritance - patch.fixAclInheritance.description - 0 - 5005 - 5006 - - - - - - - - - - - - - - - - patch.db-V3.4-JBPM-FK-indexes - patch.schemaUpgradeScript.description - 0 - 5005 - 5006 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoPostCreate-JBPM-FK-indexes.sql - - - - - patch.imap.clear.old.messages - patch.imap.clear.old.messages.description - 0 - 5005 - 5006 - - - - - - - patch.imap.clear.old.messages - patch.imap.clear.old.messages.description - 0 - 5005 - 5006 - - - - - - - patch.imapSpacesTemplates2 - patch.imapSpacesLocaleTemplates2.description - 0 - 5005 - 5006 - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.imapConfig.childname}/${spaces.imap_templates.childname} - alfresco/bootstrap/imapSpacesTemplates.xml - alfresco/messages/bootstrap-spaces - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/AclChangeSet-Tracking.sql - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/NodeAssoc-Ordering.sql - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/Node-Locale.sql - - - - - patch.db-V4.0-SubscriptionTables - patch.schemaUpgradeScript.description - 0 - 5010 - 5011 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-SubscriptionTables.sql - - - - - - patch.avmToAdmRemoteStore - patch.avmToAdmRemoteStore.description - 0 - 5011 - 5012 - false - - - - - - - sitestore - /alfresco/site-data - - - - - - - - - - - patch.copiedFromAspect - patch.copiedFromAspect.description - 0 - 5012 - 5013 - false - false - - - - - - - - - - - - - - patch.workflowNotification - patch.workflowNotification.description - 0 - 5014 - 5015 - - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.workflowemailnotification.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} - alfresco/bootstrap/notification/workflow-email-notification.xml - alfresco/messages/bootstrap-spaces - - - - - - - patch.nodeTemplatesFolder - patch.nodeTemplatesFolder.description - 0 - 5015 - 5016 - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.nodetemplates.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname} - alfresco/bootstrap/nodeTemplatesSpace.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.updateMimetypes3 - patch.updateMimetypes3.description - 0 - 5016 - 5017 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - patch.sitesSpacePermissions - patch.sitesSpacePermissions.description - 0 - 5017 - 5018 - true - true - - - - - - patch.updateWorkflowNotificationTemplates - patch.updateWorkflowNotificationTemplates.description - 0 - 5018 - 5019 - true - true - - - - - - patch.updateMimetypes4 - patch.updateMimetypes4.description - 0 - 5019 - 5020 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - patch.updateMimetypesWMA - patch.updateMimetypesWMA.description - 0 - 5020 - 5021 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - patch.updateFollowingEmailTemplatesPatch - patch.updateFollowingEmailTemplatesPatch.description - 0 - 5021 - 5022 - true - true - - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/Solr-Tracking.sql - - - - - patch.addDutchEmailTemplatesPatch - patch.addDutchEmailTemplatesPatch.description - 0 - 5023 - 5024 - true - true - - - - - - - patch.fixBpmPackages - patch.fixBpmPackages.description - 0 - 5024 - 5025 - - - - - - - - - - patch.db-V3.4-Upgrade-JBPM - patch.schemaUpgradeScript.description - 0 - 2017 - 6001 - - - - - - - classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/jbpm-upgrade.sql - - - - - patch.db-V3.4-alter-jBPM331-CLOB-columns-to-nvarchar - patch.alterJBPM331CLOBcolumnsToNvarchar.description - 0 - 6000 - 6001 - - - - - - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/alter-jBPM331-CLOB-columns-to-nvarchar.sql - - - - - patch.imapUnsubscribedAspect - patch.imapUnsubscribedAspect.description - 0 - 6001 - 6002 - - - - - - - - - - - - - patch.db-V3.4-AVM-index-child-entries-lower - patch.avmIndexChildEntriesLower.description - 0 - 6002 - 6003 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/AVM-index-child-entries-lower.sql - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/ActivitiTaskIdIndexes.sql - - - - - patch.db-V4.0-TenantTables - patch.schemaUpgradeScript.description - 0 - 6004 - 6005 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-TenantTables.sql - - - - - patch.remoteCredentialsContainer - patch.remoteCredentialsContainer.description - 0 - 6005 - 6006 - - - - - - - - - - /${system.system_container.childname}/${system.remote_credentials_container.childname} - - - - /${system.system_container.childname} - alfresco/bootstrap/remoteCredentialsSpace.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.syncSetDefinitionsContainer - patch.syncSetDefinitionsContainer.description - 0 - 6005 - 6006 - - - - - - - - - - /${system.system_container.childname}/${system.syncset_definition_container.childname} - - - - /${system.system_container.childname} - alfresco/bootstrap/syncSetDefinitionsSpace.xml - alfresco/messages/bootstrap-spaces - - - - - - patch.migrateTenantsFromAttrsToTable - patch.migrateTenantsFromAttrsToTable.description - 0 - 6006 - 6007 - false - - - - - - - - - - - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/AclChangeSet-Tracking2.sql - - - - - patch.swsdpPatch - patch.swsdpPatch.description - 0 - 6007 - 6008 - - - - - - - patch.redeployParallelActivitiWorkflows - patch.redeployParallelActivitiWorkflows.description - 0 - 6009 - 6010 - - - - patch.db-V3.4-remove-redundant-jbpm-indexes - patch.schemaUpgradeScript.description - 0 - 6010 - 6011 - - classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/remove-redundant-jbpm-indexes.sql - - - - - patch.show.audit - patch.show.audit.description - 0 - 6011 - 6012 - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname}/cm:show_audit.ftl - - - alfresco/templates/content/examples/show_audit.ftl - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/increase-column-size-activiti.sql - - - - - patch.updateMimetypesSVG - patch.updateMimetypesSVG.description - 0 - 6013 - 6014 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - patch.db-V4.1-NodeDeleted - patch.schemaUpgradeScript.description - 0 - 6014 - 6015 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/NodeDeleted.sql - - - - - patch.updateMimetypesVISIO - patch.updateMimetypesVISIO.description - 0 - 6015 - 6016 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - patch.db-V3.4-JBPM-varinst-indexes - patch.schemaUpgradeScript.description - 0 - 6016 - 6017 - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoPostCreate-JBPM-varinst-indexes.sql - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/remove-column-activiti.sql - - - - - patch.db-V4.2-upgrade-to-activiti-5.10 - patch.upgradeToActiviti5-10.description - 0 - 6018 - 6019 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/activiti-upgrade-5-10.sql - - - - - patch.emailAliasableAspect - patch.emailAliasableAspect.description - 0 - 6019 - 6020 - - - - - - - - - - - - - - - - - - - patch.db-V4.1-rename-constraint-activiti - patch.renameConstraintActiviti.description - 0 - 6020 - 6021 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/rename-constraint-activiti.sql - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/add-activti-index-historic-activity.sql - - - - - patch.db-V4.2-upgrade-to-activiti-5.11 - patch.upgradeToActiviti5-11.description - 0 - 6022 - 6023 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/activiti-upgrade-5-11.sql - - - - - - - - - - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/dropAlfQnameFKIndexes.sql - - - - - - - 0 - 6024 - 6025 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/remove-index-acl_id.sql - - - - - - - 0 - 6025 - 6026 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/drop-activiti-feed-format.sql - - - - - patch.calendarAllDayEventDatesCorrectingPatch - patch.calendarAllDayEventDatesCorrectingPatch.description - 0 - 6026 - 6027 - 1000 - true - - - - - - - - - - - patch.sharedFolder - patch.sharedFolder.description - 0 - 6023 - 6024 - true - - - - - - /${spaces.company_home.childname}/${spaces.shared.childname} - - - - /${spaces.company_home.childname}/cm:shared - - - - /${spaces.company_home.childname} - alfresco/bootstrap/sharedSpace.xml - alfresco/messages/bootstrap-spaces - - - - ${system.patch.sharedFolder.deferred} - - - - patch.db-V4.2-metadata-query-indexes - patch.db-V4.2-metadata-query-indexes.description - 0 - 6025 - 6026 - ${system.metadata-query-indexes.ignored} - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/metadata-query-indexes.sql - - - - - patch.redeployActivitiWorkflowsForCategory - patch.redeployActivitiWorkflowsForCategory.description - 0 - 6027 - 6028 - - - - activiti - alfresco/workflow/invitation-moderated.bpmn20.xml - text/xml - - - activiti - alfresco/workflow/invitation-nominated.bpmn20.xml - text/xml - - - activiti - alfresco/workflow/publish-web-content.bpmn20.xml - text/xml - - - - - - - patch.db-V4.2-upgrade-to-activiti-5.13 - patch.upgradeToActiviti5-13.description - 0 - 6028 - 6029 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/activiti-upgrade-5-13.sql - - - - - patch.db-V4.2-remove-old-index-act - patch.db-V4.2-remove-old-index-act.description - 0 - 6027 - 6028 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/remove-old-index-act.sql - - - - - patch.redeployParallelActivitiWorkflows-after-5-11-upgrade - patch.redeployParallelActivitiWorkflows.description - 0 - 6029 - 6030 - - - - activiti - alfresco/workflow/parallel-review.bpmn20.xml - text/xml - - - activiti - alfresco/workflow/parallel-review-group.bpmn20.xml - text/xml - - - - - - - - - 0 - 6030 - 6031 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/fix-Repo-seqs-order.sql - - - - - - - 0 - 6030 - 6031 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/fix-AVM-seqs-order.sql - - - - - - - 0 - 6031 - 6032 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/drop-AVM-index.sql - - - - patch.db-V4.1-ChildAssoc-OrderBy - patch.schemaUpgradeScript.description - 0 - 6032 - 6033 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/ChildAssoc-OrderBy.sql - - - - - patch.db-V4.1-createIdxAlfNodeTQN - patch.schemaUpgradeScript.description - 0 - 7000 - 7001 - - classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/createIdxAlfNodeTQN.sql - - - - - - - 0 - 7001 - 7002 - - classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/restructure-idx_alf_nprop_s-MSSQL.sql - - - - - patch.siteAdministrators - patch.siteAdministrators.description - 0 - 7002 - 7003 - - - - - - - - - - - - SITE_ADMINISTRATORS - - - SITE_ADMINISTRATORS - - - ${alfresco_user_store.adminusername} - - - - APP.DEFAULT - AUTH.ALF - - - - - - - - patch.alfrescoSearchAdministrators - patch.alfrescoSearchAdministrators.description - 0 - 7003 - 7004 - - - - - - - - - - - - ALFRESCO_SEARCH_ADMINISTRATORS - - - ALFRESCO_SEARCH_ADMINISTRATORS - - - ${alfresco_user_store.adminusername} - - - - APP.DEFAULT - AUTH.ALF - - - - - - - - - patch.surfConfigFolder - patch.surfConfigFolderPatch.description - 0 - 7004 - 7005 - false - false - - ${system.patch.surfConfigFolder.deferred} - - - - - - - - ${system.patch.surfConfigFolder.deferred} - - - - patch.renameSiteAuthorityDisplayName - - - patch.renameSiteAuthorityDisplayName.description - - - 0 - - - 8000 - - - 8001 - - - - - - - - - - - - - - - - + + + + + + + + org.alfresco.repo.admin.patch.PatchService + + + + + + + + + + + + + + + + PROPAGATION_NOT_SUPPORTED + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${system.workflow.deployWorkflowsInTenant} + + + + + + Sample01 + A NO-OP sample patch + 0 + 1000 + 1001 + + + Sample02 + A NO-OP sample patch + 0 + 1000 + 1001 + + + + + + + + Sample03 + A NO-OP sample patch + 0 + 1000 + 1001 + false + + + + + + + + + + alfresco/messages/bootstrap-spaces + + + + + + + + + + patch.savedSearchesFolder + patch.savedSearchesFolder.description + 0 + 1 + 2 + + 3.3 + + + + patch.savedSearchesPermission + patch.savedSearchesPermission.description + 0 + 4 + 5 + + 3.3 + + + + patch.updatePermissionData + patch.updatePermissionData.description + 0 + 2 + 3 + + 3.3 + + + + patch.guestUser + patch.guestUser.description + 0 + 2 + 3 + + 3.3 + + + + patch.fixNodeSerializableValues + patch.fixNodeSerializableValues.description + 0 + 3 + 4 + + 3.2 + + + + patch.updateGuestPermission + patch.updateGuestPermission.description + 0 + 5 + 6 + + 3.3 + + + + patch.guestPersonPermission + patch.guestPersonPermission.description + 0 + 5 + 6 + + + patch.spacesRootPermission + patch.spacesRootPermission.description + 0 + 5 + 6 + + 3.3 + + + + patch.categoryRootPermission + patch.categoryRootPermission.description + 0 + 5 + 6 + + 3.3 + + + + patch.contentPermission + patch.contentPermission.description + 0 + 6 + 7 + + 3.3 + + + + patch.forumsIcons + patch.forumsIcons.description + 0 + 12 + 13 + + 3.3 + + + + patch.emailTemplatesFolder + patch.emailTemplatesFolder.description + 0 + 12 + 13 + + 3.3 + + + + patch.emailTemplatesContent + patch.emailTemplatesContent.description + 0 + 12 + 13 + + 3.3 + + + + patch.descriptorUpdate + patch.descriptorUpdate.description + 0 + 11 + 12 + + 3.3 + + + + patch.scriptsFolder + patch.scriptsFolder.description + 0 + 12 + 13 + + 3.3 + + + + patch.topLevelGroupParentChildAssociationTypePatch + patch.topLevelGroupParentChildAssociationTypePatch.description + 0 + 13 + 14 + + 3.3 + + + + patch.actionRuleDecouplingPatch + patch.actionRuleDecouplingPatch.description + 0 + 14 + 15 + + 3.3 + + + + patch.systemWorkflowFolderPatch + patch.systemWorkflowFolder.description + 0 + 15 + 16 + + 3.3 + + + + patch.rssFolder + patch.rssTemplatesFolder.description + 0 + 16 + 17 + + 3.3 + + + + patch.uifacetsTemplates + patch.uifacetsAspectRemovalPatch.description + 0 + 17 + 18 + + 3.3 + + + + patch.guestPersonPermission2 + patch.guestPersonPermission2.description + 0 + 18 + 19 + + 3.3 + + + + patch.schemaUpdateScript-V1.4-1 + patch.schemaUpgradeScript.description + 0 + 19 + 20 + + 3.3.x + + + + patch.uniqueChildName + patch.uniqueChildName.description + 0 + 19 + 20 + + 2.1.4 + + + + patch.schemaUpdateScript-V1.4-2 + patch.schemaUpgradeScript.description + 0 + 20 + 21 + + 3.3.x + + + + patch.InvalidNameEnding + patch.invalidNameEnding.description + 0 + 21 + 22 + + 3.3.x + + + + patch.systemDescriptorContent + patch.systemDescriptorContent.description + 0 + 22 + 23 + + 3.3 + + + + patch.versionHistoryPerformance + patch.versionHistoryPerformance.description + 0 + 38 + 39 + + 3.3 + + + + patch.multilingualBootstrap + patch.multilingualBootstrap.description + 0 + 29 + 30 + + 3.3 + + + + patch.LinkNodeFileExtension + patch.linkNodeExtension.description + 0 + 33 + 34 + + 3.3 + + + + patch.systemRegistryBootstrap + patch.systemRegistryBootstrap.description + 0 + 34 + 35 + + 3.3 + + + + patch.userAndPersonUserNamesAsIdentifiers + patch.userAndPersonUserNamesAsIdentifiers.description + 0 + 35 + 36 + + 3.3 + + + + patch.contentFormFolderType + patch.contentFormFolderType.description + 0 + 36 + 37 + + 3.3 + + + + patch.db-V2.1-JBPMUpdate + patch.schemaUpgradeScript.description + 0 + 51 + 52 + + 3.3 + + + + patch.db-V2.1-NotNullColumns + patch.schemaUpgradeScript.description + 0 + 51 + 52 + + 3.3 + + + + patch.groupNamesAsIdentifiers + patch.groupNamesAsIdentifiers.description + 0 + 51 + 52 + + 3.3 + + + + patch.invalidUserPersonAndGroup + patch.invalidUserPersonAndGroup.description + 0 + 51 + 52 + + 3.3 + + + + patch.AVMGuidPatch + patch.AVMGuidPatch.description + 0 + 51 + 52 + + 3.3 + + + + patch.webscripts + patch.webscripts.description + 0 + 50 + 51 + + 3.3 + + + + patch.webscriptsExtension + patch.webscriptsExtension.description + 0 + 54 + 55 + + 3.3 + + + + patch.AVMLayeredSnapshot + patch.AVMLayeredSnapshot.description + 0 + 55 + 56 + + 3.3 + + + + patch.groupMembersAsIdentifiers + patch.groupMembersAsIdentifiers.description + 0 + 56 + 57 + + 3.3 + + + + patch.redeploySubmitProcess + patch.redeploySubmitProcess.description + 0 + 57 + 58 + + 3.3 + + + + patch.ReadmeTemplate + patch.ReadmeTemplate.description + 0 + 59 + 60 + + 3.3 + + + + patch.webScriptsReadme + patch.webScriptsReadme.description + 0 + 59 + 60 + + 3.3 + + + + patch.db-V2.1-JBPMProcessKey + patch.schemaUpgradeScript.description + 0 + 62 + 63 + + 3.3 + + + + patch.db-V2.1-VersionColumns2 + patch.schemaUpgradeScript.description + 0 + 63 + 64 + + 3.3 + + + + patch.db-V1.4-TxnCommitTimeIndex + patch.schemaUpgradeScript.description + 0 + 110 + 111 + + 3.3.x + + + + patch.db-V2.0-ContentUrls + patch.schemaUpgradeScript.description + 0 + 123 + 124 + + 3.3.x + + + + patch.webscripts2 + patch.webscripts2.description + 0 + 100 + 101 + + 3.4.x + + + + patch.customModels + patch.customModels.description + 0 + 101 + 102 + + 3.4.x + + + + patch.customMessages + patch.customMessages.description + 0 + 101 + 102 + + 3.4.x + + + + patch.customWebClientExtension + patch.customWebClientExtension.description + 0 + 101 + 102 + + 3.4.x + + + + patch.redeploySubmitProcess + patch.redeploySubmitProcess.description + 0 + 102 + 103 + + 3.4.x + + + + patch.db-V2.1-RemoveWcmSubmittedAspect + patch.schemaUpgradeScript.description + 0 + 103 + 104 + + 3.4.x + + + + patch.webscripts3 + patch.webscripts3.description + 0 + 104 + 105 + + 3.4.x + + + + patch.customWorkflowDefs + patch.customWorkflowDefs.description + 0 + 105 + 106 + + 3.4.x + + + + patch.avmStoreAsIdentifier + patch.avmStoreAsIdentifier.description + 0 + 109 + 110 + + 3.4.x + + + + patch.avmFormPropertyIdentifier + patch.avmFormPropertyIdentifier.description + 0 + 111 + 112 + + 3.4.x + + + + patch.formsFolder + patch.formsFolder.description + 0 + 112 + 113 + + 3.4.x + + + + patch.tagRootCategory + patch.tagRootCategory.description + 0 + 113 + 114 + + 3.4.x + + + + patch.db-V3.4-UsageTables + patch.schemaUpgradeScript.description + 0 + 113 + 114 + + 3.4.x + + + + patch.deploymentMigration + patch.deploymentMigration.description + 0 + 116 + 117 + + 3.4.x + + + + patch.redeploySubmitProcess + patch.redeploySubmitProcess.description + 0 + 117 + 118 + + 3.4.x + + + + + + + + + patch.db-V2.2-ACL-From-2.1-A + patch.schemaUpgradeScript.description + 0 + ${V2.1-A.fixes.to.schema} + 120 + + + + + + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-2.1-A--to--2.2-ACL.sql + + + + + patch.db-V2.2-ACL + patch.schemaUpgradeScript.description + 0 + 119 + 120 + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-2.2-ACL.sql + + + + + patch.updateAvmPermissionData + patch.updateAvmPermissionData.description + 0 + 119 + 120 + + + + + + + + + + + + patch.db-V2.2-CleanNodeStatuses + patch.schemaUpgradeScript.description + 0 + 89 + 90 + + + + + + + + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-2.2-CleanNodeStatuses.sql + + + + patch.db-V2.2-0-CreateMissingTables + patch.schemaUpgradeScript.description + 0 + 120 + 121 + + + + + + + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/upgrade-0-create-missing-tables.sql + + + + patch.db-V2.2-2-MoveQNames + patch.noOpPatch.description + 0 + 120 + 121 + + + patch.db-V2.2-Upgrade-From-2.1 + patch.schemaUpgradeScript.description + 0 + 120 + 135 + + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/upgrade-from-2.1.sql + + + + patch.db-V2.2-Upgrade-From-2.2SP1 + patch.schemaUpgradeScript.description + 0 + 134 + 135 + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/upgrade-from-2.2SP1.sql + + + + + patch.avmWebProjectInheritPermissions02 + patch.avmWebProjectInheritPermissions.description + 0 + 122 + 123 + + + + + + + + + + + + + + + patch.updateDmPermissions + patch.updateDmPermissions.description + 0 + 124 + 125 + + + + + + + + + + + + + + + + + + patch.db-V3.0-0-CreateActivitiesExtras + patch.db-V3.0-0-CreateActivitiesExtras.description + 0 + 125 + 126 + + + + + + + + patch.db-V3.0-ActivityTables + patch.schemaUpgradeScript.description + 0 + 125 + 126 + + + + + + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-ActivityTables.sql + + + + + patch.createSiteStore + patch.noOpPatch.description + 0 + 126 + 127 + + + + patch.sitesFolder + patch.sitesFolder.description + 0 + 127 + 128 + + + + + + + + + + /${spaces.company_home.childname}/st:sites + + + + /${spaces.company_home.childname} + alfresco/bootstrap/sitesSpace.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.sitePermissionRefactorPatch + patch.sitePermissionRefactorPatch.description + 0 + 128 + 129 + + + + + + + + + + + + + + + + + + + patch.migrateVersionStore + patch.migrateVersionStore.description + 0 + 129 + 130 + + + + + + + + + + + + + + + + + + + ${version.store.migrateVersionStore.threadCount} + + + ${version.store.migrateVersionStore.batchSize} + + + ${version.store.migrateVersionStore.runAsScheduledJob} + + + ${version.store.migrateVersionStore.limitPerJobCycle} + + + false + + + + + patch.inviteEmailTemplate + patch.inviteEmailTemplate.description + 0 + 130 + 131 + + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} + alfresco/bootstrap/invite/invite-email.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.calendarNamespaceUri + patch.calendarModelNamespacePatch.description + 0 + 131 + 132 + + + + + + + + + + + + + + + + + + + + + patch.db-V2.1-AuditPathIndex + patch.schemaUpgradeScript.description + 0 + 132 + 133 + + + + patch.spacesStoreGuestPermission + patch.spacesStoreGuestPermission.description + 0 + 133 + 134 + + + + + + + + + + + + + + + + patch.redeploySubmitProcess4 + patch.redeploySubmitProcess.description + 0 + 1000 + 1001 + + + + + + + + + + + jbpm + alfresco/workflow/submit_processdefinition.xml + text/xml + + + + + + + patch.redeploySubmitProcess5 + patch.redeploySubmitProcess.description + 0 + 2000 + 2001 + + + + + + + + + + jbpm + alfresco/workflow/submit_processdefinition.xml + text/xml + + + + + + + patch.deploySubmitDirectProcess + patch.deploySubmitDirectProcess.description + 0 + 2000 + 2001 + + + + + + + + + + jbpm + alfresco/workflow/submitdirect_processdefinition.xml + text/xml + + + + + + + + + + + + + + + + + + + patch.redeploySubmitProcess6 + patch.redeploySubmitProcess.description + 0 + 2002 + 2003 + + + + + + + + + jbpm + alfresco/workflow/submit_processdefinition.xml + text/xml + + + jbpm + alfresco/workflow/submitdirect_processdefinition.xml + text/xml + + + + + + + patch.redeploySubmitProcess7 + patch.redeploySubmitProcess.description + 0 + 2003 + 2004 + + + + + + + + + jbpm + alfresco/workflow/submit_processdefinition.xml + text/xml + + + jbpm + alfresco/workflow/submitdirect_processdefinition.xml + text/xml + + + + + + + patch.db-V2.2-Person-3 + patch.schemaUpgradeScript.description + 0 + 3002 + 3003 + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AlfrescoSchemaUpdate-Person.sql + + + + + patch.webSiteAddModerated + patch.webSiteAddModerated.description + 0 + 2006 + 2007 + + + + + + + + + + + + + + + + + + patch.invitationMigration + patch.invitationMigration.description + 0 + 2006 + 2007 + + + + + + + + + + + + + + + patch.db-V3.2-Remove-AVM-Issuer + patch.schemaUpgradeScript.description + 0 + 2007 + 2008 + + classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/remove-AVM-issuer.sql + + + + + patch.mtShareExistingTenants + patch.mtShareExistingTenants.description + 0 + 2008 + 2009 + true + + + + + + + + + + + + + + + jbpm + alfresco/workflow/invitation-nominated_processdefinition.xml + text/xml + + + jbpm + alfresco/workflow/invitation-moderated_processdefinition.xml + text/xml + + + + + + + patch.redeployInvitationProcess + patch.redeployInvitationProcess.description + 0 + 2009 + 2010 + + + + + + + + + jbpm + alfresco/workflow/invitation-moderated_processdefinition.xml + text/xml + + + jbpm + alfresco/workflow/invitation-nominated_processdefinition.xml + text/xml + + + + + + + patch.db-V3.2-LockTables + patch.schemaUpgradeScript.description + 0 + 2010 + 2011 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-LockTables.sql + + + + + patch.zonedAuthorities + patch.zonedAuthorities.description + 0 + 2011 + 2012 + + + + + + + + + + /${system.system_container.childname}/${system.authorities_container.childname} + + + + /${system.system_container.childname} + alfresco/bootstrap/alfrescoAuthorityStore.xml + + + + + + patch.authorityMigration + patch.authorityMigration.description + 0 + 2012 + 2013 + + + + + + + + + + + + + + + + + + + + patch.authorityDefaultZonesPatch + patch.authorityDefaultZonesPatch.description + 0 + 2013 + 2014 + + + + + + + + + + + + + + + + + + + + patch.db-V3.2-ContentTables + patch.schemaUpgradeScript.description + 0 + 2015 + 2016 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-ContentTables.sql + + + + + patch.db-V3.2-Modify-AVM-MimeType + patch.schemaUpgradeScript.description + 0 + 2016 + 2017 + + classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/modify-AVM-mimetype.sql + + + + + patch.imapFolders + patch.imapFolders.description + 0 + 2018 + 2019 + + + + + + + + + + + + + + + alfresco/templates/imap/imap_config_space.acp + alfresco/templates/imap/email_actions_space.acp + alfresco/templates/imap/command_processor_scripts.acp + + + + patch.db-V3.2-PropertyValueTables + patch.schemaUpgradeScript.description + 0 + 3000 + 3001 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-PropertyValueTables.sql + + + + + patch.db-V3.2-AuditTables + patch.schemaUpgradeScript.description + 0 + 3001 + 3002 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-AuditTables.sql + + + + + patch.db-V3.1-Allow-IPv6 + patch.schemaUpgradeScript.description + 0 + 3003 + 3004 + + classpath:alfresco/dbscripts/upgrade/3.1/${db.script.dialect}/IPv6-patch.sql + + + + + patch.personUsagePatch + patch.personUsagePatch.description + 0 + 3004 + 3005 + + + + + + + patch.db-V3.2-Child-Assoc-QName-CRC + patch.schemaUpgradeScript.description + 0 + 3005 + 3006 + + classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/child-assoc-qname-crc.sql + + + + + patch.fixNameCrcValues-2 + patch.fixNameCrcValues.description + 0 + 3006 + 3007 + false + + + + + + + + + + + + + + + + + + + patch.redeployNominatedInvitationProcessWithPropsForShare + patch.redeployNominatedInvitationProcessWithPropsForShare.description + 0 + 4000 + 4001 + + + + + + + + + jbpm + alfresco/workflow/invitation-nominated_processdefinition.xml + text/xml + + + + + + + patch.redeployJbpmAdhocWorkflow + patch.redeployJbpmAdhocWorkflow.description + 0 + 4204 + 4205 + + + + + + + + + jbpm + alfresco/workflow/adhoc_processdefinition.xml + text/xml + + + + + + + patch.db-V3.2-ContentTables2 + patch.schemaUpgradeScript.description + 0 + 4001 + 4002 + + + + + + + classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/AlfrescoSchemaUpdate-3.2-ContentTables2.sql + + + + + patch.db-V3.3-Remove-VersionCount + patch.schemaUpgradeScript.description + 0 + 4002 + 4003 + + classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/remove-VersionCount.sql + + + + + patch.rendition.rendering_actions + patch.rendition.rendering_actions.description + 0 + 4003 + 4004 + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.rendition.rendering_actions.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname} + alfresco/bootstrap/renderingActionSpace.xml + alfresco/messages/bootstrap-spaces + + + + + + + patch.thumbnailsAssocQName + patch.thumbnailsAssocQName.description + 0 + 4004 + 4005 + + + + + + + + + + + + + + {http://www.alfresco.org/model/content/1.0}thumbnails + + + {http://www.alfresco.org/model/rendition/1.0}rendition + + + + + + patch.emailInviteAndNotifyTemplatesFolder + patch.emailInviteAndNotifyTemplatesFolder.description + 0 + 4006 + 4007 + + + + + + + + + + + + + + + patch.transferServiceFolder + patch.transferDefinitions.description + 0 + 4008 + 4009 + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.transfers.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname} + alfresco/bootstrap/transferSpaces.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.convertContentUrls + patch.convertContentUrls.description + 0 + 4007 + 4008 + false + + + + + + + + + + + + + + + + + + patch.db-V3.4-authority-unique-idx + patch.schemaUpgradeScript.description + 0 + 4099 + 4100 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/authority-unique-idx.sql + + + + + patch.fixAuthoritiesCrcValues + patch.fixAuthoritiesCrcValues.description + 0 + 4100 + 4101 + false + + + + + + + + + + + + + patch.updateMimetypes1 + patch.updateMimetypes1.description + 0 + 4101 + 4102 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + patch.db-V3.3-modify-index-permission_id + patch.schemaUpgradeScript.description + 0 + 4102 + 4103 + + classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/modify-index-permission_id.sql + + + + + patch.db-V3.2-AddFKIndexes + patch.schemaUpgradeScript.description + 3007 + 4103 + 4104 + + classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AddFKIndexes.sql + + + + + patch.db-V3.3-Fix-Repo-Seqs + patch.schemaUpgradeScript.description + 0 + 4104 + 4105 + + classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/fix-Repo-seqs.sql + + + + + patch.db-V3.3-Fix-AVM-Seqs + patch.schemaUpgradeScript.description + 0 + 4104 + 4105 + + classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/fix-AVM-seqs.sql + + + + + patch.db-V3.4-property-unique-ctx-value + patch.schemaUpgradeScript.description + 0 + 4104 + 4105 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/property-unique-ctx-value.sql + + + + patch.db-V3.4-property-unique-ctx-idx + patch.schemaUpgradeScript.description + 0 + 4104 + 4105 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/property-unique-ctx-idx.sql + + + + + + + + + + patch.db-V3.4-child-assoc-indexes + patch.schemaUpgradeScript.description + 0 + 4104 + 4105 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/child-assoc-indexes.sql + + + + + patch.db-V3.3-JBPM-Extra + patch.schemaUpgradeScript.description + 0 + 4105 + 4106 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoPostCreate-JBPM-Extra.sql + + + + + patch.db-V3.3-Node-Prop-Serializable + patch.schemaUpgradeScript.description + 0 + 4105 + 4106 + + classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/node-prop-serializable.sql + + + + + + patch.migrateAttrTenants + patch.migrateAttrTenants.description + 0 + 0 + 1 + false + + + + + + + + + + + + + + patch.migrateAttrAVMLocks + patch.migrateAttrAVMLocks.description + 0 + 4106 + 4107 + false + + + + + + + + + + + + + + + patch.migrateAttrPropBackedBeans + patch.migrateAttrPropBackedBeans.description + 0 + 4106 + 4107 + false + + + + + + + + + + + + + + patch.migrateAttrChainingURS + patch.migrateAttrChainingURS.description + 0 + 4106 + 4107 + false + + + + + + + + + + + + + + patch.migrateAttrDelete + patch.noOpPatch.description + 0 + 4106 + 4107 + + + patch.migrateAttrDropOldTables + patch.migrateAttrDropOldTables.description + 0 + 5006 + 5007 + false + + + + + + + + + + + + + + + patch.replication.replication_actions + patch.replication.replication_actions.description + 0 + 4107 + 4108 + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.replication.replication_actions.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname} + alfresco/bootstrap/replicationActionSpace.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.transfer.targetrulefolder + patch.transfer.targetrulefolder.description + 0 + 4108 + 4109 + + + + + + + + + + + /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default/rule:ruleFolder + + + + /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default + alfresco/bootstrap/transferTargetRuleFolder.xml + + + + + + patch.transfer.targetrule + patch.transfer.targetrule.description + 0 + 4108 + 4109 + + + + + + + + + + + /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default/rule:ruleFolder/rule:rules3245de8b-2cfe-42ed-8f8b-44089f99b265 + + + + /app:company_home/app:dictionary/app:transfers/app:transfer_groups/cm:default/rule:ruleFolder + alfresco/bootstrap/transferTargetRule.xml + + + + + + patch.actions.scheduledfolder + patch.actions.scheduledfolder.description + 0 + 4109 + 4110 + + + + + + + + + + /app:company_home/app:dictionary/cm:Scheduled_x0020_Actions + + + + /app:company_home/app:dictionary + alfresco/bootstrap/scheduledActionsFolder.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.publishing.root + patch.publishing.root.description + 0 + 5013 + 5014 + + + + + + + + + + ${publishing.root} + + + + ${publishing.root.path} + alfresco/bootstrap/publishingRootFolder.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.updateMimetypes2 + patch.updateMimetypes2.description + 0 + 4110 + 4111 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + patch.db-V3.2-AddFKIndexes-2 + patch.schemaUpgradeScript.description + 0 + 4111 + 4112 + + classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/AlfrescoSchemaUpdate-3.2-AddFKIndexes-2.sql + + + + + + + + + + + + + + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/link-validation-metadata-removing.sql + + + + + patch.mtFixAdminExistingTenants + patch.mtFixAdminExistingTenants.description + + + + + + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.models.childname} + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.workflow.definitions.childname} + + + + + + patch.fixUserQNames + patch.fixUserQNames.description + + + + + + + + + + + + + + + + + + + + + + patch.db-V3.2-Upgrade-JBPM + patch.noOpPatch.description + 0 + 2017 + 2018 + + + + + + + + + patch.db-V3.4-AVM-rename-dupes + patch.schemaUpgradeScript.description + 0 + 5005 + 5006 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/AVM-rename-dupes.sql + + + + + patch.activitiesEmailTemplate + patch.activitiesEmailTemplate.description + 0 + 5005 + 5006 + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.activities.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} + alfresco/templates/activities-email-templates.xml + alfresco/messages/bootstrap-spaces + + + + + + + patch.activitiesTemplatesUpdate + + + patch.activitiesTemplatesUpdate.description + + + + + + + + + + + + + + + + patch.followingMailTemplates + patch.followingMailTemplates.description + 0 + 5010 + 5011 + + + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} + alfresco/templates/following-email-templates.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.newUserEmailTemplates + patch.newUserEmailTemplates.description + 0 + 5005 + 5006 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} + alfresco/templates/new-user-templates.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.inviteEmailTemplates + patch.inviteEmailTemplates.description + 0 + 5005 + 5006 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} + alfresco/templates/invite-email-templates.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.htmlNotificationMailTemplates + patch.htmlNotificationMailTemplates.description + 0 + 5005 + 5006 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.notify.childname} + alfresco/templates/notify_email_templates.xml + alfresco/messages/bootstrap-spaces + + + + + + + patch.imapSpacesLocaleTemplates + patch.noOpPatch.description + 0 + 4302 + 4305 + + + + + patch.siteLoadPatch.swsdp + patch.siteLoadPatch.description + 0 + ${version.schema} + 10000 + ${sample.site.disabled} + + + + + + + + + + + + + swsdp + + + + + + alfresco/bootstrap/team-sample-sites/swsdp/Users.acp + + + + + alfresco/bootstrap/team-sample-sites/swsdp/People.acp + + + + + alfresco/bootstrap/team-sample-sites/swsdp/Groups.txt + + + + + alfresco/bootstrap/team-sample-sites/swsdp/Contents.acp + + + + + + + + patch.exampleJavaScript + patch.exampleJavaScript.description + 0 + ${version.schema} + 10000 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.scripts.childname} + alfresco/bootstrap/example_javascripts2.acp + alfresco/messages/bootstrap-spaces + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/varchar-field-sizes-quadruple-increasing.sql + + + + + patch.fixAclInheritance + patch.fixAclInheritance.description + 0 + 5005 + 5006 + + + + + + + + + + + + + + + + patch.db-V3.4-JBPM-FK-indexes + patch.schemaUpgradeScript.description + 0 + 5005 + 5006 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoPostCreate-JBPM-FK-indexes.sql + + + + + patch.imap.clear.old.messages + patch.imap.clear.old.messages.description + 0 + 5005 + 5006 + + + + + + + patch.imap.clear.old.messages + patch.imap.clear.old.messages.description + 0 + 5005 + 5006 + + + + + + + patch.imapSpacesTemplates2 + patch.imapSpacesLocaleTemplates2.description + 0 + 5005 + 5006 + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.imapConfig.childname}/${spaces.imap_templates.childname} + alfresco/bootstrap/imapSpacesTemplates.xml + alfresco/messages/bootstrap-spaces + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/AclChangeSet-Tracking.sql + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/NodeAssoc-Ordering.sql + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/Node-Locale.sql + + + + + patch.db-V4.0-SubscriptionTables + patch.schemaUpgradeScript.description + 0 + 5010 + 5011 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-SubscriptionTables.sql + + + + + + patch.avmToAdmRemoteStore + patch.avmToAdmRemoteStore.description + 0 + 5011 + 5012 + false + + + + + + + sitestore + /alfresco/site-data + + + + + + + + + + + patch.copiedFromAspect + patch.copiedFromAspect.description + 0 + 5012 + 5013 + false + false + + + + + + + + + + + + + + patch.workflowNotification + patch.workflowNotification.description + 0 + 5014 + 5015 + + + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.workflowemailnotification.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} + alfresco/bootstrap/notification/workflow-email-notification.xml + alfresco/messages/bootstrap-spaces + + + + + + + patch.nodeTemplatesFolder + patch.nodeTemplatesFolder.description + 0 + 5015 + 5016 + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.nodetemplates.childname} + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname} + alfresco/bootstrap/nodeTemplatesSpace.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.updateMimetypes3 + patch.updateMimetypes3.description + 0 + 5016 + 5017 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + patch.sitesSpacePermissions + patch.sitesSpacePermissions.description + 0 + 5017 + 5018 + true + true + + + + + + patch.updateWorkflowNotificationTemplates + patch.updateWorkflowNotificationTemplates.description + 0 + 5018 + 5019 + true + true + + + + + + patch.updateMimetypes4 + patch.updateMimetypes4.description + 0 + 5019 + 5020 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + patch.updateMimetypesWMA + patch.updateMimetypesWMA.description + 0 + 5020 + 5021 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + patch.updateFollowingEmailTemplatesPatch + patch.updateFollowingEmailTemplatesPatch.description + 0 + 5021 + 5022 + true + true + + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/Solr-Tracking.sql + + + + + patch.addDutchEmailTemplatesPatch + patch.addDutchEmailTemplatesPatch.description + 0 + 5023 + 5024 + true + true + + + + + + + patch.fixBpmPackages + patch.fixBpmPackages.description + 0 + 5024 + 5025 + + + + + + + + + + patch.db-V3.4-Upgrade-JBPM + patch.schemaUpgradeScript.description + 0 + 2017 + 6001 + + + + + + + classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/jbpm-upgrade.sql + + + + + patch.db-V3.4-alter-jBPM331-CLOB-columns-to-nvarchar + patch.alterJBPM331CLOBcolumnsToNvarchar.description + 0 + 6000 + 6001 + + + + + + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/alter-jBPM331-CLOB-columns-to-nvarchar.sql + + + + + patch.imapUnsubscribedAspect + patch.imapUnsubscribedAspect.description + 0 + 6001 + 6002 + + + + + + + + + + + + + patch.db-V3.4-AVM-index-child-entries-lower + patch.avmIndexChildEntriesLower.description + 0 + 6002 + 6003 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/AVM-index-child-entries-lower.sql + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/ActivitiTaskIdIndexes.sql + + + + + patch.db-V4.0-TenantTables + patch.schemaUpgradeScript.description + 0 + 6004 + 6005 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-TenantTables.sql + + + + + patch.remoteCredentialsContainer + patch.remoteCredentialsContainer.description + 0 + 6005 + 6006 + + + + + + + + + + /${system.system_container.childname}/${system.remote_credentials_container.childname} + + + + /${system.system_container.childname} + alfresco/bootstrap/remoteCredentialsSpace.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.syncSetDefinitionsContainer + patch.syncSetDefinitionsContainer.description + 0 + 6005 + 6006 + + + + + + + + + + /${system.system_container.childname}/${system.syncset_definition_container.childname} + + + + /${system.system_container.childname} + alfresco/bootstrap/syncSetDefinitionsSpace.xml + alfresco/messages/bootstrap-spaces + + + + + + patch.migrateTenantsFromAttrsToTable + patch.migrateTenantsFromAttrsToTable.description + 0 + 6006 + 6007 + false + + + + + + + + + + + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.0/${db.script.dialect}/AclChangeSet-Tracking2.sql + + + + + patch.swsdpPatch + patch.swsdpPatch.description + 0 + 6007 + 6008 + + + + + + + patch.redeployParallelActivitiWorkflows + patch.redeployParallelActivitiWorkflows.description + 0 + 6009 + 6010 + + + + patch.db-V3.4-remove-redundant-jbpm-indexes + patch.schemaUpgradeScript.description + 0 + 6010 + 6011 + + classpath:alfresco/dbscripts/upgrade/3.4/${db.script.dialect}/remove-redundant-jbpm-indexes.sql + + + + + patch.show.audit + patch.show.audit.description + 0 + 6011 + 6012 + + + + + + + + + /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.content.childname}/cm:show_audit.ftl + + + alfresco/templates/content/examples/show_audit.ftl + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/increase-column-size-activiti.sql + + + + + patch.updateMimetypesSVG + patch.updateMimetypesSVG.description + 0 + 6013 + 6014 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + patch.db-V4.1-NodeDeleted + patch.schemaUpgradeScript.description + 0 + 6014 + 6015 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/NodeDeleted.sql + + + + + patch.updateMimetypesVISIO + patch.updateMimetypesVISIO.description + 0 + 6015 + 6016 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + patch.db-V3.4-JBPM-varinst-indexes + patch.schemaUpgradeScript.description + 0 + 6016 + 6017 + + classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoPostCreate-JBPM-varinst-indexes.sql + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/remove-column-activiti.sql + + + + + patch.db-V4.2-upgrade-to-activiti-5.10 + patch.upgradeToActiviti5-10.description + 0 + 6018 + 6019 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/activiti-upgrade-5-10.sql + + + + + patch.emailAliasableAspect + patch.emailAliasableAspect.description + 0 + 6019 + 6020 + + + + + + + + + + + + + + + + + + + patch.db-V4.1-rename-constraint-activiti + patch.renameConstraintActiviti.description + 0 + 6020 + 6021 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/rename-constraint-activiti.sql + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/add-activti-index-historic-activity.sql + + + + + patch.db-V4.2-upgrade-to-activiti-5.11 + patch.upgradeToActiviti5-11.description + 0 + 6022 + 6023 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/activiti-upgrade-5-11.sql + + + + + + + + + + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/dropAlfQnameFKIndexes.sql + + + + + + + 0 + 6024 + 6025 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/remove-index-acl_id.sql + + + + + + + 0 + 6025 + 6026 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/drop-activiti-feed-format.sql + + + + + patch.calendarAllDayEventDatesCorrectingPatch + patch.calendarAllDayEventDatesCorrectingPatch.description + 0 + 6026 + 6027 + 1000 + true + + + + + + + + + + + patch.sharedFolder + patch.sharedFolder.description + 0 + 6023 + 6024 + true + + + + + + /${spaces.company_home.childname}/${spaces.shared.childname} + + + + /${spaces.company_home.childname}/cm:shared + + + + /${spaces.company_home.childname} + alfresco/bootstrap/sharedSpace.xml + alfresco/messages/bootstrap-spaces + + + + ${system.patch.sharedFolder.deferred} + + + + patch.db-V4.2-metadata-query-indexes + patch.db-V4.2-metadata-query-indexes.description + 0 + 6025 + 6026 + ${system.metadata-query-indexes.ignored} + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/metadata-query-indexes.sql + + + + + patch.redeployActivitiWorkflowsForCategory + patch.redeployActivitiWorkflowsForCategory.description + 0 + 6027 + 6028 + + + + activiti + alfresco/workflow/invitation-moderated.bpmn20.xml + text/xml + + + activiti + alfresco/workflow/invitation-nominated.bpmn20.xml + text/xml + + + activiti + alfresco/workflow/publish-web-content.bpmn20.xml + text/xml + + + + + + + patch.db-V4.2-upgrade-to-activiti-5.13 + patch.upgradeToActiviti5-13.description + 0 + 6028 + 6029 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/activiti-upgrade-5-13.sql + + + + + patch.db-V4.2-remove-old-index-act + patch.db-V4.2-remove-old-index-act.description + 0 + 6027 + 6028 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/remove-old-index-act.sql + + + + + patch.redeployParallelActivitiWorkflows-after-5-11-upgrade + patch.redeployParallelActivitiWorkflows.description + 0 + 6029 + 6030 + + + + activiti + alfresco/workflow/parallel-review.bpmn20.xml + text/xml + + + activiti + alfresco/workflow/parallel-review-group.bpmn20.xml + text/xml + + + + + + + + + 0 + 6030 + 6031 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/fix-Repo-seqs-order.sql + + + + + + + 0 + 6030 + 6031 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/fix-AVM-seqs-order.sql + + + + + + + 0 + 6031 + 6032 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/drop-AVM-index.sql + + + + patch.db-V4.1-ChildAssoc-OrderBy + patch.schemaUpgradeScript.description + 0 + 6032 + 6033 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/ChildAssoc-OrderBy.sql + + + + + patch.db-V4.1-createIdxAlfNodeTQN + patch.schemaUpgradeScript.description + 0 + 7000 + 7001 + + classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/createIdxAlfNodeTQN.sql + + + + + + + 0 + 7001 + 7002 + + classpath:alfresco/dbscripts/upgrade/4.2/${db.script.dialect}/restructure-idx_alf_nprop_s-MSSQL.sql + + + + + patch.siteAdministrators + patch.siteAdministrators.description + 0 + 7002 + 7003 + + + + + + + + + + + + SITE_ADMINISTRATORS + + + SITE_ADMINISTRATORS + + + ${alfresco_user_store.adminusername} + + + + APP.DEFAULT + AUTH.ALF + + + + + + + + patch.alfrescoSearchAdministrators + patch.alfrescoSearchAdministrators.description + 0 + 7003 + 7004 + + + + + + + + + + + + ALFRESCO_SEARCH_ADMINISTRATORS + + + ALFRESCO_SEARCH_ADMINISTRATORS + + + ${alfresco_user_store.adminusername} + + + + APP.DEFAULT + AUTH.ALF + + + + + + + + + patch.surfConfigFolder + patch.surfConfigFolderPatch.description + 0 + 7004 + 7005 + false + false + + ${system.patch.surfConfigFolder.deferred} + + + + + + + + ${system.patch.surfConfigFolder.deferred} + + + + patch.renameSiteAuthorityDisplayName + + + patch.renameSiteAuthorityDisplayName.description + + + 0 + + + 8000 + + + 8001 + + + + + + + + + + + + + + + + diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml index 5b58620c01..153120f0b7 100644 --- a/config/alfresco/public-services-context.xml +++ b/config/alfresco/public-services-context.xml @@ -1,1541 +1,1552 @@ - - - - - - - - - - - - - - - - - - - org.alfresco.service.descriptor.DescriptorService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.alfresco.service.cmr.repository.NodeService - - - - - - - - - - - - - - - - - - - - - - setProperty - removeProperty - - - - - {http://www.alfresco.org/model/webdav/1.0}opaquelocktoken - {http://www.alfresco.org/model/webdav/1.0}lockDepth - {http://www.alfresco.org/model/webdav/1.0}lockScope - {http://www.alfresco.org/model/webdav/1.0}sharedLockTokens - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.repository.ContentService - - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - - - - - - - - - - - - - - - - - org.alfresco.service.cmr.search.SearchService - - - - - - - - - - - - - - - - - org.alfresco.service.cmr.search.SearchService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.search.CategoryService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.repository.CopyService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.lock.LockService - - - - - - - - - - - - - - - - - - - lock - unlock - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - - - - - org.alfresco.service.cmr.version.VersionService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - - org.alfresco.service.cmr.coci.CheckOutCheckInService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.rule.RuleService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.view.ImporterService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.view.ExporterService - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.action.ActionService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.security.PermissionService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.security.AuthorityService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.security.OwnableService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.security.PersonService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.usage.ContentUsageService - - - - - - - - - - - - - - - - - - - - - PROPAGATION_SUPPORTS - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.security.MutableAuthenticationService - - - - - - - - - - - - - - - - - - - - - PROPAGATION_NOT_SUPPORTED, readOnly - PROPAGATION_NOT_SUPPORTED, readOnly - PROPAGATION_NOT_SUPPORTED, readOnly - PROPAGATION_NOT_SUPPORTED, readOnly - PROPAGATION_NOT_SUPPORTED, readOnly - PROPAGATION_NOT_SUPPORTED, readOnly - - PROPAGATION_REQUIRED, readOnly - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.repository.TemplateService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.repository.ScriptService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - org.alfresco.service.cmr.model.FileFolderService - - - - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - copy - - - - - - - - org.alfresco.service.cmr.repository.CrossRepositoryCopyService - - - - crossRepositoryCopyService - - - - crossRepositoryCopyServiceWriteTxnAdvisor - checkTxnAdvisor - - - - - - - - - - - - - - org.alfresco.service.cmr.avm.AVMService - - - - avmLockingAwareService - - - - avmServiceWriteTxnAdvisor - avmServiceReadTxnAdvisor - checkTxnAdvisor - avmSnapShotTriggeredIndexingMethodInterceptor - - - - - - - - - org.alfresco.service.cmr.avm.AVMService - - - - avmLockingAwareService - - - - avmSnapShotTriggeredIndexingMethodInterceptor - - - - - - - - - org.alfresco.service.cmr.avm.AVMService - - - - - - - checkTxnAdvisor - - - - - - - - - - - - - - - - - - - - - - - - - - .* - - - - - - - - - - - getFileInputStream - getContentReader - getDirectoryListing - getDirectoryListingDirect - getDirectoryListingArray - getDeleted - getNextVersionID - getLatestSnapshotID - getStoreVersions - getStores - getStore - getStoreRoot - lookup - getPaths - getHeadPaths - getPathsInStoreHead - getPathsInStoreVersion - getIndirectionPath - getHistory - getCommonAncestor - getLayeringInfo - getNodeProperty - getNodeProperties - getStoreProperty - getStoreProperties - queryStorePropertyKey - queryStoresPropertyKeys - getContentDataForRead - getAspects - hasAspect - getAPath - getGuid - getStoreVersionsFrom - getStoreVersionsTo - getStoreVersionsBetween - - - - - - - - - - - getFileOutputStream - getContentWriter - createFile - createDirectory - createLayeredFile - createLayeredDirectory - retargetLayeredDirectory - createStore - createBranch - removeNode - rename - uncover - makeTransparent - createSnapshot - purgeStore - purgeVersion - makePrimary - setOpacity - setNodeProperty - setNodeProperties - deleteNodeProperty - deleteNodeProperties - setStoreProperty - setStoreProperties - deleteStoreProperty - getContentDataForWrite - setContentData - setMetaDataFrom - addAspect - removeAspect - link - forceCopy - copy - renameStore - getSystemStore - revert - setGuid - setEncoding - setMimeType - - - - - - - - org.alfresco.service.cmr.avm.AVMService - - - - avmService - - - - avmServiceWriteTxnAdvisor - avmServiceReadTxnAdvisor - checkTxnAdvisor - avmSnapShotTriggeredIndexingMethodInterceptor - - - - - - - - - org.alfresco.service.cmr.avm.AVMService - - - - avmService - - - - avmSnapShotTriggeredIndexingMethodInterceptor - - - - - - - - - - search.avmSnapShotTriggeredIndexingMethodInterceptor - - - - org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor - - - - - - - - - - - - - - - - - - - - - - - compare - - - - - - - - - - - - update - flatten - resetLayer - - - - - - - - org.alfresco.service.cmr.avmsync.AVMSyncService - - - - avmSyncService - - - - avmSyncServiceWriteTxnAdvisor - avmSyncServiceReadTxnAdvisor - checkTxnAdvisor - - - - - - - - - - - - - - exists - getAttribute - getAttributes - - - - - - - - - - - - setAttribute - createAttribute - updateOrCreateAttribute - removeAttribute - removeAttributes - - - - - - - - org.alfresco.service.cmr.attributes.AttributeService - - - - attributeService - - - - attributeServiceWriteTxnAdvisor - attributeServiceReadTxnAdvisor - checkTxnAdvisor - - - - - - - - - - - - - getLockOwner - getLockData - getLockState - hasAccess - - - - - - - - - - - lock - modifyLock - removeLock - removeLocks - - - - - - - - org.alfresco.service.cmr.avm.locking.AVMLockingService - - - - avmLockingService - - - - avmLockingServiceWriteTxnAdvisor - avmLockingServiceReadTxnAdvisor - checkTxnAdvisor - - - - - - - - - org.alfresco.service.cmr.workflow.WorkflowService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.audit.AuditService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - - org.alfresco.service.cmr.ml.MultilingualContentService - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - - org.alfresco.service.cmr.ml.EditionService - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.repo.configuration.ConfigurableService - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.repo.admin.registry.RegistryService - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.module.ModuleService - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.admin.RepoAdminService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - ${server.transaction.mode.default} - - - - - - - org.alfresco.service.cmr.action.scheduled.ScheduledPersistedActionService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - - - - - org.alfresco.service.cmr.security.PublicServiceAccessService - - - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.readOnly} - - - - - - - - - - org.alfresco.repo.tenant.TenantAdminService - - - - - - - - - - - - - - - - - - - ${server.transaction.mode.default} - - - - - + + + + + + + + + + + + + + + + + + + org.alfresco.service.descriptor.DescriptorService + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.alfresco.service.cmr.repository.NodeService + + + + + + + + + + + + + + + + + + + + + + setProperty + removeProperty + + + + + {http://www.alfresco.org/model/webdav/1.0}opaquelocktoken + {http://www.alfresco.org/model/webdav/1.0}lockDepth + {http://www.alfresco.org/model/webdav/1.0}lockScope + {http://www.alfresco.org/model/webdav/1.0}sharedLockTokens + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.repository.ContentService + + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + + + + + + + + + + + + + + + + + org.alfresco.service.cmr.search.SearchService + + + + + + + + + + + + + + + + + org.alfresco.service.cmr.search.SearchService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.search.CategoryService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.repository.CopyService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.lock.LockService + + + + + + + + + + + + + + + + + + + lock + unlock + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + + + + + org.alfresco.service.cmr.version.VersionService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + + org.alfresco.service.cmr.coci.CheckOutCheckInService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.rule.RuleService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.view.ImporterService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.view.ExporterService + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.action.ActionService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.security.PermissionService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.security.AuthorityService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.security.OwnableService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.security.PersonService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.usage.ContentUsageService + + + + + + + + + + + + + + + + + + + + + PROPAGATION_SUPPORTS + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.security.MutableAuthenticationService + + + + + + + + + + + + + + + + + + + + + PROPAGATION_NOT_SUPPORTED, readOnly + PROPAGATION_NOT_SUPPORTED, readOnly + PROPAGATION_NOT_SUPPORTED, readOnly + PROPAGATION_NOT_SUPPORTED, readOnly + PROPAGATION_NOT_SUPPORTED, readOnly + PROPAGATION_NOT_SUPPORTED, readOnly + + PROPAGATION_REQUIRED, readOnly + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.repository.TemplateService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.repository.ScriptService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + org.alfresco.service.cmr.model.FileFolderService + + + + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + copy + + + + + + + + org.alfresco.service.cmr.repository.CrossRepositoryCopyService + + + + crossRepositoryCopyService + + + + crossRepositoryCopyServiceWriteTxnAdvisor + checkTxnAdvisor + + + + + + + + + + + + + + org.alfresco.service.cmr.avm.AVMService + + + + avmLockingAwareService + + + + avmServiceWriteTxnAdvisor + avmServiceReadTxnAdvisor + checkTxnAdvisor + + + + + + + + + + org.alfresco.service.cmr.avm.AVMService + + + + avmLockingAwareService + + + + avmSnapShotTriggeredIndexingMethodInterceptor + + + + + + + + + org.alfresco.service.cmr.avm.AVMService + + + + + + + checkTxnAdvisor + + + + + + + + + + + + + + + + + + + + + + + + .* + + + + + + + + + + + getFileInputStream + getContentReader + getDirectoryListing + getDirectoryListingDirect + getDirectoryListingArray + getDeleted + getNextVersionID + getLatestSnapshotID + getStoreVersions + getStores + getStore + getStoreRoot + lookup + getPaths + getHeadPaths + getPathsInStoreHead + getPathsInStoreVersion + getIndirectionPath + getHistory + getCommonAncestor + getLayeringInfo + getNodeProperty + getNodeProperties + getStoreProperty + getStoreProperties + queryStorePropertyKey + queryStoresPropertyKeys + getContentDataForRead + getAspects + hasAspect + getAPath + getGuid + getStoreVersionsFrom + getStoreVersionsTo + getStoreVersionsBetween + + + + + + + + + + + getFileOutputStream + getContentWriter + createFile + createDirectory + createLayeredFile + createLayeredDirectory + retargetLayeredDirectory + createStore + createBranch + removeNode + rename + uncover + makeTransparent + createSnapshot + purgeStore + purgeVersion + makePrimary + setOpacity + setNodeProperty + setNodeProperties + deleteNodeProperty + deleteNodeProperties + setStoreProperty + setStoreProperties + deleteStoreProperty + getContentDataForWrite + setContentData + setMetaDataFrom + addAspect + removeAspect + link + forceCopy + copy + renameStore + getSystemStore + revert + setGuid + setEncoding + setMimeType + + + + + + + + org.alfresco.service.cmr.avm.AVMService + + + + avmService + + + + avmServiceWriteTxnAdvisor + avmServiceReadTxnAdvisor + checkTxnAdvisor + + + + + + + + + + org.alfresco.service.cmr.avm.AVMService + + + + avmService + + + + avmSnapShotTriggeredIndexingMethodInterceptor + + + + + + + + + + + + + + + + + + + + + compare + + + + + + + + + + + + update + flatten + resetLayer + + + + + + + + org.alfresco.service.cmr.avmsync.AVMSyncService + + + + avmSyncService + + + + avmSyncServiceWriteTxnAdvisor + avmSyncServiceReadTxnAdvisor + checkTxnAdvisor + + + + + + + + + + + + + + exists + getAttribute + getAttributes + + + + + + + + + + + + setAttribute + createAttribute + updateOrCreateAttribute + removeAttribute + removeAttributes + + + + + + + + org.alfresco.service.cmr.attributes.AttributeService + + + + attributeService + + + + attributeServiceWriteTxnAdvisor + attributeServiceReadTxnAdvisor + checkTxnAdvisor + + + + + + + + + + + + + getLockOwner + getLockData + getLockState + hasAccess + + + + + + + + + + + lock + modifyLock + removeLock + removeLocks + + + + + + + + org.alfresco.service.cmr.avm.locking.AVMLockingService + + + + avmLockingService + + + + avmLockingServiceWriteTxnAdvisor + avmLockingServiceReadTxnAdvisor + checkTxnAdvisor + + + + + + + + + org.alfresco.service.cmr.workflow.WorkflowService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.audit.AuditService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + + org.alfresco.service.cmr.ml.MultilingualContentService + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + + org.alfresco.service.cmr.ml.EditionService + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.repo.configuration.ConfigurableService + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.repo.admin.registry.RegistryService + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.module.ModuleService + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.admin.RepoAdminService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + ${server.transaction.mode.default} + + + + + + + org.alfresco.service.cmr.action.scheduled.ScheduledPersistedActionService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + + + + + org.alfresco.service.cmr.security.PublicServiceAccessService + + + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.readOnly} + + + + + + + + + + org.alfresco.repo.tenant.TenantAdminService + + + + + + + + + + + + + + + + + + + ${server.transaction.mode.default} + + + + + diff --git a/config/alfresco/subsystems/Search/common-search-context.xml b/config/alfresco/subsystems/Search/common-search-context.xml index 7ebff1a2fd..6cfb6a15de 100644 --- a/config/alfresco/subsystems/Search/common-search-context.xml +++ b/config/alfresco/subsystems/Search/common-search-context.xml @@ -43,6 +43,7 @@ + diff --git a/config/alfresco/subsystems/Search/lucene/bootstrap-context.xml b/config/alfresco/subsystems/Search/lucene/bootstrap-context.xml index 8ad563d64e..1351a6ac64 100644 --- a/config/alfresco/subsystems/Search/lucene/bootstrap-context.xml +++ b/config/alfresco/subsystems/Search/lucene/bootstrap-context.xml @@ -11,12 +11,13 @@ + diff --git a/config/alfresco/subsystems/Search/lucene/index-recovery-context.xml b/config/alfresco/subsystems/Search/lucene/index-recovery-context.xml index 47617ea2e6..e9163ae0c7 100644 --- a/config/alfresco/subsystems/Search/lucene/index-recovery-context.xml +++ b/config/alfresco/subsystems/Search/lucene/index-recovery-context.xml @@ -78,6 +78,7 @@ + @@ -154,7 +156,8 @@ - + + @@ -194,6 +197,7 @@ ${system.cronJob.startDelayMinutes} + --> @@ -111,7 +113,9 @@ - + @@ -121,7 +125,9 @@ + @@ -134,7 +140,9 @@ + @@ -341,6 +349,7 @@ + + + + @@ -478,8 +490,10 @@ + diff --git a/config/alfresco/subsystems/Search/lucene/opencmis-context.xml b/config/alfresco/subsystems/Search/lucene/opencmis-context.xml index e51c255c7b..577fbbab91 100644 --- a/config/alfresco/subsystems/Search/lucene/opencmis-context.xml +++ b/config/alfresco/subsystems/Search/lucene/opencmis-context.xml @@ -26,7 +26,9 @@ + @@ -39,7 +41,9 @@ + diff --git a/config/alfresco/subsystems/fileServers/default/network-protocol-context.xml b/config/alfresco/subsystems/fileServers/default/network-protocol-context.xml index 6aa52d18a5..1931085a5c 100644 --- a/config/alfresco/subsystems/fileServers/default/network-protocol-context.xml +++ b/config/alfresco/subsystems/fileServers/default/network-protocol-context.xml @@ -40,9 +40,11 @@ + @@ -438,6 +440,7 @@ + + diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 967cbab9f8..3898f055ee 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -23,4 +23,4 @@ version.build=r@scm-revision@-b@build-number@ # Schema number -version.schema=8001 +version.schema=8002 diff --git a/source/java/org/alfresco/repo/admin/ConfigurationChecker.java b/source/java/org/alfresco/repo/admin/ConfigurationChecker.java index f593b154a2..10b9715a41 100644 --- a/source/java/org/alfresco/repo/admin/ConfigurationChecker.java +++ b/source/java/org/alfresco/repo/admin/ConfigurationChecker.java @@ -1,296 +1,296 @@ -/* - * Copyright (C) 2005-2013 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin; - -import java.io.File; -import java.util.List; -import java.util.Properties; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; -import org.alfresco.repo.importer.ImporterBootstrap; -import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.transaction.TransactionService; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationEvent; -import org.springframework.extensions.surf.util.AbstractLifecycleBean; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Component to perform a bootstrap check of the alignment of the - * database, Lucene indexes and content store. - *

- * The algorithm is: - *

    - *
  • Get all stores from the NodeService
  • - *
  • Get each root node
  • - *
  • Perform a Lucene query for each root node
  • - *
  • Query Lucene for a small set of content nodes
  • - *
  • Get content readers for each node
  • - *
- * If any of the steps fail then the bootstrap bean will fail, except if - * the indexes are marked for full recovery. In this case, the Lucene - * checks are not required as the indexes will be due for a rebuild. - * - * @author Derek Hulley - */ -public class ConfigurationChecker extends AbstractLifecycleBean -{ - private static Log logger = LogFactory.getLog(ConfigurationChecker.class); - - private static final String WARN_RELATIVE_DIR_ROOT = "system.config_check.warn.dir_root"; - private static final String MSG_DIR_ROOT = "system.config_check.msg.dir_root"; - static final String ERR_MISSING_INDEXES = "system.config_check.err.missing_index"; - private static final String ERR_MISSING_CONTENT = "system.config_check.err.missing_content"; - static final String ERR_FIX_DIR_ROOT = "system.config_check.err.fix_dir_root"; - static final String MSG_HOWTO_INDEX_RECOVER = "system.config_check.msg.howto_index_recover"; - static final String WARN_STARTING_WITH_ERRORS = "system.config_check.warn.starting_with_errors"; - - private boolean strict; - private RecoveryMode indexRecoveryMode; - private String dirRoot; - - private ImporterBootstrap systemBootstrap; - private TransactionService transactionService; - private NamespaceService namespaceService; - private NodeService nodeService; - private SearchService searchService; - private ContentService contentService; - private IndexConfigurationChecker indexConfigurationChecker; - - public ConfigurationChecker() - { - } - - @Override - public String toString() - { - StringBuilder sb = new StringBuilder(50); - sb.append("ConfigurationChecker") - .append("[indexRecoveryMode=").append(indexRecoveryMode) - .append("]"); - return sb.toString(); - } - - /** - * This flag controls the behaviour of the component in the event of problems being found. - * Generally, the system should be strict, but this can be changed if indexes are - * going to be recovered, or if missing content is acceptable. - * - * @param strict true to prevent system startup if problems are found, otherwise - * false to allow the system to startup regardless. - */ - public void setStrict(boolean strict) - { - this.strict = strict; - } - - /** - * Set the index recovery mode. If this is - * {@link org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode#VALIDATE FULL} - * then the index checks are ignored as the indexes will be scheduled for a rebuild - * anyway. - * - * @see org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode - */ - public void setIndexRecoveryMode(String indexRecoveryMode) - { - this.indexRecoveryMode = RecoveryMode.valueOf(indexRecoveryMode); - } - - public void setDirRoot(String dirRoot) - { - this.dirRoot = dirRoot; - } - - public void setSystemBootstrap(ImporterBootstrap systemBootstrap) - { - this.systemBootstrap = systemBootstrap; - } - - public void setTransactionService(TransactionService transactionService) - { - this.transactionService = transactionService; - } - - public void setNamespaceService(NamespaceService namespaceService) - { - this.namespaceService = namespaceService; - } - - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - public void setSearchService(SearchService searchService) - { - this.searchService = searchService; - } - - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - public void setIndexConfigurationChecker(IndexConfigurationChecker indexConfigurationChecker) - { - this.indexConfigurationChecker = indexConfigurationChecker; - } - - @Override - protected void onBootstrap(ApplicationEvent event) - { - RetryingTransactionCallback checkWork = new RetryingTransactionCallback() - { - public Object execute() throws Throwable { - // run as System on bootstrap - return AuthenticationUtil.runAs(new RunAsWork() - { - public Object doWork() - { - check(); - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - }; - transactionService.getRetryingTransactionHelper().doInTransaction(checkWork, true); - } - - /** - * Performs the check work. - */ - private void check() - { - if (logger.isDebugEnabled()) - { - logger.debug("Starting bootstrap configuration check: " + this); - } - - // check the dir.root - boolean isRelativeRoot = dirRoot.startsWith("."); - if (isRelativeRoot) - { - String msg = I18NUtil.getMessage(WARN_RELATIVE_DIR_ROOT, dirRoot); - logger.warn(msg); - } - File dirRootFile = new File(dirRoot); - String msgDirRoot = I18NUtil.getMessage(MSG_DIR_ROOT, dirRootFile); - logger.info(msgDirRoot); - - List missingIndexStoreRefs = indexConfigurationChecker.checkIndexConfiguration(); - // check for the system version properties content snippet - boolean versionPropertiesContentAvailable = true; - NodeRef descriptorNodeRef = getSystemDescriptor(); - if (descriptorNodeRef != null) - { - // get the version properties - ContentReader reader = contentService.getReader( - descriptorNodeRef, - ContentModel.PROP_SYS_VERSION_PROPERTIES); - if (reader != null && !reader.exists()) - { - // the property is there, but the content is not - versionPropertiesContentAvailable = false; - } - } - - // check for missing indexes - int missingStoreIndexes = missingIndexStoreRefs.size(); - if (missingStoreIndexes > 0) - { - String msg = I18NUtil.getMessage(ERR_MISSING_INDEXES, missingStoreIndexes); - logger.error(msg); - - for (StoreRef missingIndexStoreRef : missingIndexStoreRefs) - { - logger.error("---> "+missingIndexStoreRef); - } - - String msgRecover = I18NUtil.getMessage(MSG_HOWTO_INDEX_RECOVER); - logger.info(msgRecover); - } - // check for missing content - if (!versionPropertiesContentAvailable) - { - String msg = I18NUtil.getMessage(ERR_MISSING_CONTENT); - logger.error(msg); - } - // handle either content or indexes missing - if (missingStoreIndexes > 0 || !versionPropertiesContentAvailable) - { - String msg = I18NUtil.getMessage(ERR_FIX_DIR_ROOT, dirRootFile); - logger.error(msg); - - // Now determine the failure behaviour - if (strict) - { - throw new AlfrescoRuntimeException(msg); - } - else - { - String warn = I18NUtil.getMessage(WARN_STARTING_WITH_ERRORS); - logger.warn(warn); - } - } - } - - - - /** - * @return Returns the system descriptor node or null - */ - public NodeRef getSystemDescriptor() - { - StoreRef systemStoreRef = systemBootstrap.getStoreRef(); - List nodeRefs = null; - if (nodeService.exists(systemStoreRef)) - { - Properties systemProperties = systemBootstrap.getConfiguration(); - String path = systemProperties.getProperty("system.descriptor.current.childname"); - String searchPath = "/" + path; - NodeRef rootNodeRef = nodeService.getRootNode(systemStoreRef); - nodeRefs = searchService.selectNodes(rootNodeRef, searchPath, null, namespaceService, false); - if (nodeRefs.size() > 0) - { - NodeRef descriptorNodeRef = nodeRefs.get(0); - return descriptorNodeRef; - } - } - return null; - } - - @Override - protected void onShutdown(ApplicationEvent event) - { - // nothing here - } -} +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.admin; + +import java.io.File; +import java.util.List; +import java.util.Properties; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.importer.ImporterBootstrap; +import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.transaction.TransactionService; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationEvent; +import org.springframework.extensions.surf.util.AbstractLifecycleBean; +import org.springframework.extensions.surf.util.I18NUtil; + +/** + * Component to perform a bootstrap check of the alignment of the + * database, Lucene indexes and content store. + *

+ * The algorithm is: + *

    + *
  • Get all stores from the NodeService
  • + *
  • Get each root node
  • + *
  • Perform a Lucene query for each root node
  • + *
  • Query Lucene for a small set of content nodes
  • + *
  • Get content readers for each node
  • + *
+ * If any of the steps fail then the bootstrap bean will fail, except if + * the indexes are marked for full recovery. In this case, the Lucene + * checks are not required as the indexes will be due for a rebuild. + * + * @author Derek Hulley + */ +public class ConfigurationChecker extends AbstractLifecycleBean +{ + private static Log logger = LogFactory.getLog(ConfigurationChecker.class); + + private static final String WARN_RELATIVE_DIR_ROOT = "system.config_check.warn.dir_root"; + private static final String MSG_DIR_ROOT = "system.config_check.msg.dir_root"; + static final String ERR_MISSING_INDEXES = "system.config_check.err.missing_index"; + private static final String ERR_MISSING_CONTENT = "system.config_check.err.missing_content"; + static final String ERR_FIX_DIR_ROOT = "system.config_check.err.fix_dir_root"; + static final String MSG_HOWTO_INDEX_RECOVER = "system.config_check.msg.howto_index_recover"; + static final String WARN_STARTING_WITH_ERRORS = "system.config_check.warn.starting_with_errors"; + + private boolean strict; + private RecoveryMode indexRecoveryMode; + private String dirRoot; + + private ImporterBootstrap systemBootstrap; + private TransactionService transactionService; + private NamespaceService namespaceService; + private NodeService nodeService; + private SearchService searchService; + private ContentService contentService; + private IndexConfigurationChecker indexConfigurationChecker; + + public ConfigurationChecker() + { + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(50); + sb.append("ConfigurationChecker") + .append("[indexRecoveryMode=").append(indexRecoveryMode) + .append("]"); + return sb.toString(); + } + + /** + * This flag controls the behaviour of the component in the event of problems being found. + * Generally, the system should be strict, but this can be changed if indexes are + * going to be recovered, or if missing content is acceptable. + * + * @param strict true to prevent system startup if problems are found, otherwise + * false to allow the system to startup regardless. + */ + public void setStrict(boolean strict) + { + this.strict = strict; + } + + /** + * Set the index recovery mode. If this is + * {@link org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode#VALIDATE FULL} + * then the index checks are ignored as the indexes will be scheduled for a rebuild + * anyway. + * + * @see org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode + */ + public void setIndexRecoveryMode(String indexRecoveryMode) + { + this.indexRecoveryMode = RecoveryMode.valueOf(indexRecoveryMode); + } + + public void setDirRoot(String dirRoot) + { + this.dirRoot = dirRoot; + } + + public void setSystemBootstrap(ImporterBootstrap systemBootstrap) + { + this.systemBootstrap = systemBootstrap; + } + + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } + + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + public void setIndexConfigurationChecker(IndexConfigurationChecker indexConfigurationChecker) + { + this.indexConfigurationChecker = indexConfigurationChecker; + } + + @Override + protected void onBootstrap(ApplicationEvent event) + { + RetryingTransactionCallback checkWork = new RetryingTransactionCallback() + { + public Object execute() throws Throwable { + // run as System on bootstrap + return AuthenticationUtil.runAs(new RunAsWork() + { + public Object doWork() + { + check(); + return null; + } + }, AuthenticationUtil.getSystemUserName()); + } + }; + transactionService.getRetryingTransactionHelper().doInTransaction(checkWork, true); + } + + /** + * Performs the check work. + */ + private void check() + { + if (logger.isDebugEnabled()) + { + logger.debug("Starting bootstrap configuration check: " + this); + } + + // check the dir.root + boolean isRelativeRoot = dirRoot.startsWith("."); + if (isRelativeRoot) + { + String msg = I18NUtil.getMessage(WARN_RELATIVE_DIR_ROOT, dirRoot); + logger.warn(msg); + } + File dirRootFile = new File(dirRoot); + String msgDirRoot = I18NUtil.getMessage(MSG_DIR_ROOT, dirRootFile); + logger.info(msgDirRoot); + + List missingIndexStoreRefs = indexConfigurationChecker.checkIndexConfiguration(); + // check for the system version properties content snippet + boolean versionPropertiesContentAvailable = true; + NodeRef descriptorNodeRef = getSystemDescriptor(); + if (descriptorNodeRef != null) + { + // get the version properties + ContentReader reader = contentService.getReader( + descriptorNodeRef, + ContentModel.PROP_SYS_VERSION_PROPERTIES); + if (reader != null && !reader.exists()) + { + // the property is there, but the content is not + versionPropertiesContentAvailable = false; + } + } + + // check for missing indexes + int missingStoreIndexes = missingIndexStoreRefs.size(); + if (missingStoreIndexes > 0) + { + String msg = I18NUtil.getMessage(ERR_MISSING_INDEXES, missingStoreIndexes); + logger.error(msg); + + for (StoreRef missingIndexStoreRef : missingIndexStoreRefs) + { + logger.error("---> "+missingIndexStoreRef); + } + + String msgRecover = I18NUtil.getMessage(MSG_HOWTO_INDEX_RECOVER); + logger.info(msgRecover); + } + // check for missing content + if (!versionPropertiesContentAvailable) + { + String msg = I18NUtil.getMessage(ERR_MISSING_CONTENT); + logger.error(msg); + } + // handle either content or indexes missing + if (missingStoreIndexes > 0 || !versionPropertiesContentAvailable) + { + String msg = I18NUtil.getMessage(ERR_FIX_DIR_ROOT, dirRootFile); + logger.error(msg); + + // Now determine the failure behaviour + if (strict) + { + throw new AlfrescoRuntimeException(msg); + } + else + { + String warn = I18NUtil.getMessage(WARN_STARTING_WITH_ERRORS); + logger.warn(warn); + } + } + } + + + + /** + * @return Returns the system descriptor node or null + */ + public NodeRef getSystemDescriptor() + { + StoreRef systemStoreRef = systemBootstrap.getStoreRef(); + List nodeRefs = null; + if (nodeService.exists(systemStoreRef)) + { + Properties systemProperties = systemBootstrap.getConfiguration(); + String path = systemProperties.getProperty("system.descriptor.current.childname"); + String searchPath = "/" + path; + NodeRef rootNodeRef = nodeService.getRootNode(systemStoreRef); + nodeRefs = searchService.selectNodes(rootNodeRef, searchPath, null, namespaceService, false); + if (nodeRefs.size() > 0) + { + NodeRef descriptorNodeRef = nodeRefs.get(0); + return descriptorNodeRef; + } + } + return null; + } + + @Override + protected void onShutdown(ApplicationEvent event) + { + // nothing here + } +} diff --git a/source/java/org/alfresco/repo/admin/IndexConfigurationCheckerImpl.java b/source/java/org/alfresco/repo/admin/IndexConfigurationCheckerImpl.java index 99535386bc..f1b3a37dd4 100644 --- a/source/java/org/alfresco/repo/admin/IndexConfigurationCheckerImpl.java +++ b/source/java/org/alfresco/repo/admin/IndexConfigurationCheckerImpl.java @@ -23,8 +23,6 @@ import java.util.List; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; -import org.alfresco.repo.search.IndexMode; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.InvalidStoreRefException; import org.alfresco.service.cmr.repository.NodeRef; @@ -51,7 +49,7 @@ public class IndexConfigurationCheckerImpl implements IndexConfigurationChecker private RecoveryMode indexRecoveryMode; private NodeService nodeService; private SearchService searchService; - private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; + //private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; /** * Set the index recovert mode @@ -87,10 +85,12 @@ public class IndexConfigurationCheckerImpl implements IndexConfigurationChecker * avm trigger * @param avmSnapShotTriggeredIndexingMethodInterceptor */ + /* Sparta: remove WCM/AVM public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) { this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; } + */ @@ -129,6 +129,7 @@ public class IndexConfigurationCheckerImpl implements IndexConfigurationChecker { if (storeRef.getProtocol().equals(StoreRef.PROTOCOL_AVM)) { + /* Sparta: remove WCM/AVM if (avmSnapShotTriggeredIndexingMethodInterceptor.isIndexingEnabled()) { IndexMode storeIndexMode = avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(storeRef.getIdentifier()); @@ -149,6 +150,7 @@ public class IndexConfigurationCheckerImpl implements IndexConfigurationChecker } continue; } + */ } if (logger.isDebugEnabled()) diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java index 8bf77ebac5..7afb36729e 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/ContentUrlConverterPatch.java @@ -21,7 +21,6 @@ package org.alfresco.repo.admin.patch.impl; import java.sql.Savepoint; import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.alfresco.error.AlfrescoRuntimeException; @@ -29,8 +28,6 @@ import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.admin.patch.PatchExecuter; import org.alfresco.repo.admin.registry.RegistryKey; import org.alfresco.repo.admin.registry.RegistryService; -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.PlainFileNode; import org.alfresco.repo.batch.BatchProcessor; import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorkerAdaptor; import org.alfresco.repo.content.ContentStore; @@ -39,14 +36,13 @@ import org.alfresco.repo.domain.contentdata.ContentDataDAO; import org.alfresco.repo.domain.control.ControlDAO; import org.alfresco.repo.domain.patch.PatchDAO; import org.alfresco.repo.lock.JobLockService; +import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback; import org.alfresco.repo.lock.LockAcquisitionException; -import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; @@ -316,8 +312,13 @@ public class ContentUrlConverterPatch extends AbstractPatch logger.info(I18NUtil.getMessage("patch.convertContentUrls.adm.start")); boolean admCompleted = applyADMLooping(running); + + /* Sparta: remove WCM/AVM logger.info(I18NUtil.getMessage("patch.convertContentUrls.avm.start")); boolean avmCompleted = applyAVMLooping(running); + */ + boolean avmCompleted = true; + logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.start", contentStore)); boolean urlLiftingCompleted = applyUrlLifting(running); @@ -468,6 +469,7 @@ public class ContentUrlConverterPatch extends AbstractPatch return false; } + /* private boolean applyAVMLooping(final AtomicBoolean running) { RetryingTransactionCallback callback = new RetryingTransactionCallback() @@ -488,10 +490,12 @@ public class ContentUrlConverterPatch extends AbstractPatch } return done; } + */ /** * Do the AVM conversion work */ + /* private boolean applyAVM() throws Exception { Long maxId = (Long) registryService.getProperty(KEY_AVM_MAX_ID); @@ -563,6 +567,7 @@ public class ContentUrlConverterPatch extends AbstractPatch // More to do return false; } + */ private boolean applyUrlLifting(final AtomicBoolean running) throws Exception { diff --git a/source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java deleted file mode 100644 index 7a8d3e8af2..0000000000 --- a/source/java/org/alfresco/repo/admin/patch/impl/MoveWCMToGroupBasedPermissionsPatch.java +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin.patch.impl; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.admin.patch.AbstractPatch; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptorImpl.StoreType; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.security.AccessPermission; -import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.AuthorityType; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Remove ACLs on all but staging area stores On staging area stores, set ACls according to the users and roles as set - * on the web site Note: runs as the system user - * - * @author andyh - */ -public class MoveWCMToGroupBasedPermissionsPatch extends AbstractPatch -{ - public static final String[] PERMISSIONS = new String[] - { - PermissionService.WCM_CONTENT_MANAGER, PermissionService.WCM_CONTENT_PUBLISHER, - PermissionService.WCM_CONTENT_CONTRIBUTOR, PermissionService.WCM_CONTENT_REVIEWER - }; - - protected static final String WCM_STORE_SEPARATOR = "--"; - - private static final String MSG_SUCCESS = "patch.moveWCMToGroupBasedPermissionsPatch.result"; - - AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; - - AVMService avmService; - - PermissionService permissionService; - - AuthorityService authorityService; - - String replaceAllWith = PermissionService.WCM_CONTENT_MANAGER; - - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - public void setAvmSnapShotTriggeredIndexingMethodInterceptor( - AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) - { - this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; - } - - public void setPermissionService(PermissionService permissionService) - { - this.permissionService = permissionService; - } - - public void setAuthorityService(AuthorityService authorityService) - { - this.authorityService = authorityService; - } - - public void setReplaceAllWith(String replaceAllWith) - { - this.replaceAllWith = replaceAllWith; - } - - @Override - protected String applyInternal() throws Exception - { - List stores = this.avmService.getStores(); - for (AVMStoreDescriptor store : stores) - { - - Map storeProperties = this.avmService.getStoreProperties(store.getName()); - - switch (StoreType.getStoreType(store.getName(), store, storeProperties)) - { - /* Set permissions in staging */ - case STAGING: - fixAllPermissions(store); - setStagingAreaPermissions(store); - setStagingAreaMasks(store); - // TODO: mark read only - break; - /* Clear permissions */ - case AUTHOR: - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case AUTHOR_WORKFLOW_PREVIEW: - fixAllStagingPermissions(store); - setSandBoxMasks(store); - break; - case STAGING_PREVIEW: - fixAllStagingPermissions(store); - setStagingAreaMasks(store); - // TODO: mark read only - break; - case WORKFLOW: - case WORKFLOW_PREVIEW: - break; - /* non WCM stores - nothing to do */ - case UNKNOWN: - default: - } - } - - // build the result message - String msg = I18NUtil.getMessage(MoveWCMToGroupBasedPermissionsPatch.MSG_SUCCESS); - // done - return msg; - } - - private boolean isPermissionSet(NodeRef nodeRef, String authority, String permission) - { - Set set = this.permissionService.getAllSetPermissions(nodeRef); - for (AccessPermission ap : set) - { - if (ap.getAuthority().equals(authority) && ap.isSetDirectly() && ap.getPermission().equals(permission)) - { - return true; - } - } - return false; - } - - private boolean isMaskSet(StoreRef storeRef, String authority, String permission) - { - Set set = this.permissionService.getAllSetPermissions(storeRef); - for (AccessPermission ap : set) - { - if (ap.getAuthority().equals(authority) && ap.isSetDirectly() && ap.getPermission().equals(permission)) - { - return true; - } - } - return false; - } - - private void makeGroupsIfRequired(String stagingStoreName, NodeRef dirRef) - { - for (String permission : MoveWCMToGroupBasedPermissionsPatch.PERMISSIONS) - { - String shortName = stagingStoreName + "-" + permission; - String group = this.authorityService.getName(AuthorityType.GROUP, shortName); - if (!this.authorityService.authorityExists(group)) - { - String newGroup = this.authorityService.createAuthority(AuthorityType.GROUP, shortName); - this.permissionService.setPermission(dirRef, newGroup, permission, true); - } - } - } - - protected void addToGroupIfRequired(String stagingStoreName, String user, String permission) - { - String shortName = stagingStoreName + "-" + permission; - String group = this.authorityService.getName(AuthorityType.GROUP, shortName); - Set members = this.authorityService.getContainedAuthorities(AuthorityType.USER, group, true); - if (!members.contains(user)) - { - this.authorityService.addAuthority(group, user); - } - } - - private void fixAllPermissions(AVMStoreDescriptor store) - { - fixAllPermissionsImpl(store.getName()); - } - - private void fixAllStagingPermissions(AVMStoreDescriptor store) - { - - String stagingAreaName = extractStagingAreaName(store.getName()); - fixAllPermissionsImpl(stagingAreaName); - } - - private void fixAllPermissionsImpl(String stagingStoreName) - { - QName propQName = QName.createQName(null, ".web_project.noderef"); - - PropertyValue pValue = this.avmService.getStoreProperty(stagingStoreName, propQName); - - if (pValue != null) - { - NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); - - // Apply sepcific user permissions as set on the web project - List userInfoRefs = this.nodeService.getChildAssocs(webProjectNodeRef, - WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - //String username = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); // not used - String userrole = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - if (userrole.equals(PermissionService.ALL_PERMISSIONS)) - { - this.nodeService.setProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE, this.replaceAllWith); - } - - } - } - } - - protected void setStagingAreaPermissions(AVMStoreDescriptor store) throws Exception - { - QName propQName = QName.createQName(null, ".web_project.noderef"); - - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, store.getName() + ":/www"); - - makeGroupsIfRequired(store.getName(), dirRef); - - if (!isPermissionSet(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ)) - { - this.permissionService.setPermission(dirRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, - true); - } - - // Add group permissions - for (String permission : MoveWCMToGroupBasedPermissionsPatch.PERMISSIONS) - { - String cms = this.authorityService.getName(AuthorityType.GROUP, store.getName() + "-" + permission); - this.permissionService.setPermission(dirRef, cms, permission, true); - } - - PropertyValue pValue = this.avmService.getStoreProperty(store.getName(), propQName); - - if (pValue != null) - { - NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); - - // Apply sepcific user permissions as set on the web project - List userInfoRefs = this.nodeService.getChildAssocs(webProjectNodeRef, - WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - // remove existing - - if (isPermissionSet(dirRef, username, userrole)) - { - this.permissionService.deletePermission(dirRef, username, userrole); - } - - addToGroupIfRequired(store.getName(), username, userrole); - } - } - } - - protected void setStagingAreaMasks(AVMStoreDescriptor store) - { - // groups must exist - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, store.getName() + ":/www"); - - if (!isMaskSet(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ)) - { - this.permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, - PermissionService.READ, true); - } - - String cms = this.authorityService.getName(AuthorityType.GROUP, store.getName() + "-" - + PermissionService.WCM_CONTENT_MANAGER); - if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.CHANGE_PERMISSIONS)) - { - this.permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.CHANGE_PERMISSIONS, true); - } - - if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.READ_PERMISSIONS)) - { - this.permissionService.setPermission(dirRef.getStoreRef(), cms, PermissionService.READ_PERMISSIONS, true); - } - - QName propQName = QName.createQName(null, ".web_project.noderef"); - - PropertyValue pValue = this.avmService.getStoreProperty(store.getName(), propQName); - - if (pValue != null) - { - NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); - - // Apply sepcific user permissions as set on the web project - List userInfoRefs = this.nodeService.getChildAssocs(webProjectNodeRef, - WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - if (userrole.equals(PermissionService.WCM_CONTENT_MANAGER)) - { - // remove existing - - if (isMaskSet(dirRef.getStoreRef(), username, PermissionService.CHANGE_PERMISSIONS)) - { - this.permissionService.deletePermission(dirRef.getStoreRef(), username, - PermissionService.CHANGE_PERMISSIONS); - } - - if (isMaskSet(dirRef.getStoreRef(), username, PermissionService.READ_PERMISSIONS)) - { - this.permissionService.deletePermission(dirRef.getStoreRef(), username, - PermissionService.READ_PERMISSIONS); - } - } - } - } - - } - - protected void setSandBoxMasks(AVMStoreDescriptor sandBoxStore) - { - // get the settings from the staging store ... - - String owner = extractOwner(sandBoxStore.getName()); - String stagingAreaName = extractStagingAreaName(sandBoxStore.getName()); - - QName propQName = QName.createQName(null, ".web_project.noderef"); - - NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, sandBoxStore.getName() + ":/www"); - - //Map woof = this.avmService.getStoreProperties(stagingAreaName); // not used - PropertyValue pValue = this.avmService.getStoreProperty(stagingAreaName, propQName); - - if (!isMaskSet(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ)) - { - this.permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, - PermissionService.READ, true); - } - - String cms = this.authorityService.getName(AuthorityType.GROUP, stagingAreaName + "-" - + PermissionService.WCM_CONTENT_MANAGER); - if (!isMaskSet(dirRef.getStoreRef(), cms, PermissionService.WCM_CONTENT_MANAGER)) - { - this.permissionService - .setPermission(dirRef.getStoreRef(), cms, PermissionService.WCM_CONTENT_MANAGER, true); - } - - if (pValue != null) - { - NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); - - // Apply sepcific user permissions as set on the web project - List userInfoRefs = this.nodeService.getChildAssocs(webProjectNodeRef, - WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - if (username.equals(owner)) - { - this.permissionService.setPermission(dirRef.getStoreRef(), username, - PermissionService.ALL_PERMISSIONS, true); - } - else if (userrole.equals("ContentManager")) - { - if (isMaskSet(dirRef.getStoreRef(), username, userrole)) - { - this.permissionService.deletePermission(dirRef.getStoreRef(), username, userrole); - } - } - } - } - } - - private String extractOwner(String name) - { - int start = name.indexOf(WCM_STORE_SEPARATOR); - if (start == -1) - { - throw new UnsupportedOperationException(name); - } - int end = name.indexOf(WCM_STORE_SEPARATOR, start + 1); - if (end == -1) - { - return name.substring(start + 2); - } - return name.substring(start + 2, end); - } - - protected String extractStagingAreaName(String name) - { - int index = name.indexOf(WCM_STORE_SEPARATOR); - if (index == -1) - { - throw new UnsupportedOperationException(name); - } - return name.substring(0, index); - } -} diff --git a/source/java/org/alfresco/repo/admin/patch/impl/ResetWCMToGroupBasedPermissionsPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/ResetWCMToGroupBasedPermissionsPatch.java deleted file mode 100644 index fcd44ff624..0000000000 --- a/source/java/org/alfresco/repo/admin/patch/impl/ResetWCMToGroupBasedPermissionsPatch.java +++ /dev/null @@ -1,1107 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin.patch.impl; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.avm.AVMChildEntryEntity; -import org.alfresco.repo.domain.avm.AVMNodeLinksDAO; -import org.alfresco.repo.domain.avm.AVMStoreDAO; -import org.alfresco.repo.domain.patch.PatchDAO; -import org.alfresco.repo.domain.permissions.AclCrudDAO; -import org.alfresco.repo.domain.permissions.AclEntity; -import org.alfresco.repo.domain.permissions.AclUpdateEntity; -import org.alfresco.repo.domain.permissions.Authority; -import org.alfresco.repo.domain.permissions.Permission; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptorImpl.StoreType; -import org.alfresco.repo.security.permissions.ACEType; -import org.alfresco.repo.security.permissions.ACLType; -import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; -import org.alfresco.service.cmr.admin.PatchException; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.AccessStatus; -import org.alfresco.service.cmr.security.AuthorityType; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.util.GUID; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Alternative patch to remove ACLs from all WCM stores, and replace with WCM group-based ACLs. - * - * @author janv - */ -public class ResetWCMToGroupBasedPermissionsPatch extends MoveWCMToGroupBasedPermissionsPatch -{ - private static Log logger = LogFactory.getLog(ResetWCMToGroupBasedPermissionsPatch.class); - - private static final String MSG_SUCCESS = "patch.resetWCMToGroupBasedPermissionsPatch.result"; - - private AclCrudDAO aclCrudDAO; - private AVMStoreDAO avmStoreDAO; - private AVMNodeLinksDAO avmNodeLinksDAO; - private PatchDAO patchDAO; - - private HelperDAO helper; // local helper class - - private PersonService personService; - - private static int batchSize = 500; - - // cache staging store acl change set and shared acl id - private Map> stagingData = new HashMap>(10); - - public void setPersonService(PersonService personService) - { - this.personService = personService; - } - - public void setAvmStoreDAO(AVMStoreDAO avmStoreDAO) - { - this.avmStoreDAO = avmStoreDAO; - } - - public void setAvmNodeLinksDAO(AVMNodeLinksDAO avmNodeLinksDAO) - { - this.avmNodeLinksDAO = avmNodeLinksDAO; - } - - public void setAclCrudDAO(AclCrudDAO aclCrudDAO) - { - this.aclCrudDAO = aclCrudDAO; - } - - public void setPatchDAO(PatchDAO patchDAO) - { - this.patchDAO = patchDAO; - } - - public void setBatchSize(int batchSizeOverride) - { - batchSize = batchSizeOverride; - } - - public ResetWCMToGroupBasedPermissionsPatch() - { - helper = new HelperDAO(); - } - - @Override - protected String applyInternal() throws Exception - { - long splitTime = System.currentTimeMillis(); - - List stores = this.avmService.getStores(); - - logger.info("Retrieved list of "+stores.size()+" AVM store descriptors in "+(System.currentTimeMillis()-splitTime)/1000+" secs"); - - splitTime = System.currentTimeMillis(); - - List> wcmStores = new ArrayList>(stores.size()); - - int count = 0; - - for (AVMStoreDescriptor store : stores) - { - Map storeProperties = this.avmService.getStoreProperties(store.getName()); - - StoreType storeType = StoreType.getStoreType(store.getName(), store, storeProperties); - - if (! storeType.equals(StoreType.UNKNOWN)) - { - wcmStores.add(new Pair(store, storeType)); - count++; - } - } - - logger.info("Retrieved store types for "+count+" WCM stores in "+(System.currentTimeMillis()-splitTime)/1000+" secs"); - - splitTime = System.currentTimeMillis(); - - count = 0; - - // process WCM staging stores - for (Pair wcmStore : wcmStores) - { - AVMStoreDescriptor store = wcmStore.getFirst(); - StoreType storeType = wcmStore.getSecond(); - - switch (storeType) - { - case STAGING: - - if (logger.isDebugEnabled()) - { - logger.debug("Process store "+store.getName()+" ("+storeType+")"); - } - - count++; - - makeGroupsIfRequired(store); - addUsersToGroupIfRequired(store); - - // belts-and-braces - nullify root children acls (if any) that are not 'www' (which will be overwritten anyway for staging stores) - nullifyAvmNodeAclsExcluding(store.getName(), JNDIConstants.DIR_DEFAULT_WWW); - - setStagingAreaPermissions(store); - - setStagingAreaMasks(store); - - break; - case UNKNOWN: - // non WCM store - nothing to do - default: - } - } - - if (count > 0) - { - logger.info("Processed "+count+" WCM staging stores: "+(System.currentTimeMillis()-splitTime)/1000+" secs"); - } - - splitTime = System.currentTimeMillis(); - - count = 0; - - // process WCM sandbox stores - nullify acls - for (Pair wcmStore : wcmStores) - { - AVMStoreDescriptor store = wcmStore.getFirst(); - StoreType storeType = wcmStore.getSecond(); - - switch (storeType) - { - case AUTHOR: - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case AUTHOR_WORKFLOW_PREVIEW: - case WORKFLOW: - case WORKFLOW_PREVIEW: - case STAGING_PREVIEW: - - if (logger.isDebugEnabled()) - { - logger.debug("Nullify acls for store "+store.getName()+" ("+storeType+")"); - } - - count++; - - // nullify acls for avm nodes for this store - nullifyAvmNodeAcls(store.getName()); - - break; - - case STAGING: - case UNKNOWN: - default: - break; - } - } - - if (count > 0) - { - logger.info("Nullified acls for "+count+" WCM sandbox stores: "+(System.currentTimeMillis()-splitTime)/1000+" secs"); - } - - if (wcmStores.size() > 0) - { - // delete any dangling acls/aces (across all stores) - // note: delete before creating new acls since dangling shared acl currently possible (after creating new sandbox) - splitTime = System.currentTimeMillis(); - deleteDangling(); - logger.info("Deleted dangling acls/aces across all stores in "+(System.currentTimeMillis()-splitTime)/1000+" secs"); - } - - splitTime = System.currentTimeMillis(); - - count = 0; - - // process WCM sandbox stores (1st layer) - for (Pair wcmStore : wcmStores) - { - AVMStoreDescriptor store = wcmStore.getFirst(); - StoreType storeType = wcmStore.getSecond(); - - switch (storeType) - { - case AUTHOR: - case WORKFLOW: - - if (stagingData.get(extractBaseStore(store.getName())) == null) - { - // skip store - no corresponding base store - if (logger.isDebugEnabled()) - { - logger.debug("Skip store "+store.getName()+" ("+storeType+") since no corresponding base store"); - } - - break; - } - - if (logger.isDebugEnabled()) - { - logger.debug("Process store "+store.getName()+" ("+storeType+")"); - } - - count++; - - setSandboxPermissions(store); - - setSandBoxMasks(store); - break; - - case STAGING_PREVIEW: - - if (stagingData.get(extractBaseStore(store.getName())) == null) - { - // skip store - no corresponding base store - if (logger.isDebugEnabled()) - { - logger.debug("Skip store "+store.getName()+" ("+storeType+") since no corresponding base store"); - } - - break; - } - - if (logger.isDebugEnabled()) - { - logger.debug("Process store "+store.getName()+" ("+storeType+")"); - } - - count++; - - setSandboxPermissions(store); - - setStagingAreaMasks(store); - break; - - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case AUTHOR_WORKFLOW_PREVIEW: - case WORKFLOW_PREVIEW: - case STAGING: - case UNKNOWN: - default: - break; - } - } - - // process WCM sandbox stores (2nd layer) - for (Pair wcmStore : wcmStores) - { - AVMStoreDescriptor store = wcmStore.getFirst(); - StoreType storeType = wcmStore.getSecond(); - - switch (storeType) - { - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case WORKFLOW_PREVIEW: - - if (stagingData.get(extractBaseStore(store.getName())) == null) - { - // skip store - no corresponding base store - if (logger.isDebugEnabled()) - { - logger.debug("Skip store "+store.getName()+" ("+storeType+") since no corresponding base store"); - } - - break; - } - - if (logger.isDebugEnabled()) - { - logger.debug("Process store "+store.getName()+" ("+storeType+")"); - } - - count++; - - setSandboxPermissions(store); - - setSandBoxMasks(store); - break; - - case AUTHOR_WORKFLOW_PREVIEW: - case AUTHOR: - case WORKFLOW: - case STAGING_PREVIEW: - case STAGING: - case UNKNOWN: - default: - break; - } - } - - // process WCM sandbox stores (3rd layer) - for (Pair wcmStore : wcmStores) - { - AVMStoreDescriptor store = wcmStore.getFirst(); - StoreType storeType = wcmStore.getSecond(); - - switch (storeType) - { - case AUTHOR_WORKFLOW_PREVIEW: - - if (stagingData.get(extractBaseStore(store.getName())) == null) - { - // skip store - no corresponding base store - if (logger.isDebugEnabled()) - { - logger.debug("Skip store "+store.getName()+" ("+storeType+") since no corresponding base store"); - } - - break; - } - - if (logger.isDebugEnabled()) - { - logger.debug("Process store "+store.getName()+" ("+storeType+")"); - } - - count++; - - setSandboxPermissions(store); - - setSandBoxMasks(store); - break; - - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case WORKFLOW_PREVIEW: - case AUTHOR: - case WORKFLOW: - case STAGING_PREVIEW: - case STAGING: - case UNKNOWN: - default: - break; - } - } - - if (count > 0) - { - logger.info("Processed "+count+" WCM sandbox stores: "+(System.currentTimeMillis()-splitTime)/1000+" secs"); - } - - // build the result message - String msg = I18NUtil.getMessage(MSG_SUCCESS); - // done - return msg; - } - - private void makeGroupsIfRequired(AVMStoreDescriptor stagingStore) - { - long startTime = System.currentTimeMillis(); - - String stagingStoreName = stagingStore.getName(); - - int count = 0; - - for (String permission : MoveWCMToGroupBasedPermissionsPatch.PERMISSIONS) - { - String shortName = stagingStoreName + "-" + permission; - String group = this.authorityService.getName(AuthorityType.GROUP, shortName); - if (!this.authorityService.authorityExists(group)) - { - if (logger.isDebugEnabled()) - { - logger.debug("Create: "+group); - } - - this.authorityService.createAuthority(AuthorityType.GROUP, shortName); - count++; - } - else - { - if (logger.isDebugEnabled()) - { - logger.debug("Already exists: "+group); - } - } - } - - if (logger.isDebugEnabled() && (count > 0)) - { - logger.debug("Created "+count+" missing groups in "+(System.currentTimeMillis()-startTime)/1000+" secs"); - } - } - - private void nullifyAvmNodeAcls(String storeName) throws Exception - { - long startTime = System.currentTimeMillis(); - - int updatedCount = helper.nullifyAvmNodeAcls(storeName); - - if (logger.isDebugEnabled() && (updatedCount > 0)) - { - logger.debug("nullifyAvmNodeAcls ("+updatedCount+") for store: "+storeName+" in "+(System.currentTimeMillis()-startTime)/1000+" secs"); - } - } - - private void nullifyAvmNodeAclsExcluding(String storeName, String excludeRootChild) throws Exception - { - long startTime = System.currentTimeMillis(); - - int updatedCount = helper.nullifyAvmNodeAclsExcluding(storeName, excludeRootChild); - - if (logger.isDebugEnabled() && (updatedCount > 0)) - { - logger.debug("nullifyAvmNodeAcls ("+updatedCount+") for store: "+storeName+" excluding '"+excludeRootChild+"' in "+(System.currentTimeMillis()-startTime)/1000+" secs"); - } - } - - private void deleteDangling() - { - try - { - long startTime = System.currentTimeMillis(); - - if (logger.isDebugEnabled()) - { - logger.debug("Start deleting dangling acls/aces (across all stores)"); - } - - int aclsDeletedCount = helper.deleteDanglingAcls(); - int acesDeletedCount = patchDAO.deleteDanglingAces(); - - if (logger.isDebugEnabled()) - { - logger.debug("Finish deleting dangling acls/aces ["+aclsDeletedCount+"/"+acesDeletedCount+"] (across all stores) in "+(System.currentTimeMillis()-startTime)/1000+" secs"); - } - } - catch (Throwable e) - { - String msg = "Failed to delete dangling acls/aces"; - logger.error(msg, e); - throw new PatchException(msg, e); - } - } - - @Override - protected void setStagingAreaPermissions(AVMStoreDescriptor stagingStore) throws Exception - { - long startTime = System.currentTimeMillis(); - - String stagingStoreName = stagingStore.getName(); - - if (logger.isDebugEnabled()) - { - logger.debug("Start set staging area permissions: "+stagingStoreName); - } - - // create acl change set, defining acl and shared acl - Long aclChangeSet = aclCrudDAO.createAclChangeSet(); - - long definingAclId = helper.createWCMGroupBasedAcl(stagingStoreName, aclChangeSet, ACLType.DEFINING, false); - long sharedAclId = helper.createWCMGroupBasedAcl(stagingStoreName, aclChangeSet, ACLType.SHARED, false); - - stagingData.put(stagingStoreName, new Pair(aclChangeSet, sharedAclId)); - - helper.updateAclInherited(definingAclId, sharedAclId); - - helper.updateAclInheritsFrom(sharedAclId, definingAclId); - helper.updateAclInherited(sharedAclId, sharedAclId); // mimics current - do we need ? - - // set defining acl (on 'www') - helper.setRootAcl(stagingStoreName, definingAclId); - - // set shared acls - int updatedCount = helper.setSharedAcls(stagingStoreName, sharedAclId); - - if (logger.isDebugEnabled()) - { - logger.debug("Finish set staging area permissions: "+stagingStore.getName()+" in "+(System.currentTimeMillis()-startTime)/1000+" secs (updated "+(updatedCount+1)+")"); - } - } - - protected void setSandboxPermissions(AVMStoreDescriptor sandboxStore) throws Exception - { - long startTime = System.currentTimeMillis(); - - String sandboxStoreName = sandboxStore.getName(); - - if (logger.isDebugEnabled()) - { - logger.debug("Start set sandbox permissions: "+sandboxStoreName); - } - - Pair aclData = stagingData.get(extractBaseStore(sandboxStoreName)); - - long aclChangeSet = aclData.getFirst(); - long baseSharedAclId = aclData.getSecond(); - - String stagingStoreName = extractStagingAreaName(sandboxStoreName); - - // create layered acl - long layeredAclId = helper.createWCMGroupBasedAcl(stagingStoreName, aclChangeSet, ACLType.LAYERED, true); - long sharedAclId = helper.createWCMGroupBasedAcl(stagingStoreName, aclChangeSet, ACLType.SHARED, false); - - stagingData.put(sandboxStoreName, new Pair(aclChangeSet, sharedAclId)); - - helper.updateAclInheritsFrom(layeredAclId, baseSharedAclId); - helper.updateAclInheritsFrom(sharedAclId, layeredAclId); - - // set layered acl (on 'www') - helper.setRootAcl(sandboxStoreName, layeredAclId); - - // set shared acls - int updatedCount = helper.setSharedAcls(sandboxStoreName, sharedAclId); - - if (logger.isDebugEnabled()) - { - logger.debug("Finish set sandbox permissions: "+sandboxStoreName+" in "+(System.currentTimeMillis()-startTime)/1000+" secs (updated "+(updatedCount+1)+")"); - } - } - - private void addUsersToGroupIfRequired(AVMStoreDescriptor stagingStore) - { - long startTime = System.currentTimeMillis(); - - QName propQName = QName.createQName(null, ".web_project.noderef"); - - PropertyValue pValue = this.avmService.getStoreProperty(stagingStore.getName(), propQName); - - if (pValue != null) - { - NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF); - - List userInfoRefs = this.nodeService.getChildAssocs(webProjectNodeRef, - WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String) this.nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - - if (userrole.equals(PermissionService.ALL_PERMISSIONS)) - { - userrole = this.replaceAllWith; - this.nodeService.setProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE, userrole); - - if (logger.isDebugEnabled()) - { - logger.debug("Set role "+userrole+" for user "+username+" in web project "+stagingStore.getName()); - } - } - - addToGroupIfRequired(stagingStore.getName(), username, userrole); - } - } - - if (logger.isDebugEnabled()) - { - logger.debug("Check and add missing users (if any) to group(s) in "+(System.currentTimeMillis()-startTime)/1000+" secs"); - } - } - - @Override - protected void addToGroupIfRequired(String stagingStoreName, String user, String permission) - { - String shortName = stagingStoreName + "-" + permission; - String group = this.authorityService.getName(AuthorityType.GROUP, shortName); - Set members = this.authorityService.getContainedAuthorities(AuthorityType.USER, group, true); - if (!members.contains(user)) - { - // skip mismatch - eg. user is linked to web project but does not exist as a person - if (! personService.personExists(user)) - { - logger.warn("Person does not exist: "+user+" (not added to: "+group); - } - else - { - this.authorityService.addAuthority(group, user); - - if (logger.isDebugEnabled()) - { - logger.debug("Added user "+user+" to: "+group); - } - } - } - } - - protected String extractBaseStore(String name) - { - // STAGING -> STAGING - // STAGING--PREVIEW -> STAGING - // STAGING--AUTHOR -> STAGING - // STAGING--AUTHOR--PREVIEW -> STAGING--AUTHOR - // STAGING--AUTHOR--WORKFLOW -> STAGING--AUTHOR - // STAGING--AUTHOR--WORKFLOW--PREVIEW -> STAGING--AUTHOR--WORKFLOW - // STAGING--WORKFLOW -> STAGING - // STAGING--WORKFLOW--PREVIEW -> STAGING--WORKFLOW - - int index = name.lastIndexOf(WCM_STORE_SEPARATOR); - if (index != -1) - { - return name.substring(0, index); - } - - return name; - } - - private class HelperDAO - { - private int nullifyAvmNodeAcls(final String storeName) - { - try - { - long rootId = getAVMStoreCurrentRootNodeId(storeName); - - // recursively nullify below the root - int updatedCount = nullifyAvmNodeAcls(rootId); - - // also nullify the root - List childIds = new ArrayList(1); - childIds.add(rootId); - updatedCount += nullifyAvmNodeAclsForChildren(childIds); - - return updatedCount; - } - catch (Throwable e) - { - String msg = "Failed to nullify avm node acl ids for: "+storeName; - logger.error(msg, e); - throw new PatchException(msg, e); - } - } - - private int nullifyAvmNodeAclsExcluding(String storeName, String excludeRootChild) - { - try - { - long rootId = getAVMStoreCurrentRootNodeId(storeName); - - List children = getAVMChildrenEntries(rootId); - - int totalUpdatedCount = 0; - - List childIds = new ArrayList(0); - - for (AVMChildEntryEntity child : children) - { - Long childId = child.getChildId(); - String name = child.getName(); - - if (! name.equals(excludeRootChild)) - { - // recursively nullify below the (non-excluded) root children - totalUpdatedCount += nullifyAvmNodeAcls(childId); - childIds.add(childId); - } - } - - if (childIds.size() > 0) - { - // also nullify the (non-excluded) root children - totalUpdatedCount += nullifyAvmNodeAclsForChildren(childIds); - } - - return totalUpdatedCount; - } - catch (Throwable e) - { - String msg = "Failed to nullify avm node acl ids for: "+storeName+" (excluding "+excludeRootChild+")"; - logger.error(msg, e); - throw new PatchException(msg, e); - } - } - - private int nullifyAvmNodeAcls(final long parentId) throws Exception - { - List childIds = getAVMChildren(parentId); - - int updatedCount = 0; - - if (childIds.size() > 0) - { - updatedCount = nullifyAvmNodeAclsForChildren(childIds); - - for (Long childId : childIds) - { - // recursive - walk children - updatedCount += nullifyAvmNodeAcls(childId); - } - } - - return updatedCount; - } - - private int nullifyAvmNodeAclsForChildren(List childIds) - { - int totalUpdateCount = 0; - - Iterator childIdIterator = childIds.iterator(); - List batchChildIds = new ArrayList(batchSize); - - while (childIdIterator.hasNext()) - { - Long childId = childIdIterator.next(); - - batchChildIds.add(childId); - - if (batchChildIds.size() == batchSize || !childIdIterator.hasNext()) - { - // execute the update - int batchUpdateCount = patchDAO.updateAVMNodesNullifyAcl(batchChildIds); - - totalUpdateCount = totalUpdateCount + batchUpdateCount; - batchChildIds.clear(); - } - } - - return totalUpdateCount; - } - - private int updateChildNodeAclIds(long aclId, List childIds) - { - int totalUpdateCount = 0; - - Iterator childIdIterator = childIds.iterator(); - List batchChildIds = new ArrayList(batchSize); - - while (childIdIterator.hasNext()) - { - Long childId = childIdIterator.next(); - - batchChildIds.add(childId); - - if (batchChildIds.size() == batchSize || !childIdIterator.hasNext()) - { - // execute the update - int batchUpdateCount = patchDAO.updateAVMNodesSetAcl(aclId, batchChildIds); - - totalUpdateCount = totalUpdateCount + batchUpdateCount; - - batchChildIds.clear(); - } - } - - return totalUpdateCount; - } - - // set root acl on top node (eg. defining or layered acl applied to 'www') - private void setRootAcl(String storeName, long aclId) throws Exception - { - try - { - long rootId = getAVMStoreCurrentRootNodeId(storeName); - - List children = getAVMChildrenEntries(rootId); - - int totalUpdatedCount = 0; - - for (AVMChildEntryEntity child : children) - { - Long childId = child.getChildId(); - String name = child.getName(); - - if (name.equals(JNDIConstants.DIR_DEFAULT_WWW)) - { - List childIds = new ArrayList(1); - childIds.add(childId); - - int updatedCount = updateChildNodeAclIds(aclId, childIds); - totalUpdatedCount += updatedCount; - } - } - - // belts-and-braces - we expect to find & update 'www' - if (totalUpdatedCount != 1) - { - throw new AlfrescoRuntimeException("Failed to set top acl for store: "+storeName+" (unexpected updateCount = "+totalUpdatedCount); - } - } - catch (Throwable e) - { - String msg = "Failed to set top acl for store: "+storeName; - logger.error(msg, e); - throw new PatchException(msg, e); - } - } - - // set shared acls (ie. below 'www' -> from 'avm_webapps' down) - private int setSharedAcls(final String storeName, final long sharedAclId) throws Exception - { - try - { - long rootId = getAVMStoreCurrentRootNodeId(storeName); - - List children = getAVMChildrenEntries(rootId); - - List childIds = new ArrayList(1); - - for (AVMChildEntryEntity child : children) - { - Long childId = child.getChildId(); - String name = child.getName(); - - if (name.equals(JNDIConstants.DIR_DEFAULT_WWW)) - { - childIds.add(childId); - } - } - - // belts-and-braces - if (childIds.size() != 1) - { - throw new AlfrescoRuntimeException("Did not find one 'www' ("+childIds.size()+ ") for: "+storeName); - } - - return setSharedAcls(childIds.get(0), sharedAclId); - } - catch (Throwable e) - { - String msg = "Failed to set shared acls for store: "+storeName; - logger.error(msg, e); - throw new PatchException(msg, e); - } - } - - private int setSharedAcls(final long parentId, final long sharedAclId) throws Exception - { - List childIds = getAVMChildren(parentId); - - int updatedCount = 0; - - if (childIds.size() > 0) - { - updatedCount = updateChildNodeAclIds(sharedAclId, childIds); - - for (Long childId : childIds) - { - // recursive - walk children - updatedCount += setSharedAcls(childId, sharedAclId); - } - } - - return updatedCount; - } - - // note: dangling shared acl currently possible (after creating new sandbox) - private int deleteDanglingAcls() throws Exception - { - List nonDanglingAclIds = patchDAO.selectNonDanglingAclIds(); - List aclIds = patchDAO.selectAllAclIds(); - - // get set of dangling acl ids - aclIds.removeAll(nonDanglingAclIds); - - int totalDeletedCount = 0; - - Iterator aclIdIterator = aclIds.iterator(); - List batchAclIds = new ArrayList(batchSize); - - while (aclIdIterator.hasNext()) - { - Long aclId = aclIdIterator.next(); - - batchAclIds.add(aclId); - - if (batchAclIds.size() == batchSize || !aclIdIterator.hasNext()) - { - // execute delete - int batchDeletedCount = patchDAO.deleteAclMembersForAcls(batchAclIds); - - totalDeletedCount = totalDeletedCount + batchDeletedCount; - batchAclIds.clear(); - } - } - - if (logger.isDebugEnabled()) - { - logger.debug("Deleted "+totalDeletedCount+" dangling acl members"); - } - - totalDeletedCount = 0; - - aclIdIterator = aclIds.iterator(); - batchAclIds = new ArrayList(batchSize); - - while (aclIdIterator.hasNext()) - { - Long aclId = aclIdIterator.next(); - - batchAclIds.add(aclId); - - if (batchAclIds.size() == batchSize || !aclIdIterator.hasNext()) - { - // execute delete - int batchDeletedCount = patchDAO.deleteAcls(batchAclIds); - - totalDeletedCount = totalDeletedCount + batchDeletedCount; - batchAclIds.clear(); - } - } - - if (logger.isDebugEnabled()) - { - logger.debug("Deleted "+totalDeletedCount+" dangling acls"); - } - - return totalDeletedCount; - } - - private long getAVMStoreCurrentRootNodeId(final String avmStoreName) - { - return avmStoreDAO.getStore(avmStoreName).getRootNodeId(); - } - - private List getAVMChildren(final long parentId) - { - List childEntries = getAVMChildrenEntries(parentId); - List childIds = new ArrayList(childEntries.size()); - - for (AVMChildEntryEntity childEntry : childEntries) - { - Long childId = (Long)childEntry.getChildId(); - childIds.add(childId); - } - return childIds; - } - - private List getAVMChildrenEntries(final long parentId) - { - return avmNodeLinksDAO.getChildEntriesByParent(parentId, null); - } - - private long findOrCreateAce(final String authorityName, final String permissionName) throws Exception - { - Authority authority = aclCrudDAO.getOrCreateAuthority(authorityName); - - QName permissionQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "cmobject"); - SimplePermissionReference permRef = SimplePermissionReference.getPermissionReference(permissionQName, permissionName); - - Permission permission = aclCrudDAO.getOrCreatePermission(permRef); - - return aclCrudDAO.getOrCreateAce(permission, authority, ACEType.ALL, AccessStatus.ALLOWED).getId(); - } - - private long createAcl(final long aclChangeSet, final ACLType aclType, boolean requiresVersion) throws Exception - { - AclEntity acl = new AclEntity(); - - acl.setAclId(GUID.generate()); - acl.setAclType(aclType); - acl.setAclVersion(Long.valueOf(1l)); - - switch (aclType) - { - case FIXED: - case GLOBAL: - acl.setInherits(Boolean.FALSE); - case OLD: - case SHARED: - case DEFINING: - case LAYERED: - default: - acl.setInherits(Boolean.TRUE); - break; - } - - acl.setLatest(Boolean.TRUE); - - switch (aclType) - { - case OLD: - acl.setVersioned(Boolean.FALSE); - break; - case FIXED: - case GLOBAL: - case SHARED: - case DEFINING: - case LAYERED: - default: - acl.setVersioned(Boolean.TRUE); - break; - } - - acl.setAclChangeSetId(aclChangeSet); - acl.setRequiresVersion(requiresVersion); - - // save - return aclCrudDAO.createAcl(acl).getId(); - } - - private void updateAclInheritsFrom(final long aclId, final long inheritsFromId) throws Exception - { - AclUpdateEntity aclEntity = aclCrudDAO.getAclForUpdate(aclId); - aclEntity.setInheritsFrom(inheritsFromId); - aclCrudDAO.updateAcl(aclEntity); - } - - private void updateAclInherited(final long aclId, final long inheritedAclId) throws Exception - { - AclUpdateEntity aclEntity = aclCrudDAO.getAclForUpdate(aclId); - aclEntity.setInheritedAcl(inheritedAclId); - aclCrudDAO.updateAcl(aclEntity); - } - - // assume groups exist, if permission does not exist then will be created - private Long createWCMGroupBasedAcl(String stagingStoreName, long aclChangeSet, ACLType aclType, boolean requiresVersion) throws Exception - { - if (stagingStoreName.contains(WCM_STORE_SEPARATOR)) - { - throw new AlfrescoRuntimeException("Unexpected staging store name: "+stagingStoreName); - } - - List aceIds = new ArrayList(5); - - // find or create 5 aces - long cmAceId = findOrCreateAce(PermissionService.GROUP_PREFIX + stagingStoreName + "-" + PermissionService.WCM_CONTENT_MANAGER, PermissionService.WCM_CONTENT_MANAGER); - long cpAceId = findOrCreateAce(PermissionService.GROUP_PREFIX + stagingStoreName + "-" + PermissionService.WCM_CONTENT_PUBLISHER, PermissionService.WCM_CONTENT_PUBLISHER); - long ccAceId = findOrCreateAce(PermissionService.GROUP_PREFIX + stagingStoreName + "-" + PermissionService.WCM_CONTENT_CONTRIBUTOR, PermissionService.WCM_CONTENT_CONTRIBUTOR); - long crAceId = findOrCreateAce(PermissionService.GROUP_PREFIX + stagingStoreName + "-" + PermissionService.WCM_CONTENT_REVIEWER, PermissionService.WCM_CONTENT_REVIEWER); - - long erAceId = findOrCreateAce(PermissionService.ALL_AUTHORITIES, PermissionService.READ); - - // create acl - long aclId = createAcl(aclChangeSet, aclType, requiresVersion); - - aceIds.add(cmAceId); - aceIds.add(cpAceId); - aceIds.add(ccAceId); - aceIds.add(crAceId); - aceIds.add(erAceId); - - // create acl members - aclCrudDAO.addAclMembersToAcl(aclId, aceIds, 0); - - return aclId; - } - } -} diff --git a/source/java/org/alfresco/repo/admin/patch/impl/WCMFoldersPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/WCMFoldersPatch.java deleted file mode 100644 index fc4724a383..0000000000 --- a/source/java/org/alfresco/repo/admin/patch/impl/WCMFoldersPatch.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin.patch.impl; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.alfresco.model.ApplicationModel; -import org.alfresco.model.ContentModel; -import org.alfresco.repo.admin.patch.AbstractPatch; -import org.alfresco.repo.importer.ImporterBootstrap; -import org.alfresco.repo.rule.RuleModel; -import org.alfresco.service.cmr.admin.PatchException; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.QName; -import org.springframework.context.MessageSource; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Ensures that the Web Projects and Web Formsfolders are present. - *

- * This uses the bootstrap importer to get the paths to look for. If not present, - * the required structures are created. - *

- * - * @author Kevin Roast - */ -public class WCMFoldersPatch extends AbstractPatch -{ - private static final String MSG_WEBPROJECTS_EXISTS = "patch.wcmFolders.webprojects.result.exists"; - private static final String MSG_WEBPROJECTS_CREATED = "patch.wcmFolders.webprojects.result.created"; - private static final String MSG_WEBFORMS_EXISTS = "patch.wcmFolders.webforms.result.exists"; - private static final String MSG_WEBFORMS_CREATED = "patch.wcmFolders.webforms.result.created"; - - private static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname"; - private static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname"; - public static final String PROPERTY_WEBPROJECTS_FOLDER_CHILDNAME = "spaces.wcm.childname"; - private static final String MSG_WEBPROJECTS_FOLDER_NAME = "spaces.wcm.name"; - private static final String MSG_WEBPROJECTS_FOLDER_DESCRIPTION = "spaces.wcm.description"; - public static final String PROPERTY_WEBFORMS_FOLDER_CHILDNAME = "spaces.wcm_content_forms.childname"; - private static final String MSG_WEBFORMS_FOLDER_NAME = "spaces.wcm_content_forms.name"; - private static final String MSG_WEBFORMS_FOLDER_DESCRIPTION = "spaces.wcm_content_forms.description"; - - private static final String PROPERTY_ICON = "space-icon-default"; - - private ImporterBootstrap importerBootstrap; - private MessageSource messageSource; - - protected NodeRef companyHomeNodeRef; - protected NodeRef dictionaryNodeRef; - protected Properties configuration; - protected NodeRef wcmProjectsFolderNodeRef; - protected NodeRef wcmFormsFolderNodeRef; - - public void setImporterBootstrap(ImporterBootstrap importerBootstrap) - { - this.importerBootstrap = importerBootstrap; - } - - public void setMessageSource(MessageSource messageSource) - { - this.messageSource = messageSource; - } - - /** - * Ensure that required common properties have been set - */ - protected void checkCommonProperties() throws Exception - { - if (importerBootstrap == null) - { - throw new PatchException("'importerBootstrap' property has not been set"); - } - else if (namespaceService == null) - { - throw new PatchException("'namespaceService' property has not been set"); - } - else if (searchService == null) - { - throw new PatchException("'searchService' property has not been set"); - } - else if (nodeService == null) - { - throw new PatchException("'nodeService' property has not been set"); - } - } - - /** - * Extracts pertinent references and properties that are common to execution - * of this and derived patches. - */ - protected void setUp() throws Exception - { - // get the node store that we must work against - StoreRef storeRef = importerBootstrap.getStoreRef(); - if (storeRef == null) - { - throw new PatchException("Bootstrap store has not been set"); - } - NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef); - - this.configuration = importerBootstrap.getConfiguration(); - // get the association names that form the path - String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME); - if (companyHomeChildName == null || companyHomeChildName.length() == 0) - { - throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present"); - } - String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME); - if (dictionaryChildName == null || dictionaryChildName.length() == 0) - { - throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present"); - } - String wcmProjectsChildName = configuration.getProperty(PROPERTY_WEBPROJECTS_FOLDER_CHILDNAME); - if (wcmProjectsChildName == null || wcmProjectsChildName.length() == 0) - { - throw new PatchException("Bootstrap property '" + PROPERTY_WEBPROJECTS_FOLDER_CHILDNAME + "' is not present"); - } - String wcmFormsChildName = configuration.getProperty(PROPERTY_WEBFORMS_FOLDER_CHILDNAME); - if (wcmFormsChildName == null || wcmFormsChildName.length() == 0) - { - throw new PatchException("Bootstrap property '" + PROPERTY_WEBFORMS_FOLDER_CHILDNAME + "' is not present"); - } - - // build the search string to get the company home node - StringBuilder sb = new StringBuilder(256); - sb.append("/").append(companyHomeChildName); - String xpath = sb.toString(); - // get the company home - List nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); - if (nodeRefs.size() == 0) - { - throw new PatchException("XPath didn't return any results: \n" + - " root: " + storeRootNodeRef + "\n" + - " xpath: " + xpath); - } - else if (nodeRefs.size() > 1) - { - throw new PatchException("XPath returned too many results: \n" + - " root: " + storeRootNodeRef + "\n" + - " xpath: " + xpath + "\n" + - " results: " + nodeRefs); - } - this.companyHomeNodeRef = nodeRefs.get(0); - - // build the search string to get the dictionary node - sb.append("/").append(dictionaryChildName); - xpath = sb.toString(); - // get the dictionary node - nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false); - if (nodeRefs.size() == 0) - { - throw new PatchException("XPath didn't return any results: \n" + - " root: " + storeRootNodeRef + "\n" + - " xpath: " + xpath); - } - else if (nodeRefs.size() > 1) - { - throw new PatchException("XPath returned too many results: \n" + - " root: " + storeRootNodeRef + "\n" + - " xpath: " + xpath + "\n" + - " results: " + nodeRefs); - } - this.dictionaryNodeRef = nodeRefs.get(0); - - // Check for the existence of the 'Web Projects' folder - xpath = wcmProjectsChildName; - nodeRefs = searchService.selectNodes(companyHomeNodeRef, xpath, null, namespaceService, false); - if (nodeRefs.size() > 1) - { - throw new PatchException("XPath returned too many results: \n" + - " company home node: " + companyHomeNodeRef + "\n" + - " xpath: " + xpath + "\n" + - " results: " + nodeRefs); - } - else if (nodeRefs.size() == 0) - { - // the node does not exist - this.wcmProjectsFolderNodeRef = null; - } - else - { - // we have the 'Web Projects' folder noderef - this.wcmProjectsFolderNodeRef = nodeRefs.get(0); - } - - // Check for the existence of the 'Web Forms' folder - xpath = wcmFormsChildName; - nodeRefs = searchService.selectNodes(dictionaryNodeRef, xpath, null, namespaceService, false); - if (nodeRefs.size() > 1) - { - throw new PatchException("XPath returned too many results: \n" + - " dictionary node: " + dictionaryNodeRef + "\n" + - " xpath: " + xpath + "\n" + - " results: " + nodeRefs); - } - else if (nodeRefs.size() == 0) - { - // the node does not exist - this.wcmFormsFolderNodeRef = null; - } - else - { - // we have the 'Web Forms' folder noderef - this.wcmFormsFolderNodeRef = nodeRefs.get(0); - } - } - - @Override - protected String applyInternal() throws Exception - { - // properties must be set - checkCommonProperties(); - if (messageSource == null) - { - throw new PatchException("'messageSource' property has not been set"); - } - - // get useful values - setUp(); - - String msg = null; - if (wcmProjectsFolderNodeRef == null) - { - // create it - createWebProjectsFolder(); - msg = I18NUtil.getMessage(MSG_WEBPROJECTS_CREATED, wcmProjectsFolderNodeRef); - } - else - { - // it already exists - msg = I18NUtil.getMessage(MSG_WEBPROJECTS_EXISTS, wcmProjectsFolderNodeRef); - } - - if (wcmFormsFolderNodeRef == null) - { - // create it - createWebFormsFolder(); - msg = msg + "\r\n" + I18NUtil.getMessage(MSG_WEBFORMS_CREATED, wcmProjectsFolderNodeRef); - } - else - { - // it already exists - msg = msg + "\r\n" + I18NUtil.getMessage(MSG_WEBFORMS_EXISTS, wcmProjectsFolderNodeRef); - } - - // done - return msg; - } - - private void createWebProjectsFolder() - { - // get required properties - String wcmProjectsChildName = configuration.getProperty(PROPERTY_WEBPROJECTS_FOLDER_CHILDNAME); - if (wcmProjectsChildName == null) - { - throw new PatchException("Bootstrap property '" + PROPERTY_WEBPROJECTS_FOLDER_CHILDNAME + "' is not present"); - } - - String name = messageSource.getMessage( - MSG_WEBPROJECTS_FOLDER_NAME, - null, - I18NUtil.getLocale()); - if (name == null || name.length() == 0) - { - throw new PatchException("Bootstrap property '" + MSG_WEBPROJECTS_FOLDER_NAME + "' is not present"); - } - - String description = messageSource.getMessage( - MSG_WEBPROJECTS_FOLDER_DESCRIPTION, - null, - I18NUtil.getLocale()); - if (description == null || description.length() == 0) - { - throw new PatchException("Bootstrap property '" + MSG_WEBPROJECTS_FOLDER_DESCRIPTION + "' is not present"); - } - - Map properties = new HashMap(7); - properties.put(ContentModel.PROP_NAME, name); - properties.put(ContentModel.PROP_TITLE, name); - properties.put(ContentModel.PROP_DESCRIPTION, description); - properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON); - // create the node - ChildAssociationRef childAssocRef = nodeService.createNode( - companyHomeNodeRef, - ContentModel.ASSOC_CONTAINS, - QName.resolveToQName(namespaceService, wcmProjectsChildName), - ContentModel.TYPE_FOLDER, - properties); - wcmProjectsFolderNodeRef = childAssocRef.getChildRef(); - - // add the required aspects - nodeService.addAspect(wcmProjectsFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null); - - // ALF-906: ensure that DM rules are not inherited by web projects - nodeService.addAspect(wcmProjectsFolderNodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES, null); - } - - private void createWebFormsFolder() - { - // get required properties - String wcmFormsChildName = configuration.getProperty(PROPERTY_WEBFORMS_FOLDER_CHILDNAME); - if (wcmFormsChildName == null) - { - throw new PatchException("Bootstrap property '" + PROPERTY_WEBFORMS_FOLDER_CHILDNAME + "' is not present"); - } - - String name = messageSource.getMessage( - MSG_WEBFORMS_FOLDER_NAME, - null, - I18NUtil.getLocale()); - if (name == null || name.length() == 0) - { - throw new PatchException("Bootstrap property '" + MSG_WEBFORMS_FOLDER_NAME + "' is not present"); - } - - String description = messageSource.getMessage( - MSG_WEBFORMS_FOLDER_DESCRIPTION, - null, - I18NUtil.getLocale()); - if (description == null || description.length() == 0) - { - throw new PatchException("Bootstrap property '" + MSG_WEBFORMS_FOLDER_DESCRIPTION + "' is not present"); - } - - Map properties = new HashMap(7); - properties.put(ContentModel.PROP_NAME, name); - properties.put(ContentModel.PROP_TITLE, name); - properties.put(ContentModel.PROP_DESCRIPTION, description); - properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON); - // create the node - ChildAssociationRef childAssocRef = nodeService.createNode( - dictionaryNodeRef, - ContentModel.ASSOC_CONTAINS, - QName.resolveToQName(namespaceService, wcmFormsChildName), - ContentModel.TYPE_FOLDER, - properties); - wcmFormsFolderNodeRef = childAssocRef.getChildRef(); - - // add the required aspects - nodeService.addAspect(wcmFormsFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null); - } -} diff --git a/source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java deleted file mode 100644 index 4dc97ee36a..0000000000 --- a/source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin.patch.impl; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.repo.admin.patch.AbstractPatch; -import org.alfresco.repo.domain.patch.PatchDAO; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; -import org.alfresco.repo.search.impl.lucene.AVMLuceneIndexer; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Snap shot all stores after applying the staging are permissions patch - * - * @author andyh - */ -public class WCMPostPermissionSnapshotPatch extends AbstractPatch -{ - private static final String MSG_SUCCESS = "patch.wcmPostPermissionSnapshotPatch.result"; - - private static final String AVM_SITE_STORE_NAME = "sitestore"; - - private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; - - private AVMService avmService; - - private PatchDAO patchDAO; - - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) - { - this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; - } - - public void setPatchDAO(PatchDAO patchDAO) - { - this.patchDAO = patchDAO; - } - - @Override - protected String applyInternal() throws Exception - { - List stores = avmService.getStores(); - - Thread progressThread = null; - - Long toDo = patchDAO.getAVMNodesCountWhereNewInStore(); - - List indexers = new ArrayList(stores.size()); - for (AVMStoreDescriptor storeDesc : stores) - { - // post 4.0 we can safely skip "sitestore" no longer used by share - if(storeDesc.getName().equals(AVM_SITE_STORE_NAME)) - { - continue; - } - - AVMLuceneIndexer indexer = avmSnapShotTriggeredIndexingMethodInterceptor.getIndexer(storeDesc.getName()); - indexers.add(indexer); - } - - progressThread = new Thread(new ProgressWatcher(toDo, indexers), "WCMPactchProgressWatcher"); - progressThread.start(); - - for (AVMStoreDescriptor storeDesc : stores) - { - // post 4.0 we can safely skip "sitestore" no longer used by share - if(storeDesc.getName().equals(AVM_SITE_STORE_NAME)) - { - continue; - } - - if (avmService.getStoreRoot(-1, storeDesc.getName()).getLayerID() == -1) - { - avmService.createSnapshot(storeDesc.getName(), "PermissionPatch", "Snapshot after 2.2 permission patch"); - AVMLuceneIndexer indexer = avmSnapShotTriggeredIndexingMethodInterceptor.getIndexer(storeDesc.getName()); - indexer.flushPending(); - } - } - - progressThread.interrupt(); - progressThread.join(); - - // build the result message - String msg = I18NUtil.getMessage(MSG_SUCCESS); - // done - return msg; - } - - private class ProgressWatcher implements Runnable - { - private boolean running = true; - - Long toDo; - - List indexers; - - ProgressWatcher(Long toDo, List indexers) - { - this.toDo = toDo; - this.indexers = indexers; - } - - public void run() - { - while (running) - { - try - { - Thread.sleep(60000); - } - catch (InterruptedException e) - { - running = false; - } - - if (running) - { - long done = 0; - for(AVMLuceneIndexer indexer : indexers) - { - if(indexer != null) - { - done += indexer.getIndexedDocCount(); - } - } - - reportProgress(toDo, done); - } - } - } - - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMDAOs.java b/source/java/org/alfresco/repo/avm/AVMDAOs.java deleted file mode 100644 index d81c7ea6a9..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMDAOs.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import org.alfresco.repo.domain.contentdata.ContentDataDAO; -import org.alfresco.repo.domain.permissions.AclDAO; - -/** - * This is the (shudder) global context for AVM. It a rendezvous - * point for access to needed global instances. - * @author britt - */ -public class AVMDAOs -{ - /** - * The single instance of an AVMContext. - */ - private static final AVMDAOs fgInstance = new AVMDAOs(); - - private AVMDAOs() - { - } - - /** - * Get the instance of this. - * @return - */ - public static AVMDAOs Instance() - { - return fgInstance; - } - - /** - * The AVMNodeDAO. - */ - public AVMNodeDAO fAVMNodeDAO; - - public org.alfresco.repo.domain.avm.AVMNodeDAO newAVMNodeDAO; - public org.alfresco.repo.domain.avm.AVMNodeLinksDAO newAVMNodeLinksDAO; - public ContentDataDAO contentDataDAO; - - /** - * The AVMStore DAO. - */ - public AVMStoreDAO fAVMStoreDAO; - - public org.alfresco.repo.domain.avm.AVMStoreDAO newAVMStoreDAO; - - /** - * The VersionRootDAO. - */ - public VersionRootDAO fVersionRootDAO; - - public org.alfresco.repo.domain.avm.AVMVersionRootDAO newAVMVersionRootDAO; - - /** - * The ChildEntryDAO. - */ - public ChildEntryDAO fChildEntryDAO; - - /** - * The AVMStorePropertyDAO - */ - public AVMStorePropertyDAO fAVMStorePropertyDAO; - - public VersionLayeredNodeEntryDAO fVersionLayeredNodeEntryDAO; - - public AclDAO fAclDAO; - - /** - * @param nodeDAO the fAVMNodeDAO to set - */ - public void setNodeDAO(AVMNodeDAO nodeDAO) - { - fAVMNodeDAO = nodeDAO; - } - - public void setNewAvmNodeDAO(org.alfresco.repo.domain.avm.AVMNodeDAO newAVMNodeDAO) - { - this.newAVMNodeDAO = newAVMNodeDAO; - } - - public void setNewAvmNodeLinksDAO(org.alfresco.repo.domain.avm.AVMNodeLinksDAO newAVMNodeLinksDAO) - { - this.newAVMNodeLinksDAO = newAVMNodeLinksDAO; - } - - public void setContentDataDAO(ContentDataDAO contentDataDAO) - { - this.contentDataDAO = contentDataDAO; - } - - /** - * @param childEntryDAO the fChildEntryDAO to set - */ - public void setChildEntryDAO(ChildEntryDAO childEntryDAO) - { - fChildEntryDAO = childEntryDAO; - } - - /** - * @param aVMStoreDAO The fAVMStoreDAO to set - */ - public void setAvmStoreDAO(AVMStoreDAO aVMStoreDAO) - { - fAVMStoreDAO = aVMStoreDAO; - } - - public void setNewAvmStoreDAO(org.alfresco.repo.domain.avm.AVMStoreDAO newAVMStoreDAO) - { - this.newAVMStoreDAO = newAVMStoreDAO; - } - - /** - * @param versionRootDAO the fVersionRootDAO to set - */ - public void setVersionRootDAO(VersionRootDAO versionRootDAO) - { - fVersionRootDAO = versionRootDAO; - } - - public void setNewAvmVersionRootDAO(org.alfresco.repo.domain.avm.AVMVersionRootDAO newAVMVersionRootDAO) - { - this.newAVMVersionRootDAO = newAVMVersionRootDAO; - } - - public void setAvmStorePropertyDAO(AVMStorePropertyDAO avmStorePropertyDAO) - { - fAVMStorePropertyDAO = avmStorePropertyDAO; - } - - public void setVersionLayeredNodeEntryDAO(VersionLayeredNodeEntryDAO dao) - { - fVersionLayeredNodeEntryDAO = dao; - } - - public void setAclDAO(AclDAO dao) - { - fAclDAO = dao; - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMNode.java b/source/java/org/alfresco/repo/avm/AVMNode.java deleted file mode 100644 index 82f2cc4594..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMNode.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import java.util.Map; -import java.util.Set; - -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.namespace.QName; - -/** - * The Interface for versionable objects. - * @author britt - */ -public interface AVMNode -{ - /** - * Set the ancestor of this node. - * @param ancestor The ancestor to set. - */ - public void setAncestor(AVMNode ancestor); - - /** - * Change the ancestor of a node. - * @param ancestor The ancestor node that should be set. - */ - public void changeAncestor(AVMNode ancestor); - - /** - * Get the ancestor of this node. - * @return The ancestor of this node. - */ - public AVMNode getAncestor(); - - /** - * Set the merged from node. - * @param mergedFrom The merged from node. - */ - public void setMergedFrom(AVMNode mergedFrom); - - /** - * Get the node this was merged from. - * @return The node this was merged from. - */ - public AVMNode getMergedFrom(); - - /** - * Get the version number. - * @return The version number. - */ - public int getVersionID(); - - /** - * Set the version number. - * @param version The version number to set. - */ - public void setVersionID(int version); - - /** - * Possibly copy ourselves. - * @param lPath The Lookup for this node. - * @return A copy of ourself or null if no copy was necessary. - */ - public AVMNode copy(Lookup lPath); - - /** - * Get the type of this node. - */ - public int getType(); - - /** - * Get the descriptor for this node. - * @param lPath The Lookup. - * @param name The name of this in the current context. - * @return The descriptor for this node. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath, String name); - - /** - * Get the descriptor for this node. - * @param lPath The Lookup. - * @return The descriptor for this node. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath); - - /** - * Get a node descriptor for this node. - * @param parentPath The parent path. - * @param name The name looked up as. - * @param parentIndirection The indirection of the parent. - * @param parentIndirectionVersion The indirection version of the parent. - * @return The descriptor for this node. - */ - public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion); - - /** - * Get the object id. - * @return The object id. - */ - public long getId(); - - /** - * Get the newnews. - * @return Whether the node is new. - */ - public boolean getIsNew(); - - /** - * Get a string representation for debugging. - * @param lPath The Lookup. - * @return A String representation. - */ - public String toString(Lookup lPath); - - /** - * Set whether this node to be a root of a AVMStore - * @param isRoot - */ - public void setIsRoot(boolean isRoot); - - /** - * Get whether this node is a root of a AVMStore. - * @return Whether this node is a root. - */ - public boolean getIsRoot(); - - /** - * Update the modification time of this node. - */ - public void updateModTime(); - - /** - * Set a property. - * @param qname the QName - * @param value The value to set. - */ - public void setProperty(QName qname, PropertyValue value); - - /** - * Set a collection of properties on this node. - * @param properties The Map of QNames to PropertyValues. - */ - public void setProperties(Map properties); - - /** - * Add properties to those that already exist. - * @param properties The properties to add. - */ - public void addProperties(Map properties); - - /** - * Get a property by name. - * @param name The name of the property to get. - * @return A PropertyValue - */ - public PropertyValue getProperty(QName name); - - /** - * Get all the properties associated with this node. - * @return A Map of QNames to PropertyValues. - */ - public Map getProperties(); - - /** - * Delete a property from this node. - * @param qnameEntityId the ID of the QName to delete - */ - public void deleteProperty(QName qname); - - /** - * Delete all properties from this node. - */ - public void deleteProperties(); - - /** - * Set an ACL on this node. - * @param acl The ACL to set. - */ - public void setAcl(Acl acl); - - /** - * Get the ACL on this node. - * @return The ACL on this node. - */ - public Acl getAcl(); - - /** - * Set the store that we are new in. - * @param store The store we are new in. - */ - public void setStoreNew(AVMStore store); - - /** - * Get the possibly null store that we're new in. - * @return The store that we're new in. - */ - public AVMStore getStoreNew(); - - /** - * Copy ACL from another node. - * - * @param other - * @param mode - */ - public void copyACLs(AVMNode other, ACLCopyMode mode); - - public void copyACLs(Acl otherAcl, Acl parentAcl, ACLCopyMode mode); - - /** - * Copy metadata from another node. - * @param other The other node. - */ - public void copyMetaDataFrom(AVMNode other, Long parentAcl); - - /** - * Get the GUID associated with this version. - * @return The GUID. - */ - public String getGuid(); - - /** - * Set the GUID associated with this version. - * @param guid - */ - public void setGuid(String guid); - - /** - * Get the Aspects that this node has. - * @return A Set of Aspects IDs. - */ - public Set getAspects(); - - public void addAspect(QName aspectQName); - - public void removeAspect(QName aspectQName); - - /** - * Get the Basic Attributes on this node. - * @return - */ - public BasicAttributes getBasicAttributes(); -} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeDAO.java b/source/java/org/alfresco/repo/avm/AVMNodeDAO.java deleted file mode 100644 index b323aeb0f8..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMNodeDAO.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.service.namespace.QName; - -/** - * DAO for AVMNodes interface. - * @author britt - */ -public interface AVMNodeDAO -{ - /** - * Save the given node, having never been saved before. - */ - public void save(AVMNode node); - - /** - * Delete a single node. - * @param node The node to delete. - */ - public void delete(AVMNode node); - - public void createAspect(long nodeId, QName aspectQName); - - public void deleteAspect(long nodeId, QName aspectQName); - - public void deleteAspects(long nodeId); - - public Set getAspects(long nodeId); - - public void createOrUpdateProperty(long nodeId, QName propQName, PropertyValue value); - - public void deleteProperty(long nodeId, QName propQName); - - public void deleteProperties(long nodeId); - - public Map getProperties(long nodeId); - - /** - * Get by ID. - * @param id The id to get. - */ - public AVMNode getByID(long id); - - /** - * Get the root of a particular version. - * @param store The store we're querying. - * @param version The version. - * @return The VersionRoot or null. - */ - public DirectoryNode getAVMStoreRoot(AVMStore store, int version); - - /** - * Update a node that has been dirtied. - * @param node The node. - */ - public void update(AVMNode node); - - // update optimisation, eg. when creating files - public void updateModTimeAndGuid(AVMNode node); - - /** - * Get the ancestor of a node. - * @param node The node whose ancestor is desired. - * @return The ancestor or null. - */ - public AVMNode getAncestor(AVMNode node); - - /** - * Get the node the given node was merged from. - * @param node The node whose merged from is desired. - * @return The merged from node or null. - */ - public AVMNode getMergedFrom(AVMNode node); - - /** - * Get up to batchSize orphans. - * @param batchSize Get no more than this number. - * @return A List of orphaned AVMNodes. - */ - public List getOrphans(int batchSize); - - - /** - * Get all the nodes that are new in the given store. - * @param store The store to query. - * @return A List of AVMNodes. - */ - public List getNewInStore(AVMStore store); - - /** - * Clear newInStore field for a store. (Snapshot) - * @param store - */ - public void clearNewInStore(AVMStore store); - - /** - * Get any new layered entries in a store. - * @param store - * @return - */ - public List getNewLayeredInStoreIDs(AVMStore store); - - public List getNewLayeredInStore(AVMStore store); - - /** - * Clear the cache. - */ - public void clear(); -} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java deleted file mode 100644 index 4bcde69882..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.alfresco.repo.avm.util.RawServices; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.avm.AVMHistoryLinkEntity; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMReadOnlyException; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Base class for all repository file system like objects. - * @author britt - */ -public abstract class AVMNodeImpl implements AVMNode -{ - private static Log logger = LogFactory.getLog(AVMNodeImpl.class); - - protected static final boolean DEBUG = logger.isDebugEnabled(); - - /** - * The Object ID. - */ - private long fID; - - /** - * The Version ID. - */ - private int fVersionID; - - /** - * The basic attributes of this. Owner, creator, mod time, etc. - */ - private BasicAttributes fBasicAttributes; - - /** - * The version number (for concurrency control). - */ - private long fVers; - - /** - * The rootness of this node. - */ - private boolean fIsRoot; - - /** - * The ACL on this node. - */ - private Acl fACL; - - /** - * The Store that we're new in. - */ - private AVMStore fStoreNew; - - /** - * The GUID for this version. - */ - private String fGUID; - - /** - * The Aspects that belong to this node. - */ - private Set fAspects; - - private Map fProperties; - - /** - * Default constructor. - */ - protected AVMNodeImpl() - { - } - - /** - * Constructor used when creating a new concrete subclass instance. - * @param store The AVMStore that owns this. - */ - protected AVMNodeImpl(AVMStore store) - { - this(); - - setVersionID(-1); - setIsRoot(false); - - long time = System.currentTimeMillis(); - String user = - RawServices.Instance().getAuthenticationContext().getCurrentUserName(); - if (user == null) - { - user = RawServices.Instance().getAuthenticationContext().getSystemUserName(); - } - setBasicAttributes(new BasicAttributesImpl(user, - user, - user, - time, - time, - time)); - setStoreNew(store); - setGuid(GUID.generate()); - } - - /** - * Set the ancestor of this node. - * @param ancestor The ancestor to set. - */ - public void setAncestor(AVMNode ancestor) - { - if (ancestor == null) - { - return; - } - AVMDAOs.Instance().newAVMNodeLinksDAO.createHistoryLink(ancestor.getId(), this.getId()); - } - - /** - * Change the ancestor of this node. - * @param ancestor The new ancestor to give it. - */ - public void changeAncestor(AVMNode ancestor) - { - AVMHistoryLinkEntity hlEntity = AVMDAOs.Instance().newAVMNodeLinksDAO.getHistoryLinkByDescendent(this.getId()); - if (hlEntity != null) - { - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteHistoryLink(hlEntity.getAncestorNodeId(), hlEntity.getDescendentNodeId()); - } - setAncestor(ancestor); - } - - /** - * Get the ancestor of this node. - * @return The ancestor of this node. - */ - public AVMNode getAncestor() - { - return AVMDAOs.Instance().fAVMNodeDAO.getAncestor(this); - } - - /** - * Set the node that was merged into this. - * @param mergedFrom The node that was merged into this. - */ - public void setMergedFrom(AVMNode mergedFrom) - { - if (mergedFrom == null) - { - return; - } - AVMDAOs.Instance().newAVMNodeLinksDAO.createMergeLink(mergedFrom.getId(), this.getId()); - } - - /** - * Get the node that was merged into this. - * @return The node that was merged into this. - */ - public AVMNode getMergedFrom() - { - return AVMDAOs.Instance().fAVMNodeDAO.getMergedFrom(this); - } - - /** - * Equality based on object ids. - * @param obj The thing to compare against. - * @return Equality. - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (!(obj instanceof AVMNode)) - { - return false; - } - return getId() == ((AVMNode)obj).getId(); - } - - /** - * Get a reasonable hash value. - * @return The hash code. - */ - @Override - public int hashCode() - { - return (int)getId(); - } - - /** - * Set the object id. - * @param id The id to set. - */ - public void setId(long id) - { - fID = id; - } - - /** - * Get the id of this node. - * @return The object id. - */ - public long getId() - { - return fID; - } - - /** - * Set the versionID for this node. - * @param versionID The id to set. - */ - public void setVersionID(int versionID) - { - fVersionID = versionID; - } - - /** - * Get the version id of this node. - * @return The version id. - */ - public int getVersionID() - { - return fVersionID; - } - - /** - * Set the basic attributes. - * @param attrs - */ - public void setBasicAttributes(BasicAttributes attrs) - { - fBasicAttributes = attrs; - } - - /** - * Get the basic attributes. - * @return The basic attributes. - */ - public BasicAttributes getBasicAttributes() - { - return fBasicAttributes; - } - - /** - * Get whether this is a new node. - * @return Whether this is new. - */ - public boolean getIsNew() - { - return getStoreNew() != null; - } - - /** - * Set the version (for concurrency control). - * @param The version for optimistic locks. - */ - public void setVers(long vers) - { - fVers = vers; - } - - /** - * Get the version (for concurrency control). - * @return vers The version for optimistic locks. - */ - public long getVers() - { - return fVers; - } - - /** - * Get whether this is a root node. - * @return Whether this is a root node. - */ - public boolean getIsRoot() - { - return fIsRoot; - } - - /** - * @param isRoot - */ - public void setIsRoot(boolean isRoot) - { - fIsRoot = isRoot; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNode#updateModTime() - */ - public void updateModTime() - { - if (DEBUG) - { - checkReadOnly(); - } - String user = - RawServices.Instance().getAuthenticationContext().getCurrentUserName(); - if (user == null) - { - user = RawServices.Instance().getAuthenticationContext().getSystemUserName(); - } - getBasicAttributes().setModDate(System.currentTimeMillis()); - getBasicAttributes().setLastModifier(user); - } - - /** - * Copy all properties from another node. - * @param other The other node. - */ - protected void copyProperties(AVMNode other) - { - Map props = new HashMap(); - for (Map.Entry entry : other.getProperties().entrySet()) - { - props.put(entry.getKey(), entry.getValue()); - } - - setProperties(props); - } - - /** - * Copy all aspects from another node. - * @param other The other node. - */ - protected void copyAspects(AVMNode other) - { - Set aspects = new HashSet(other.getAspects()); - setAspects(aspects); - } - - protected void copyCreationAndOwnerBasicAttributes(AVMNode other) - { - getBasicAttributes().setCreateDate(other.getBasicAttributes().getCreateDate()); - getBasicAttributes().setCreator(other.getBasicAttributes().getCreator()); - getBasicAttributes().setOwner(other.getBasicAttributes().getOwner()); - } - - public void copyACLs(AVMNode other, ACLCopyMode mode) - { - Acl otherAcl = other.getAcl(); - Long otherAclId = (otherAcl == null ? null : otherAcl.getId()); - copyACLs(otherAclId, otherAclId, mode); - } - - public void copyACLs(Acl otherAcl, Acl parentAcl, ACLCopyMode mode) - { - Long otherAclId = (otherAcl == null ? null : otherAcl.getId()); - Long parentAclId = (parentAcl == null ? null : parentAcl.getId()); - - copyACLs(otherAclId, parentAclId, mode); - } - - protected void copyACLs(AVMNode other, Long parentAcl, ACLCopyMode mode) - { - Acl otherAcl = other.getAcl(); - copyACLs((otherAcl == null ? null : otherAcl.getId()), parentAcl, mode); - } - - protected void copyACLs(Long otherAcl, Long parentAcl, ACLCopyMode mode) - { - if (otherAcl != null) - { - Acl aclCopy = AVMDAOs.Instance().fAclDAO.getAclCopy(otherAcl, parentAcl, mode); - setAcl(aclCopy); - } - else - { - setAcl(null); - } - } - - /** - * Copy out metadata from another node. - * @param other The other node. - */ - public void copyMetaDataFrom(AVMNode other, Long parentAcl) - { - copyAspects(other); - copyACLs(other, parentAcl, ACLCopyMode.COPY); - copyProperties(other); - copyCreationAndOwnerBasicAttributes(other); - } - - /** - * Set a property on a node. Overwrite it if it exists. - * @param name The name of the property. - * @param value The value to set. - */ - public void setProperty(QName qname, PropertyValue value) - { - if (DEBUG) - { - checkReadOnly(); - } - - getProperties().put(qname, value); - - AVMDAOs.Instance().fAVMNodeDAO.createOrUpdateProperty(this.getId(), qname, value); - } - - public void addProperties(Map properties) - { - for (Map.Entry entry : properties.entrySet()) - { - setProperty(entry.getKey(), entry.getValue()); - } - } - - /** - * Set a collection of properties on this node. - * @param properties The Map of QNames to PropertyValues. - */ - public void setProperties(Map properties) - { - fProperties = properties; - - for (Map.Entry entry : properties.entrySet()) - { - setProperty(entry.getKey(), entry.getValue()); - } - } - - /** - * Get a property by name. - * @param name The name of the property. - * @return The PropertyValue or null if non-existent. - */ - public PropertyValue getProperty(QName qname) - { - return getProperties().get(qname); - } - - /** - * {@inheritDoc} - */ - public Map getProperties() - { - if (fProperties == null) - { - fProperties = AVMDAOs.Instance().fAVMNodeDAO.getProperties(getId()); - } - return fProperties; - } - - /** - * Delete a property from this node. - * @param name The name of the property. - */ - public void deleteProperty(QName qname) - { - if (DEBUG) - { - checkReadOnly(); - } - getProperties().remove(qname); - - AVMDAOs.Instance().fAVMNodeDAO.deleteProperty(getId(), qname); - } - - /** - * Delete all properties from this node. - */ - public void deleteProperties() - { - getProperties().clear(); - - AVMDAOs.Instance().fAVMNodeDAO.deleteProperties(getId()); - } - - /** - * Set the ACL on this node. - * @param acl The ACL to set. - */ - public void setAcl(Acl acl) - { - fACL = acl; - } - - /** - * Get the ACL on this node. - * @return The ACL on this node. - */ - public Acl getAcl() - { - return fACL; - } - - /** - * Set the store we are new in. - * @param store The store we are new in. - */ - public void setStoreNew(AVMStore store) - { - fStoreNew = store; - } - - /** - * Get the possibly null store we are new in. - * @return The store we are new in. - */ - public AVMStore getStoreNew() - { - return fStoreNew; - } - - protected void checkReadOnly() - { - if (getStoreNew() == null) - { - throw new AVMReadOnlyException("Write Operation on R/O Node."); - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNode#getGuid() - */ - public String getGuid() - { - return fGUID; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNode#setGuid(java.lang.String) - */ - public void setGuid(String guid) - { - fGUID = guid; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNode#getAspects() - */ - public Set getAspects() - { - if (fAspects == null) - { - fAspects = AVMDAOs.Instance().fAVMNodeDAO.getAspects(getId()); - } - return fAspects; - } - - /** - * Set the aspects on this node. - * @param aspects - */ - public void setAspects(Set aspects) - { - fAspects = aspects; - - if ((aspects != null) && (aspects.size() > 0)) - { - for (QName aspectQName : aspects) - { - AVMDAOs.Instance().fAVMNodeDAO.createAspect(this.getId(), aspectQName); - } - } - } - - public void addAspect(QName aspectQName) - { - fAspects = null; - AVMDAOs.Instance().fAVMNodeDAO.createAspect(this.getId(), aspectQName); - } - - public void removeAspect(QName aspectQName) - { - fAspects = null; - AVMDAOs.Instance().fAVMNodeDAO.deleteAspect(this.getId(), aspectQName); - } - - // debug - public String toString() - { - return toString(null); - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeService.java b/source/java/org/alfresco/repo/avm/AVMNodeService.java index e5f03dbdcc..1bc231e19b 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeService.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeService.java @@ -1,2087 +1,2090 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMModel; -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.node.AbstractNodeServiceImpl; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.AVMWrongTypeException; -import org.alfresco.service.cmr.dictionary.AspectDefinition; -import org.alfresco.service.cmr.dictionary.ClassDefinition; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryException; -import org.alfresco.service.cmr.dictionary.InvalidAspectException; -import org.alfresco.service.cmr.dictionary.InvalidTypeException; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.cmr.dictionary.TypeDefinition; -import org.alfresco.service.cmr.repository.AssociationExistsException; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.CyclicChildRelationshipException; -import org.alfresco.service.cmr.repository.InvalidChildAssociationRefException; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.InvalidStoreRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.Path; -import org.alfresco.service.cmr.repository.StoreExistsException; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.datatype.TypeConversionException; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.QNamePattern; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * NodeService implementing facade over AVMService. - * @author britt - */ -public class AVMNodeService extends AbstractNodeServiceImpl implements NodeService -{ - private static Log logger = LogFactory.getLog(AVMNodeService.class); - - /** - * Flag for whether policy callbacks are made. - */ - private boolean fInvokePolicies = false; - - /** - * Reference to AVMService. - */ - private AVMService fAVMService; - - /** - * Set the AVMService. For Spring. - * @param service The AVMService instance. - */ - public void setAvmService(AVMService service) - { - fAVMService = service; - } - - /** - * Default constructor. - */ - public AVMNodeService() - { - } - - public void setInvokePolicies(boolean invoke) - { - fInvokePolicies = invoke; - } - - /** - * Helper method to convert the Serializable value into a full, - * persistable {@link PropertyValue}. - *

- * Where the property definition is null, the value will take on the - * {@link DataTypeDefinition#ANY generic ANY} value. - *

- * Where the property definition specifies a multi-valued property but the - * value provided is not a collection, the value will be wrapped in a collection. - * - * @param propertyDef the property dictionary definition, may be null - * @param value the value, which will be converted according to the definition - - * may be null - * @return Returns the persistable property value - */ - protected PropertyValue makePropertyValue(PropertyDefinition propertyDef, Serializable value) - { - // get property attributes - QName propertyTypeQName = null; - if (propertyDef == null) // property not recognised - { - // allow it for now - persisting excess properties can be useful sometimes - propertyTypeQName = DataTypeDefinition.ANY; - } - else - { - propertyTypeQName = propertyDef.getDataType().getName(); - // check that multi-valued properties are allowed - boolean isMultiValued = propertyDef.isMultiValued(); - if (isMultiValued && !(value instanceof Collection)) - { - if (value != null) - { - // put the value into a collection - // the implementation gives back a Serializable list - value = (Serializable) Collections.singletonList(value); - } - } - else if (!isMultiValued && (value instanceof Collection)) - { - // we only allow this case if the property type is ANY - if (!propertyTypeQName.equals(DataTypeDefinition.ANY)) - { - throw new DictionaryException( - "A single-valued property of this type may not be a collection: \n" + - " Property: " + propertyDef + "\n" + - " Type: " + propertyTypeQName + "\n" + - " Value: " + value); - } - } - } - try - { - PropertyValue propertyValue = new PropertyValue(propertyTypeQName, value); - // done - return propertyValue; - } - catch (TypeConversionException e) - { - throw new TypeConversionException( - "The property value is not compatible with the type defined for the property: \n" + - " property: " + (propertyDef == null ? "unknown" : propertyDef) + "\n" + - " value: " + value + "\n" + - " value type: " + value.getClass(), - e); - } - } - - /** - * Extracts the externally-visible property from the {@link PropertyValue propertyValue}. - * - * @param propertyDef the model property definition - may be null - * @param propertyValue the persisted property - * @return Returns the value of the property in the format dictated by the property - * definition, or null if the property value is null - */ - protected Serializable makeSerializableValue(PropertyDefinition propertyDef, PropertyValue propertyValue) - { - if (propertyValue == null) - { - return null; - } - // get property attributes - QName propertyTypeQName = null; - if (propertyDef == null) - { - // allow this for now - propertyTypeQName = DataTypeDefinition.ANY; - } - else - { - propertyTypeQName = propertyDef.getDataType().getName(); - } - try - { - Serializable value = propertyValue.getValue(propertyTypeQName); - // done - return value; - } - catch (TypeConversionException e) - { - throw new TypeConversionException( - "The property value is not compatible with the type defined for the property: \n" + - " property: " + (propertyDef == null ? "unknown" : propertyDef) + "\n" + - " property value: " + propertyValue, - e); - } - } - - /** - * Gets a list of all available node store references - * - * @return Returns a list of store references - */ - public List getStores() - { - // For AVM stores we fake up StoreRefs. - List stores = fAVMService.getStores(); - List result = new ArrayList(); - for (AVMStoreDescriptor desc : stores) - { - String name = desc.getName(); - result.add(new StoreRef(StoreRef.PROTOCOL_AVM, name)); - } - return result; - } - - /** - * Create a new AVM store. - * @param protocol the implementation protocol - * @param identifier the protocol-specific identifier - * @return Returns a reference to the store - * @throws StoreExistsException - */ - public StoreRef createStore(String protocol, String identifier) throws StoreExistsException - { - StoreRef result = new StoreRef(StoreRef.PROTOCOL_AVM, identifier); - // invokeBeforeCreateStore(ContentModel.TYPE_STOREROOT, result); - try - { - fAVMService.createStore(identifier); - NodeRef rootRef = getRootNode(result); - addAspect(rootRef, ContentModel.ASPECT_ROOT, - Collections.emptyMap()); - // invokeOnCreateStore(rootRef); - return result; - } - catch (AVMExistsException e) - { - throw new StoreExistsException(result, e); - } - } - - /** - * @throws UnsupportedOperationException Always - */ - public void deleteStore(StoreRef storeRef) throws InvalidStoreRefException - { - throw new UnsupportedOperationException(); - } - - /** - * Does the indicated store exist? - * @param storeRef a reference to the store to look for - * @return Returns true if the store exists, otherwise false - */ - public boolean exists(StoreRef storeRef) - { - return fAVMService.getStore(storeRef.getIdentifier()) != null; - } - - /** - * @param nodeRef a reference to the node to look for - * @return Returns true if the node exists, otherwise false - */ - public boolean exists(NodeRef nodeRef) - { - Pair avmInfo = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmInfo.getFirst(); - String avmPath = avmInfo.getSecond(); - return fAVMService.lookup(version, avmPath) != null; - } - - /** - * Gets the ID of the last transaction that caused the node to change. This includes - * deletions, so it is possible that the node being referenced no longer exists. - * If the node never existed, then null is returned. - * - * @param nodeRef a reference to a current or previously existing node - * @return Returns the status of the node, or null if the node never existed - */ - public NodeRef.Status getNodeStatus(NodeRef nodeRef) - { - // TODO Need to find out if this is important and if so - // need to capture Transaction IDs. - return new NodeRef.Status(null, nodeRef, "Unknown", null, !exists(nodeRef)); - } - - /** - * @throws UnsupportedOperationException always - */ - @Override - public NodeRef getNodeRef(Long nodeId) - { - throw new UnsupportedOperationException(); - } - - /** - * @param storeRef a reference to an existing store - * @return Returns a reference to the root node of the store - * @throws InvalidStoreRefException if the store could not be found - */ - public NodeRef getRootNode(StoreRef storeRef) throws InvalidStoreRefException - { - String storeName = storeRef.getIdentifier(); - if (fAVMService.getStore(storeName) != null) - { - return AVMNodeConverter.ToNodeRef(-1, storeName + ":/"); - } - else - { - throw new InvalidStoreRefException(storeName +":/" + " not found.", storeRef); - } - } - - public Set getAllRootNodes(StoreRef storeRef) - { - return Collections.singleton(getRootNode(storeRef)); - } - - /** - * @see #createNode(NodeRef, QName, QName, QName, Map) - */ - public ChildAssociationRef createNode( - NodeRef parentRef, - QName assocTypeQName, - QName assocQName, - QName nodeTypeQName) - throws InvalidNodeRefException, InvalidTypeException - { - return createNode(parentRef, - assocTypeQName, - assocQName, - nodeTypeQName, - new HashMap()); - } - - /** - * Creates a new, non-abstract, real node as a primary child of the given parent node. - * - * @param parentRef the parent node - * @param assocTypeQName the type of the association to create. This is used - * for verification against the data dictionary. - * @param assocQName the qualified name of the association - * @param nodeTypeQName a reference to the node type - * @param properties optional map of properties to keyed by their qualified names - * @return Returns a reference to the newly created child association - * @throws InvalidNodeRefException if the parent reference is invalid - * @throws InvalidTypeException if the node type reference is not recognised - * - * @see org.alfresco.service.cmr.dictionary.DictionaryService - */ - @SuppressWarnings("deprecation") - public ChildAssociationRef createNode( - NodeRef parentRef, - QName assocTypeQName, - QName assocQName, - QName nodeTypeQName, - Map properties) - throws InvalidNodeRefException, InvalidTypeException - { - // AVM stores only allow simple child associations. - if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) - { - throw new InvalidTypeException(assocTypeQName); - } - String nodeName = assocQName.getLocalName(); - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read only store.", parentRef); - } - String avmPath = avmVersionPath.getSecond(); - // Invoke policy behavior. - // invokeBeforeUpdateNode(parentRef); - // invokeBeforeCreateNode(parentRef, assocTypeQName, assocQName, nodeTypeQName); - // Look up the type definition in the dictionary. - TypeDefinition nodeTypeDef = dictionaryService.getType(nodeTypeQName); - // Do the creates for supported types, or error out. - try - { - if (nodeTypeQName.equals(WCMModel.TYPE_AVM_PLAIN_FOLDER) || - nodeTypeQName.equals(ContentModel.TYPE_FOLDER)) - { - fAVMService.createDirectory(avmPath, nodeName); - } - else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_PLAIN_CONTENT) || - nodeTypeQName.equals(ContentModel.TYPE_CONTENT)) - { - OutputStream os = fAVMService.createFile(avmPath, nodeName); - try - { - if (os != null) { os.close(); } - } - catch (IOException ioe) - { - logger.warn("Failed to close output stream when creating file '"+AVMUtil.extendAVMPath(avmPath, nodeName)+"'"+ioe.getMessage()); - } - } - else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_LAYERED_CONTENT)) - { - NodeRef indirection = (NodeRef)properties.get(WCMModel.PROP_AVM_FILE_INDIRECTION); - if (indirection == null) - { - throw new InvalidTypeException("No Indirection Property", nodeTypeQName); - } - Pair indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection); - fAVMService.createLayeredFile(indVersionPath.getSecond(), avmPath, nodeName); - } - else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_LAYERED_FOLDER)) - { - NodeRef indirection = (NodeRef)properties.get(WCMModel.PROP_AVM_DIR_INDIRECTION); - if (indirection == null) - { - throw new InvalidTypeException("No Indirection Property.", nodeTypeQName); - } - Pair indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection); - fAVMService.createLayeredDirectory(indVersionPath.getSecond(), avmPath, nodeName); - } - else - { - throw new InvalidTypeException("Invalid node type for AVM.", nodeTypeQName); - } - properties.putAll(getDefaultProperties(nodeTypeDef)); - addDefaultAspects(nodeTypeDef, avmPath, properties); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmPath + " not found.", parentRef); - } - catch (AVMExistsException e) - { - throw new InvalidNodeRefException("Child " + nodeName + " exists", parentRef); - } - String newAVMPath = AVMNodeConverter.ExtendAVMPath(avmPath, nodeName); - NodeRef childRef = AVMNodeConverter.ToNodeRef(-1, newAVMPath); - properties.putAll(getDefaultProperties(nodeTypeDef)); - addDefaultAspects(nodeTypeDef, newAVMPath, properties); - Map props = new HashMap(); - for (Map.Entry entry : properties.entrySet()) - { - QName propertyQName = entry.getKey(); - if (isBuiltInProperty(propertyQName)) - { - continue; - } - Serializable value = entry.getValue(); - PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); - PropertyValue propertyValue = makePropertyValue(propertyDef, value); - props.put(propertyQName, propertyValue); - } - fAVMService.setNodeProperties(newAVMPath, props); - ChildAssociationRef ref = - new ChildAssociationRef(assocTypeQName, - parentRef, - assocQName, - childRef, - true, - -1); -// invokeOnCreateNode(ref); -// invokeOnUpdateNode(parentRef); -// if (properties.size() != 0) -// { -// invokeOnUpdateProperties(childRef, new HashMap(), properties); -// } - return ref; - } - - /** - * Moves the primary location of the given node. - *

- * This involves changing the node's primary parent and possibly the name of the - * association referencing it. - *

- * If the new parent is in a different store from the original, then the entire - * node hierarchy is moved to the new store. Inter-store associations are not - * affected. - * - * @param nodeToMoveRef the node to move - * @param newParentRef the new parent of the moved node - * @param assocTypeQName the type of the association to create. This is used - * for verification against the data dictionary. - * @param assocQName the qualified name of the new child association - * @return Returns a reference to the newly created child association - * @throws InvalidNodeRefException if either the parent node or move node reference is invalid - * @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add - * - * @see #getPrimaryParent(NodeRef) - */ - public ChildAssociationRef moveNode( - NodeRef nodeToMoveRef, - NodeRef newParentRef, - QName assocTypeQName, - QName assocQName) - throws InvalidNodeRefException - { - // AVM stores only allow simple child associations. - if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) - { - throw new InvalidTypeException(assocTypeQName); - } - // Extract the parts from the source. - Pair src = AVMNodeConverter.ToAVMVersionPath(nodeToMoveRef); - int srcVersion = src.getFirst(); - if (srcVersion >= 0) - { - throw new InvalidNodeRefException("Read Only Store.", nodeToMoveRef); - } - String srcPath = src.getSecond(); - String [] splitSrc = null; - try - { - splitSrc = AVMNodeConverter.SplitBase(srcPath); - } - catch (AVMException e) - { - throw new InvalidNodeRefException("Invalid src path.", nodeToMoveRef); - } - String srcParent = splitSrc[0]; - if (srcParent == null) - { - throw new InvalidNodeRefException("Cannot rename root node.", nodeToMoveRef); - } - String srcName = splitSrc[1]; - // Extract and setup the parts of the destination. - Pair dst = AVMNodeConverter.ToAVMVersionPath(newParentRef); - if (dst.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read Only Store.", newParentRef); - } - String dstParent = dst.getSecond(); - String dstName = assocQName.getLocalName(); - // TODO Invoke policy behavior. Not quite sure how to translate this. - NodeRef oldParentRef = AVMNodeConverter.ToNodeRef(-1, srcParent); - ChildAssociationRef oldAssocRef = - new ChildAssociationRef(assocTypeQName, - oldParentRef, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, srcName), - nodeToMoveRef, - true, - -1); -// invokeBeforeDeleteChildAssociation(oldAssocRef); - String dstPath = AVMNodeConverter.ExtendAVMPath(dstParent, dstName); - NodeRef newChildRef = AVMNodeConverter.ToNodeRef(-1, dstPath); -// invokeBeforeUpdateNode(oldParentRef); -// invokeBeforeUpdateNode(newParentRef); - // Actually perform the rename and return a pseudo - // ChildAssociationRef. - try - { - fAVMService.rename(srcParent, srcName, dstParent, dstName); - ChildAssociationRef newAssocRef = - new ChildAssociationRef(assocTypeQName, - newParentRef, - assocQName, - newChildRef, - true, - -1); - invokeOnMoveNode(oldAssocRef, newAssocRef); -// invokeOnCreateChildAssociation(newAssocRef); -// invokeOnDeleteChildAssociation(oldAssocRef); -// invokeOnUpdateNode(oldParentRef); -// invokeOnUpdateNode(newParentRef); - return newAssocRef; - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException("Non existent node.", nodeToMoveRef); - } - catch (AVMExistsException e) - { - throw new InvalidNodeRefException("Target already exists.", newParentRef); - } - catch (AVMException e) - { - throw new InvalidNodeRefException("Illegal move.", nodeToMoveRef); - } - } - - /** - * Set the ordering index of the child association. This affects the ordering of - * of the return values of methods that return a set of children or child - * associations. - * - * @param childAssocRef the child association that must be moved in the order - * @param index an arbitrary index that will affect the return order - * - * @see #getChildAssocs(NodeRef) - * @see #getChildAssocs(NodeRef, QNamePattern, QNamePattern) - * @see ChildAssociationRef#getNthSibling() - */ - public void setChildAssociationIndex( - ChildAssociationRef childAssocRef, - int index) - throws InvalidChildAssociationRefException - { - // TODO We'll keep this a no-op unless there's a - // compelling reason to implement this capability - // for the AVM repository. - } - - /** - * @param nodeRef - * @return Returns the type name - * @throws InvalidNodeRefException if the node could not be found - * - * @see org.alfresco.service.cmr.dictionary.DictionaryService - */ - public QName getType(NodeRef nodeRef) throws InvalidNodeRefException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(), - avmVersionPath.getSecond()); - if (desc == null) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - if (desc.isPlainDirectory()) - { - return WCMModel.TYPE_AVM_PLAIN_FOLDER; - } - else if (desc.isPlainFile()) - { - return WCMModel.TYPE_AVM_PLAIN_CONTENT; - } - else if (desc.isLayeredDirectory()) - { - return WCMModel.TYPE_AVM_LAYERED_FOLDER; - } - else - { - return WCMModel.TYPE_AVM_LAYERED_CONTENT; - } - } - - /** - * Re-sets the type of the node. Can be called in order specialise a node to a sub-type. - * - * This should be used with caution since calling it changes the type of the node and thus - * implies a different set of aspects, properties and associations. It is the calling codes - * responsibility to ensure that the node is in a approriate state after changing the type. - * - * @param nodeRef the node reference - * @param typeQName the type QName - * - * @since 1.1 - */ - public void setType(NodeRef nodeRef, QName typeQName) throws InvalidNodeRefException - { - throw new UnsupportedOperationException("AVM Types are immutable."); - } - - /** - * Applies an aspect to the given node. After this method has been called, - * the node with have all the aspect-related properties present - * - * @param nodeRef - * @param aspectTypeQName the aspect to apply to the node - * @param aspectProperties a minimum of the mandatory properties required for - * the aspect - * @throws InvalidNodeRefException - * @throws InvalidAspectException if the class reference is not to a valid aspect - * - * @see org.alfresco.service.cmr.dictionary.DictionaryService#getAspect(QName) - * @see org.alfresco.service.cmr.dictionary.ClassDefinition#getProperties() - */ - public void addAspect( - NodeRef nodeRef, - QName aspectTypeQName, - Map aspectProperties) - throws InvalidNodeRefException, InvalidAspectException - { - // Check that the aspect exists. - AspectDefinition aspectDef = this.dictionaryService.getAspect(aspectTypeQName); - if (aspectDef == null) - { - throw new InvalidAspectException("The aspect is invalid: " + aspectTypeQName, - aspectTypeQName); - } - // Invoke policy behaviors. -// invokeBeforeUpdateNode(nodeRef); -// invokeBeforeAddAspect(nodeRef, aspectTypeQName); - // Crack the nodeRef. - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only node.", nodeRef); - } - String avmPath = avmVersionPath.getSecond(); - // Accumulate properties. - Map properties = new HashMap(); - // Add the supplied properties. - if (aspectProperties != null) - { - properties.putAll(aspectProperties); - } - // Now set any unspecified default properties for the aspect. - Map defaultProperties = getDefaultProperties(aspectDef); - properties.putAll(defaultProperties); - // Now add any cascading aspects. - addDefaultAspects(aspectDef, avmPath, properties); - // Set the property values on the AVM Node. - if (properties.size() != 0) - { - Map props = new HashMap(); - for (Map.Entry entry : properties.entrySet()) - { - QName propertyQName = entry.getKey(); - if (isBuiltInProperty(propertyQName)) - { - continue; - } - Serializable value = entry.getValue(); - PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); - PropertyValue propertyValue = makePropertyValue(propertyDef, value); - props.put(propertyQName, propertyValue); - } - if (props.size() != 0) - { - fAVMService.setNodeProperties(avmPath, props); - } - } - if (isBuiltinAspect(aspectTypeQName)) - { - // No more work to do in this case. - return; - } - try - { - fAVMService.addAspect(avmPath, aspectTypeQName); - // Invoke policy behaviors. -// invokeOnUpdateNode(nodeRef); -// invokeOnAddAspect(nodeRef, aspectTypeQName); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - /** - * Add any aspects that are mandatory for the ClassDefinition. - * @param classDef The ClassDefinition. - * @param path The path to the AVMNode. - * @param properties The in/out map of accumulated properties. - */ - private void addDefaultAspects(ClassDefinition classDef, String path, - Map properties) - { - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path); - // Get mandatory aspects. - List defaultAspectDefs = classDef.getDefaultAspects(); - // add all the aspects (and there dependent aspects recursively). - for (AspectDefinition def : defaultAspectDefs) - { -// invokeBeforeAddAspect(nodeRef, def.getName()); - addAspect(nodeRef, def.getName(), Collections.emptyMap()); - properties.putAll(getDefaultProperties(def)); -// invokeOnAddAspect(nodeRef, def.getName()); - // recurse - addDefaultAspects(def, path, properties); - } - } - - /** - * Remove an aspect and all related properties from a node - * - * @param nodeRef - * @param aspectTypeQName the type of aspect to remove - * @throws InvalidNodeRefException if the node could not be found - * @throws InvalidAspectException if the the aspect is unknown or if the - * aspect is mandatory for the class of the node - */ - public void removeAspect(NodeRef nodeRef, QName aspectTypeQName) - throws InvalidNodeRefException, InvalidAspectException - { - // Invoke policy behaviors. -// invokeBeforeUpdateNode(nodeRef); -// invokeBeforeRemoveAspect(nodeRef, aspectTypeQName); - AspectDefinition def = dictionaryService.getAspect(aspectTypeQName); - if (def == null) - { - throw new InvalidAspectException(aspectTypeQName); - } - if (isBuiltinAspect(aspectTypeQName)) - { - // TODO shouldn't we be throwing some kind of exception here. - return; - } - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", nodeRef); - } - String path = avmVersionPath.getSecond(); - try - { - if (fAVMService.hasAspect(-1, path, aspectTypeQName)) - { - fAVMService.removeAspect(path, aspectTypeQName); - Map propDefs = def.getProperties(); - for (QName propertyName : propDefs.keySet()) - { - fAVMService.deleteNodeProperty(path, propertyName); - } - } - // Invoke policy behaviors. -// invokeOnUpdateNode(nodeRef); -// invokeOnRemoveAspect(nodeRef, aspectTypeQName); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - /** - * Determines if a given aspect is present on a node. Aspects may only be - * removed if they are NOT mandatory. - * - * @param nodeRef - * @param aspectTypeQName - * @return Returns true if the aspect has been applied to the given node, - * otherwise false - * @throws InvalidNodeRefException if the node could not be found - * @throws InvalidAspectException if the aspect reference is invalid - */ - public boolean hasAspect(NodeRef nodeRef, QName aspectTypeQName) - throws InvalidNodeRefException, InvalidAspectException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - if (isBuiltinAspect(aspectTypeQName)) - { - return true; - } - return fAVMService.hasAspect(version, path, aspectTypeQName); - } - - private static QName [] fgBuiltinAspects = new QName[] { ContentModel.ASPECT_AUDITABLE, - ContentModel.ASPECT_REFERENCEABLE }; - - private boolean isBuiltinAspect(QName aspectQName) - { - for (QName builtin : fgBuiltinAspects) - { - if (builtin.equals(aspectQName)) - { - return true; - } - } - return false; - } - - /** - * @param nodeRef - * @return Returns a set of all aspects applied to the node, including mandatory - * aspects - * @throws InvalidNodeRefException if the node could not be found - */ - public Set getAspects(NodeRef nodeRef) throws InvalidNodeRefException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - Set result = new HashSet(); - // Add the builtin ones. - for (QName name : fgBuiltinAspects) - { - result.add(name); - } - try - { - for (QName name : fAVMService.getAspects(version, path)) - { - result.add(name); - } - return result; - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - /** - * Deletes the given node. - *

- * All associations (both children and regular node associations) - * will be deleted, and where the given node is the primary parent, - * the children will also be cascade deleted. - * - * @param nodeRef reference to a node within a store - * @throws InvalidNodeRefException if the reference given is invalid - */ - public void deleteNode(NodeRef nodeRef) throws InvalidNodeRefException - { - // Invoke policy behaviors. -// invokeBeforeDeleteNode(nodeRef); - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - if (avmVersionPath.getFirst() != -1) - { - throw new InvalidNodeRefException("Read only store.", nodeRef); - } - String [] avmPathBase = AVMNodeConverter.SplitBase(avmVersionPath.getSecond()); - if (avmPathBase[0] == null) - { - throw new InvalidNodeRefException("Cannot delete root node.", nodeRef); - } - try - { -// QName nodeTypeQName = getType(nodeRef); -// Set aspects = getAspects(nodeRef); - fAVMService.removeNode(avmPathBase[0], avmPathBase[1]); -// ChildAssociationRef childAssocRef = -// new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, -// AVMNodeConverter.ToNodeRef(-1, avmPathBase[0]), -// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, -// avmPathBase[1]), -// nodeRef); -// invokeOnDeleteNode(childAssocRef, nodeTypeQName, aspects, false); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() +" not found.", nodeRef); - } - } - - /** - * Makes a parent-child association between the given nodes. Both nodes must belong to the same store. - *

- * - * @param parentRef - * @param childRef - * @param assocTypeQName the qualified name of the association type as defined in the datadictionary - * @param qname the qualified name of the association - * @return Returns a reference to the newly created child association - * @throws InvalidNodeRefException if the parent or child nodes could not be found - * @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add - */ - public ChildAssociationRef addChild( - NodeRef parentRef, - NodeRef childRef, - QName assocTypeQName, - QName qname) throws InvalidNodeRefException - { - return addChild(Collections.singletonList(parentRef), childRef, assocTypeQName, qname).get(0); - } - - /** - * Associates a given child node with a given collection of parents. All nodes must belong to the same store. - *

- * - * - * @param parentRefs - * @param childRef - * @param assocTypeQName the qualified name of the association type as defined in the datadictionary - * @param qname the qualified name of the association - * @return Returns a reference to the newly created child association - * @throws InvalidNodeRefException if the parent or child nodes could not be found - * @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add - */ - public List addChild( - Collection parentRefs, - NodeRef childRef, - QName assocTypeQName, - QName qname) throws InvalidNodeRefException - { - Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - AVMNodeDescriptor child = fAVMService.lookup(childVersionPath.getFirst(), - childVersionPath.getSecond()); - if (child == null) - { - throw new InvalidNodeRefException(childVersionPath.getSecond() + " not found.", childRef); - } - - List childAssociationRefs = new ArrayList(parentRefs.size()); - for (NodeRef parentRef : parentRefs) - { - Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); - if (parentVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read Only.", parentRef); - } - try - { - fAVMService.link(parentVersionPath.getSecond(), qname.getLocalName(), child); - ChildAssociationRef newChild = new ChildAssociationRef(assocTypeQName, parentRef, qname, - AVMNodeConverter.ToNodeRef(-1, AVMNodeConverter.ExtendAVMPath(parentVersionPath.getSecond(), - qname.getLocalName()))); - childAssociationRefs.add(newChild); - } - catch (AVMException e) - { - throw new InvalidNodeRefException("Could not link.", childRef); - } - } - return childAssociationRefs; - } - - /** - * Severs all parent-child relationships between two nodes. - *

- * The child node will be cascade deleted if one of the associations was the - * primary association, i.e. the one with which the child node was created. - * - * @param parentRef the parent end of the association - * @param childRef the child end of the association - * @throws InvalidNodeRefException if the parent or child nodes could not be found - */ - public void removeChild(NodeRef parentRef, NodeRef childRef) throws InvalidNodeRefException - { - Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); - if (parentVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read only store.", parentRef); - } - Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - if (childVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read only store.", childRef); - } - String parentPath = parentVersionPath.getSecond(); - String childPath = childVersionPath.getSecond(); - String [] childPathBase = AVMNodeConverter.SplitBase(childPath); - if (childPathBase[0] == null || !childPathBase[0].equals(parentPath)) - { - throw new InvalidNodeRefException(childPath + " not a child of " + parentPath, childRef); - } - try - { -// ChildAssociationRef assocRef = -// new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, -// AVMNodeConverter.ToNodeRef(-1, parentPath), -// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, -// childPathBase[1]), -// AVMNodeConverter.ToNodeRef(-1, childPath)); -// invokeBeforeDeleteChildAssociation(assocRef); - fAVMService.removeNode(childPathBase[0], childPathBase[1]); -// invokeOnDeleteChildAssociation(assocRef); -// invokeOnUpdateNode(AVMNodeConverter.ToNodeRef(-1, parentPath)); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(childPathBase[1] + " not found in " + childPathBase[0], - childRef); - } - } - - /** - * TODO: Check implementation - */ - public boolean removeChildAssociation(ChildAssociationRef childAssocRef) - { - NodeRef parentRef = childAssocRef.getParentRef(); - NodeRef childRef = childAssocRef.getChildRef(); - Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); - if (parentVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read only store.", parentRef); - } - Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - if (childVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read only store.", childRef); - } - String parentPath = parentVersionPath.getSecond(); - String childPath = childVersionPath.getSecond(); - String [] childPathBase = AVMNodeConverter.SplitBase(childPath); - if (childPathBase[0] == null || !childPathBase[0].equals(parentPath)) - { - return false; - } - try - { - fAVMService.removeNode(childPathBase[0], childPathBase[1]); - return true; - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException("Not found.", childRef); - } - } - - /** - * TODO: Implement - */ - public boolean removeSecondaryChildAssociation(ChildAssociationRef childAssocRef) - { - throw new UnsupportedOperationException(); - } - - /** - * @param nodeRef - * @return Returns all properties keyed by their qualified name - * @throws InvalidNodeRefException if the node could not be found - */ - public Map getProperties(NodeRef nodeRef) throws InvalidNodeRefException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - Map props = null; - AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(), - avmVersionPath.getSecond()); - try - { - props = fAVMService.getNodeProperties(avmVersionPath.getFirst(), - avmVersionPath.getSecond()); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - Map result = new HashMap(); - for (QName qName : props.keySet()) - { - PropertyValue value = props.get(qName); - PropertyDefinition def = dictionaryService.getProperty(qName); - result.put(qName, makeSerializableValue(def, value)); - } - // Now spoof properties that are built in. - result.put(ContentModel.PROP_CREATED, new Date(desc.getCreateDate())); - result.put(ContentModel.PROP_CREATOR, desc.getCreator()); - result.put(ContentModel.PROP_MODIFIED, new Date(desc.getModDate())); - result.put(ContentModel.PROP_MODIFIER, desc.getLastModifier()); - result.put(ContentModel.PROP_OWNER, desc.getOwner()); - result.put(ContentModel.PROP_NAME, desc.getName()); - result.put(ContentModel.PROP_NODE_UUID, "UNKNOWN"); - result.put(ContentModel.PROP_NODE_DBID, new Long(desc.getId())); - result.put(ContentModel.PROP_STORE_PROTOCOL, "avm"); - result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier()); - if (desc.isLayeredDirectory()) - { - result.put(WCMModel.PROP_AVM_DIR_INDIRECTION, - AVMNodeConverter.ToNodeRef(-1, desc.getIndirection())); - } - if (desc.isLayeredFile()) - { - result.put(WCMModel.PROP_AVM_FILE_INDIRECTION, - AVMNodeConverter.ToNodeRef(-1, desc.getIndirection())); - } - if (desc.isFile()) - { - try - { - ContentData contentData = fAVMService.getContentDataForRead(avmVersionPath.getFirst(), - avmVersionPath.getSecond()); - result.put(ContentModel.PROP_CONTENT, contentData); - } - catch (AVMException e) - { - // TODO For now ignore. - } - } - return result; - } - - /** - * @param nodeRef - * @param qname the qualified name of the property - * @return Returns the value of the property, or null if not yet set - * @throws InvalidNodeRefException if the node could not be found - */ - public Serializable getProperty(NodeRef nodeRef, QName qname) throws InvalidNodeRefException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - if (isBuiltInProperty(qname)) - { - return getBuiltInProperty(avmVersionPath, qname, nodeRef); - } - try - { - PropertyValue value = fAVMService.getNodeProperty(avmVersionPath.getFirst(), - avmVersionPath.getSecond(), - qname); - if (value == null) - { - return null; - } - PropertyDefinition def = this.dictionaryService.getProperty(qname); - return makeSerializableValue(def, value); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - } - - /** - * {@inheritDoc} - */ - public void removeProperty(NodeRef nodeRef, QName qname) throws InvalidNodeRefException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - if (isBuiltInProperty(qname)) - { - // Ignore - return; - } - try - { - fAVMService.deleteNodeProperty(avmVersionPath.getSecond(), qname); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - } - - /** - * A Helper to spoof built in properties. - * @param avmVersionPath The broken out version and path from a NodeRef. - * @param qName The name of the property to retrieve. - * @param nodeRef The original NodeRef (for error reporting). - * @return The property value. - */ - private Serializable getBuiltInProperty(Pair avmVersionPath, - QName qName, - NodeRef nodeRef) - { - if (qName.equals(ContentModel.PROP_CONTENT)) - { - try - { - ContentData contentData = - fAVMService.getContentDataForRead(avmVersionPath.getFirst(), - avmVersionPath.getSecond()); - return contentData; - } - catch (AVMException e) - { - // TODO This seems very wrong. Do something better - // sooner rather than later. - return null; - } - } - AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(), - avmVersionPath.getSecond()); - if (desc == null) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - if (qName.equals(ContentModel.PROP_CREATED)) - { - return new Date(desc.getCreateDate()); - } - else if (qName.equals(ContentModel.PROP_CREATOR)) - { - return desc.getCreator(); - } - else if (qName.equals(ContentModel.PROP_MODIFIED)) - { - return new Date(desc.getModDate()); - } - else if (qName.equals(ContentModel.PROP_MODIFIER)) - { - return desc.getLastModifier(); - } - else if (qName.equals(ContentModel.PROP_OWNER)) - { - return desc.getOwner(); - } - else if (qName.equals(ContentModel.PROP_NAME)) - { - return desc.getName(); - } - else if (qName.equals(ContentModel.PROP_NODE_UUID)) - { - return "UNKNOWN"; - } - else if (qName.equals(ContentModel.PROP_NODE_DBID)) - { - return new Long(desc.getId()); - } - else if (qName.equals(ContentModel.PROP_STORE_PROTOCOL)) - { - return "avm"; - } - else if (qName.equals(ContentModel.PROP_STORE_IDENTIFIER)) - { - return nodeRef.getStoreRef().getIdentifier(); - } - else if (qName.equals(WCMModel.PROP_AVM_DIR_INDIRECTION)) - { - if (desc.isLayeredDirectory()) - { - return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()); - } - return null; - } - else if (qName.equals(WCMModel.PROP_AVM_FILE_INDIRECTION)) - { - if (desc.isLayeredFile()) - { - return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()); - } - return null; - } - else - { - logger.error("Invalid Built In Property: " + qName); - return null; - } - } - - /** - * Set the values of all properties to be an Serializable instances. - * The properties given must still fulfill the requirements of the class and - * aspects relevant to the node. - *

- * NOTE: Null values are allowed. - * - * @param nodeRef - * @param properties all the properties of the node keyed by their qualified names - * @throws InvalidNodeRefException if the node could not be found - */ - public void setProperties(NodeRef nodeRef, Map properties) throws InvalidNodeRefException - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - if (avmVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read only store.", nodeRef); - } - // TODO Not sure this try block is necessary. - try - { - // Prepare fr policy invocation. - Map propsBefore = null; - if (fInvokePolicies) - { - propsBefore = getProperties(nodeRef); - } - // Remove all properties - fAVMService.deleteNodeProperties(avmVersionPath.getSecond()); - // Rebuild node properties - Map values = new HashMap(); - for (Map.Entry entry : properties.entrySet()) - { - QName propertyQName = entry.getKey(); - Serializable value = entry.getValue(); - // For AVM nodes is in place. - if (isBuiltInProperty(propertyQName)) - { - if (propertyQName.equals(ContentModel.PROP_CONTENT)) - { - AVMNodeDescriptor desc = fAVMService.lookup(-1, avmVersionPath.getSecond()); - if (desc == null) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - if (desc.isPlainFile()) - { - fAVMService.setContentData(avmVersionPath.getSecond(), - (ContentData)properties.get(propertyQName)); - } - } - } - PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); - PropertyValue propertyValue = makePropertyValue(propertyDef, value); - values.put(propertyQName, propertyValue); - } - // Finally set node properties - fAVMService.setNodeProperties(avmVersionPath.getSecond(), values); - // Invoke policies - if (fInvokePolicies) - { - Map propsAfter = properties; - invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); - } - // Invoke policy behaviors. -// invokeOnUpdateNode(nodeRef); -// invokeOnUpdateProperties(nodeRef, oldProps, properties); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - } - - public void addProperties(NodeRef nodeRef, Map properties) - { - // Overwrite the current properties - Map currentProperties = getProperties(nodeRef); - currentProperties.putAll(properties); - setProperties(nodeRef, currentProperties); - } - - static QName [] fgBuiltinProperties = new QName [] - { - ContentModel.PROP_CREATED, - ContentModel.PROP_CREATOR, - ContentModel.PROP_MODIFIED, - ContentModel.PROP_MODIFIER, - ContentModel.PROP_OWNER, - ContentModel.PROP_CONTENT, - ContentModel.PROP_NAME, - ContentModel.PROP_NODE_UUID, - ContentModel.PROP_NODE_DBID, - ContentModel.PROP_STORE_PROTOCOL, - ContentModel.PROP_STORE_IDENTIFIER, - WCMModel.PROP_AVM_FILE_INDIRECTION, - WCMModel.PROP_AVM_DIR_INDIRECTION - }; - - /** - * Helper to distinguish built-in from generic properties. - * @param qName The name of the property to check. - * @return Whether qName is a built-in propety. - */ - private boolean isBuiltInProperty(QName qName) - { - for (QName name : fgBuiltinProperties) - { - if (name.equals(qName)) - { - return true; - } - } - return false; - } - - /** - * Sets the value of a property to be any Serializable instance. - * To remove a property value, use {@link #getProperties(NodeRef)}, remove the - * value and call {@link #setProperties(NodeRef, Map)}. - *

- * NOTE: Null values are allowed. - * - * @param nodeRef - * @param qname the fully qualified name of the property - * @param propertyValue the value of the property - never null - * @throws InvalidNodeRefException if the node could not be found - */ - public void setProperty(NodeRef nodeRef, QName qname, Serializable value) throws InvalidNodeRefException - { - // Invoke policy behaviors. - // invokeBeforeUpdateNode(nodeRef); - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - if (avmVersionPath.getFirst() >= 0) - { - throw new InvalidNodeRefException("Read only store.", nodeRef); - } - - Map propsBefore = null; - if (fInvokePolicies) - { - propsBefore = getProperties(nodeRef); - } - - if (isBuiltInProperty(qname)) - { - if (qname.equals(ContentModel.PROP_CONTENT)) - { - try - { - fAVMService.setContentData(avmVersionPath.getSecond(), (ContentData)value); - if (fInvokePolicies) - { - Map propsAfter = new HashMap(propsBefore); - propsAfter.put(ContentModel.PROP_CONTENT, value); - invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); - } - } - catch (ClassCastException e) - { - throw new AVMException("Invalid ContentData.", e); - } - } - return; - } - try - { - - PropertyDefinition propertyDef = dictionaryService.getProperty(qname); - PropertyValue propertyValue = makePropertyValue(propertyDef, value); - fAVMService.setNodeProperty(avmVersionPath.getSecond(), qname, propertyValue); - if (fInvokePolicies) - { - Map propsAfter = new HashMap(propsBefore); - propsAfter.put(qname, value); - invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); - } - // Map propsAfter = getProperties(nodeRef); - // Invoke policy behaviors. - // invokeOnUpdateNode(nodeRef); - // invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); - } - catch (AVMNotFoundException e) - { - throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); - } - } - - /** - * @param nodeRef the child node - * @return Returns a list of all parent-child associations that exist where the given - * node is the child - * @throws InvalidNodeRefException if the node could not be found - * - * @see #getParentAssocs(NodeRef, QNamePattern, QNamePattern) - */ - public List getParentAssocs(NodeRef nodeRef) throws InvalidNodeRefException - { - // TODO OK, for now we'll simply return the single parent that corresponds - // to the path stuffed in the NodeRef. - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - String path = avmVersionPath.getSecond(); - List result = new ArrayList(); - String [] splitPath = AVMNodeConverter.SplitBase(path); - if (splitPath[0] == null) - { - return result; - } - result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, - AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(), - splitPath[0]), - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, - splitPath[1]), - nodeRef, - true, - -1)); - return result; - } - - /** - * Gets all parent associations where the pattern of the association qualified - * name is a match - *

- * The resultant list is ordered by (a) explicit index and (b) association creation time. - * - * @param nodeRef the child node - * @param typeQNamePattern the pattern that the type qualified name of the association must match - * @param qnamePattern the pattern that the qnames of the assocs must match - * @return Returns a list of all parent-child associations that exist where the given - * node is the child - * @throws InvalidNodeRefException if the node could not be found - * - * @see ChildAssociationRef#getNthSibling() - * @see #setChildAssociationIndex(ChildAssociationRef, int) - * @see QName - * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL - */ - public List getParentAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern) - throws InvalidNodeRefException - { - if (!typeQNamePattern.isMatch(ContentModel.ASSOC_CONTAINS)) - { - return new ArrayList(); - } - List result = getParentAssocs(nodeRef); - if (result.size() == 0) - { - return result; - } - if (qnamePattern.isMatch(result.get(0).getQName())) - { - return result; - } - return new ArrayList(); - } - - /** - * Get all child associations of the given node. - *

- * The resultant list is ordered by (a) explicit index and (b) association creation time. - * - * @param nodeRef the parent node - usually a container - * @return Returns a collection of ChildAssocRef instances. If the - * node is not a container then the result will be empty. - * @throws InvalidNodeRefException if the node could not be found - * - * @see #getChildAssocs(NodeRef, QNamePattern, QNamePattern) - * @see #setChildAssociationIndex(ChildAssociationRef, int) - * @see ChildAssociationRef#getNthSibling() - */ - public List getChildAssocs(NodeRef nodeRef) throws InvalidNodeRefException - { - - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - List result = new ArrayList(); - SortedMap children = null; - try - { - children = - fAVMService.getDirectoryListing(version, - path); - } - catch (AVMNotFoundException e) - { - return result; - } - for (String name : children.keySet()) - { - result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, - nodeRef, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, - name), - AVMNodeConverter.ToNodeRef( - version, - AVMNodeConverter.ExtendAVMPath(path, name)), - true, - -1)); - } - return result; - } - - /** - * Gets all child associations where the pattern of the association qualified - * name is a match. - * - * @param nodeRef the parent node - usually a container - * @param typeQNamePattern the pattern that the type qualified name of the association must match - * @param qnamePattern the pattern that the qnames of the assocs must match - * @return Returns a list of ChildAssocRef instances. If the - * node is not a container then the result will be empty. - * @throws InvalidNodeRefException if the node could not be found - * - * @see QName - * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL - */ - public List getChildAssocs( - NodeRef nodeRef, - QNamePattern typeQNamePattern, - QNamePattern qnamePattern) - throws InvalidNodeRefException - { - List result = new ArrayList(); - if (!typeQNamePattern.isMatch(ContentModel.ASSOC_CONTAINS)) - { - return result; - } - // First check if we are matching on all - if (qnamePattern == null || !(qnamePattern instanceof QName)) - { - // Either null (always match) or we have to match on each, individually - List all = getChildAssocs(nodeRef); - for (ChildAssociationRef child : all) - { - if (qnamePattern == null || !qnamePattern.isMatch(child.getQName())) - { - continue; - } - result.add(child); - } - return result; - } - else - { - // We have a specific QName and therefore an exact path - QName qname = (QName) qnamePattern; - String name = qname.getLocalName(); - - // Resolve the container - Pair containerVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int containerVersion = containerVersionPath.getFirst(); - String containerPath = containerVersionPath.getSecond(); - try - { - // Get the descriptor for the container - AVMNodeDescriptor containerDescriptor = fAVMService.lookup(containerVersion, containerPath); - @SuppressWarnings("unused") // Might succeed or fail - AVMNodeDescriptor childDescriptor = fAVMService.lookup(containerDescriptor, name); - result.add( - new ChildAssociationRef( - ContentModel.ASSOC_CONTAINS, - nodeRef, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), - AVMNodeConverter.ToNodeRef( - containerVersion, - AVMNodeConverter.ExtendAVMPath(containerPath, name)), - true, - -1)); - } - catch (AVMNotFoundException e) - { - return result; - } - catch (AVMWrongTypeException e) - { - return result; - } - return result; - } - } - - @Override - public List getChildAssocs(NodeRef nodeRef, QNamePattern typeQName, QNamePattern qname, int maxResults, - boolean preload) throws InvalidNodeRefException - { - List result = getChildAssocs(nodeRef, typeQName, qname); - if (result.size() > maxResults) - { - return result.subList(0, maxResults); - } - return result; - } - - public List getChildAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, - QNamePattern qnamePattern, boolean preload) throws InvalidNodeRefException - { - return getChildAssocs(nodeRef, typeQNamePattern, qnamePattern); - } - - public List getChildAssocs(NodeRef nodeRef, Set childNodeTypes) - { - /* - * ETWOTWO-961 forced an implementation, but this is just a workaround. - * We do a listing and then keep files or folders looking specifically - * for cm:folder and cm:content types from childNodeTypes. - */ - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - List result = new ArrayList(); - SortedMap children = null; - try - { - children = - fAVMService.getDirectoryListing(version, - path); - } - catch (AVMNotFoundException e) - { - return result; - } - for (Map.Entry entry : children.entrySet()) - { - String name = entry.getKey(); - AVMNodeDescriptor descriptor = entry.getValue(); - if (descriptor.isFile()) - { - if (!childNodeTypes.contains(ContentModel.TYPE_CONTENT)) - { - continue; - } - } - else if (descriptor.isDirectory()) - { - if (!childNodeTypes.contains(ContentModel.TYPE_FOLDER)) - { - continue; - } - } - else - { - // Not a file or directory??? - continue; - } - result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, - nodeRef, - QName.createQName( - NamespaceService.CONTENT_MODEL_1_0_URI, - name), - AVMNodeConverter.ToNodeRef( - version, - AVMNodeConverter.ExtendAVMPath(path, name)), - true, - -1)); - } - return result; - } - - /** - * getChildrenByName - */ - public List getChildrenByName(NodeRef nodeRef, QName assocTypeQName, Collection childNames) - { - final List results = new ArrayList(100); - - if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) - { - throw new UnsupportedOperationException("AVM getChildrenByName only supports ASSOCS_CONTAINS."); - } - - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - try - { - for(String childName : childNames) - { - AVMNodeDescriptor child = fAVMService.lookup(avmVersionPath.getFirst(), - AVMUtil.extendAVMPath(avmVersionPath.getSecond(), childName)); - - if (child != null) - { - NodeRef childRef = AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(), - child.getPath()); - QName childQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, - childName); - ChildAssociationRef ref = new ChildAssociationRef(assocTypeQName, nodeRef, childQName, childRef); - - if(logger.isDebugEnabled()) - { - logger.debug("got a child node :" + ref); - } - results.add(ref); - } - } - return results; - } - catch (AVMException e) - { - logger.debug("exception in getChildrenByName ", e); - return results; - } - } - - - /** - * Get a child NodeRef by name. - * @param nodeRef The parent node. - * @param assocTypeQName The type of the Child Association. - * @param childName The name of the child to get. - */ - public NodeRef getChildByName(NodeRef nodeRef, QName assocTypeQName, String childName) - { - if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) - { - return null; - } - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - try - { - AVMNodeDescriptor child = fAVMService.lookup(avmVersionPath.getFirst(), - AVMUtil.extendAVMPath(avmVersionPath.getSecond(), childName)); - if (child == null) - { - return null; - } - return AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(), - child.getPath()); - } - catch (AVMException e) - { - return null; - } - } - - /** - * Fetches the primary parent-child relationship. - *

- * For a root node, the parent node reference will be null. - * - * @param nodeRef - * @return Returns the primary parent-child association of the node - * @throws InvalidNodeRefException if the node could not be found - */ - public ChildAssociationRef getPrimaryParent(NodeRef nodeRef) throws InvalidNodeRefException - { - List parents = getParentAssocs(nodeRef); - if (parents.size() == 0) - { - return new ChildAssociationRef(null, null, null, nodeRef); - } - return parents.get(0); - } - - /** - * @throws UnsupportedOperationException always - */ - @Override - public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) - throws InvalidNodeRefException, AssociationExistsException - { - throw new UnsupportedOperationException("AVM does not support arbitrary associations."); - } - - /** - * @throws UnsupportedOperationException always - */ - @Override - public void setAssociations(NodeRef sourceRef, QName assocTypeQName, List targetRefs) - { - throw new UnsupportedOperationException("AVM does not support arbitrary associations."); - } - - /** - * - * @param sourceRef the associaton source node - * @param targetRef the association target node - * @param assocTypeQName the qualified name of the association type - * @throws InvalidNodeRefException if either of the nodes could not be found - */ - public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) - throws InvalidNodeRefException - { - throw new UnsupportedOperationException("AVM does not support arbitrary associations."); - } - - /** - * Gets an association by ID. - * - * @param assocId - * the association id - * @return the association, or null if it does not exist - */ - public AssociationRef getAssoc(Long id) - { - return null; - } - - /** - * Fetches all associations from the given source where the associations' - * qualified names match the pattern provided. - * - * @param sourceRef the association source - * @param qnamePattern the association qname pattern to match against - * @return Returns a list of NodeAssocRef instances for which the - * given node is a source - * @throws InvalidNodeRefException if the source node could not be found - * - * @see QName - * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL - */ - public List getTargetAssocs(NodeRef sourceRef, QNamePattern qnamePattern) - throws InvalidNodeRefException - { - return new ArrayList(); - } - - /** - * Fetches all associations to the given target where the associations' - * qualified names match the pattern provided. - * - * @param targetRef the association target - * @param qnamePattern the association qname pattern to match against - * @return Returns a list of NodeAssocRef instances for which the - * given node is a target - * @throws InvalidNodeRefException - * - * @see QName - * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL - */ - public List getSourceAssocs(NodeRef targetRef, QNamePattern qnamePattern) - throws InvalidNodeRefException - { - return new ArrayList(); - } - - /** - * The root node has an entry in the path(s) returned. For this reason, there - * will always be at least one path element in the returned path(s). - * The first element will have a null parent reference and qname. - * - * @param nodeRef - * @return Returns the path to the node along the primary node path - * @throws InvalidNodeRefException if the node could not be found - * - * @see #getPaths(NodeRef, boolean) - */ - public Path getPath(NodeRef nodeRef) throws InvalidNodeRefException - { - // TODO Review later. This may be wrong. - Path path = new Path(); - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String currPath = avmVersionPath.getSecond(); - while (!currPath.endsWith("/")) - { - String [] splitPath = AVMNodeConverter.SplitBase(currPath); - String parentPath = splitPath[0]; - String name = splitPath[1]; - ChildAssociationRef caRef = - new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, - AVMNodeConverter.ToNodeRef(version, parentPath), - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, - name), - AVMNodeConverter.ToNodeRef(version, currPath), - true, - -1); - path.prepend(new Path.ChildAssocElement(caRef)); - currPath = parentPath; - } - ChildAssociationRef caRef = new ChildAssociationRef(null, null, null, - AVMNodeConverter.ToNodeRef(version, - currPath)); - path.prepend(new Path.ChildAssocElement(caRef)); - return path; - } - - /** - * The root node has an entry in the path(s) returned. For this reason, there - * will always be at least one path element in the returned path(s). - * The first element will have a null parent reference and qname. - * - * @param nodeRef - * @param primaryOnly true if only the primary path must be retrieved. If true, the - * result will have exactly one entry. - * @return Returns a List of all possible paths to the given node - * @throws InvalidNodeRefException if the node could not be found - */ - public List getPaths(NodeRef nodeRef, boolean primaryOnly) throws InvalidNodeRefException - { - List result = new ArrayList(); - result.add(getPath(nodeRef)); - return result; - } - - /** - * Get the node where archived items will have gone when deleted from the given store. - * - * @param storeRef the store that items were deleted from - * @return Returns the archive node parent - */ - public NodeRef getStoreArchiveNode(StoreRef storeRef) - { - throw new UnsupportedOperationException("AVM does not support this operation."); - } - - /** - * Restore an individual node (along with its sub-tree nodes) to the target location. - * The archived node must have the {@link org.alfresco.model.ContentModel#ASPECT_ARCHIVED archived aspect} - * set against it. - * - * @param archivedNodeRef the archived node - * @param destinationParentNodeRef the parent to move the node into - * or null to use the original - * @param assocTypeQName the primary association type name to use in the new location - * or null to use the original - * @param assocQName the primary association name to use in the new location - * or null to use the original - * @return Returns the reference to the newly created node - */ - public NodeRef restoreNode( - NodeRef archivedNodeRef, - NodeRef destinationParentNodeRef, - QName assocTypeQName, - QName assocQName) - { - throw new UnsupportedOperationException("AVM does not support this operation."); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.repository.NodeService#getChildAssocsWithoutParentAssocsOfType(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) - */ - public Collection getChildAssocsWithoutParentAssocsOfType(NodeRef parent, QName assocTypeQName) - { - throw new UnsupportedOperationException("AVM does not support this operation."); - } - - public Long getNodeAclId(NodeRef nodeRef) throws InvalidNodeRefException - { - throw new UnsupportedOperationException("getNodeAclId is unsupported for AVMNodeService"); - } - - @Override - public List getChildAssocsByPropertyValue( - NodeRef nodeRef, QName propertyQName, Serializable value) - { - throw new UnsupportedOperationException("AVM does not support this operation."); - } - - @Override - public int countChildAssocs(NodeRef nodeRef, boolean isPrimary) throws InvalidNodeRefException - { - throw new UnsupportedOperationException("AVM does not support this operation."); - } - -} +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . */ + +package org.alfresco.repo.avm; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMModel; +import org.alfresco.repo.avm.util.AVMUtil; +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.node.AbstractNodeServiceImpl; +import org.alfresco.service.cmr.avm.AVMException; +import org.alfresco.service.cmr.avm.AVMExistsException; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMNotFoundException; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMStoreDescriptor; +import org.alfresco.service.cmr.avm.AVMWrongTypeException; +import org.alfresco.service.cmr.dictionary.AspectDefinition; +import org.alfresco.service.cmr.dictionary.ClassDefinition; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryException; +import org.alfresco.service.cmr.dictionary.InvalidAspectException; +import org.alfresco.service.cmr.dictionary.InvalidTypeException; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.cmr.dictionary.TypeDefinition; +import org.alfresco.service.cmr.repository.AssociationExistsException; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.CyclicChildRelationshipException; +import org.alfresco.service.cmr.repository.InvalidChildAssociationRefException; +import org.alfresco.service.cmr.repository.InvalidNodeRefException; +import org.alfresco.service.cmr.repository.InvalidStoreRefException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.Path; +import org.alfresco.service.cmr.repository.StoreExistsException; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.repository.datatype.TypeConversionException; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.QNamePattern; +import org.alfresco.util.Pair; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * NodeService implementing facade over AVMService. + * @author britt + */ +public class AVMNodeService extends AbstractNodeServiceImpl implements NodeService +{ + private static Log logger = LogFactory.getLog(AVMNodeService.class); + + /** + * Flag for whether policy callbacks are made. + */ + private boolean fInvokePolicies = false; + + /** + * Reference to AVMService. + */ + private AVMService fAVMService; + + /** + * Set the AVMService. For Spring. + * @param service The AVMService instance. + */ + public void setAvmService(AVMService service) + { + fAVMService = service; + } + + /** + * Default constructor. + */ + public AVMNodeService() + { + } + + public void setInvokePolicies(boolean invoke) + { + fInvokePolicies = invoke; + } + + /** + * Helper method to convert the Serializable value into a full, + * persistable {@link PropertyValue}. + *

+ * Where the property definition is null, the value will take on the + * {@link DataTypeDefinition#ANY generic ANY} value. + *

+ * Where the property definition specifies a multi-valued property but the + * value provided is not a collection, the value will be wrapped in a collection. + * + * @param propertyDef the property dictionary definition, may be null + * @param value the value, which will be converted according to the definition - + * may be null + * @return Returns the persistable property value + */ + protected PropertyValue makePropertyValue(PropertyDefinition propertyDef, Serializable value) + { + // get property attributes + QName propertyTypeQName = null; + if (propertyDef == null) // property not recognised + { + // allow it for now - persisting excess properties can be useful sometimes + propertyTypeQName = DataTypeDefinition.ANY; + } + else + { + propertyTypeQName = propertyDef.getDataType().getName(); + // check that multi-valued properties are allowed + boolean isMultiValued = propertyDef.isMultiValued(); + if (isMultiValued && !(value instanceof Collection)) + { + if (value != null) + { + // put the value into a collection + // the implementation gives back a Serializable list + value = (Serializable) Collections.singletonList(value); + } + } + else if (!isMultiValued && (value instanceof Collection)) + { + // we only allow this case if the property type is ANY + if (!propertyTypeQName.equals(DataTypeDefinition.ANY)) + { + throw new DictionaryException( + "A single-valued property of this type may not be a collection: \n" + + " Property: " + propertyDef + "\n" + + " Type: " + propertyTypeQName + "\n" + + " Value: " + value); + } + } + } + try + { + PropertyValue propertyValue = new PropertyValue(propertyTypeQName, value); + // done + return propertyValue; + } + catch (TypeConversionException e) + { + throw new TypeConversionException( + "The property value is not compatible with the type defined for the property: \n" + + " property: " + (propertyDef == null ? "unknown" : propertyDef) + "\n" + + " value: " + value + "\n" + + " value type: " + value.getClass(), + e); + } + } + + /** + * Extracts the externally-visible property from the {@link PropertyValue propertyValue}. + * + * @param propertyDef the model property definition - may be null + * @param propertyValue the persisted property + * @return Returns the value of the property in the format dictated by the property + * definition, or null if the property value is null + */ + protected Serializable makeSerializableValue(PropertyDefinition propertyDef, PropertyValue propertyValue) + { + if (propertyValue == null) + { + return null; + } + // get property attributes + QName propertyTypeQName = null; + if (propertyDef == null) + { + // allow this for now + propertyTypeQName = DataTypeDefinition.ANY; + } + else + { + propertyTypeQName = propertyDef.getDataType().getName(); + } + try + { + Serializable value = propertyValue.getValue(propertyTypeQName); + // done + return value; + } + catch (TypeConversionException e) + { + throw new TypeConversionException( + "The property value is not compatible with the type defined for the property: \n" + + " property: " + (propertyDef == null ? "unknown" : propertyDef) + "\n" + + " property value: " + propertyValue, + e); + } + } + + /** + * Gets a list of all available node store references + * + * @return Returns a list of store references + */ + public List getStores() + { + /* Sparta: disable/remove WCM/AVM + // For AVM stores we fake up StoreRefs. + List stores = fAVMService.getStores(); + List result = new ArrayList(); + for (AVMStoreDescriptor desc : stores) + { + String name = desc.getName(); + result.add(new StoreRef(StoreRef.PROTOCOL_AVM, name)); + } + return result; + */ + return Collections.emptyList(); + } + + /** + * Create a new AVM store. + * @param protocol the implementation protocol + * @param identifier the protocol-specific identifier + * @return Returns a reference to the store + * @throws StoreExistsException + */ + public StoreRef createStore(String protocol, String identifier) throws StoreExistsException + { + StoreRef result = new StoreRef(StoreRef.PROTOCOL_AVM, identifier); + // invokeBeforeCreateStore(ContentModel.TYPE_STOREROOT, result); + try + { + fAVMService.createStore(identifier); + NodeRef rootRef = getRootNode(result); + addAspect(rootRef, ContentModel.ASPECT_ROOT, + Collections.emptyMap()); + // invokeOnCreateStore(rootRef); + return result; + } + catch (AVMExistsException e) + { + throw new StoreExistsException(result, e); + } + } + + /** + * @throws UnsupportedOperationException Always + */ + public void deleteStore(StoreRef storeRef) throws InvalidStoreRefException + { + throw new UnsupportedOperationException(); + } + + /** + * Does the indicated store exist? + * @param storeRef a reference to the store to look for + * @return Returns true if the store exists, otherwise false + */ + public boolean exists(StoreRef storeRef) + { + return fAVMService.getStore(storeRef.getIdentifier()) != null; + } + + /** + * @param nodeRef a reference to the node to look for + * @return Returns true if the node exists, otherwise false + */ + public boolean exists(NodeRef nodeRef) + { + Pair avmInfo = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmInfo.getFirst(); + String avmPath = avmInfo.getSecond(); + return fAVMService.lookup(version, avmPath) != null; + } + + /** + * Gets the ID of the last transaction that caused the node to change. This includes + * deletions, so it is possible that the node being referenced no longer exists. + * If the node never existed, then null is returned. + * + * @param nodeRef a reference to a current or previously existing node + * @return Returns the status of the node, or null if the node never existed + */ + public NodeRef.Status getNodeStatus(NodeRef nodeRef) + { + // TODO Need to find out if this is important and if so + // need to capture Transaction IDs. + return new NodeRef.Status(null, nodeRef, "Unknown", null, !exists(nodeRef)); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public NodeRef getNodeRef(Long nodeId) + { + throw new UnsupportedOperationException(); + } + + /** + * @param storeRef a reference to an existing store + * @return Returns a reference to the root node of the store + * @throws InvalidStoreRefException if the store could not be found + */ + public NodeRef getRootNode(StoreRef storeRef) throws InvalidStoreRefException + { + String storeName = storeRef.getIdentifier(); + if (fAVMService.getStore(storeName) != null) + { + return AVMNodeConverter.ToNodeRef(-1, storeName + ":/"); + } + else + { + throw new InvalidStoreRefException(storeName +":/" + " not found.", storeRef); + } + } + + public Set getAllRootNodes(StoreRef storeRef) + { + return Collections.singleton(getRootNode(storeRef)); + } + + /** + * @see #createNode(NodeRef, QName, QName, QName, Map) + */ + public ChildAssociationRef createNode( + NodeRef parentRef, + QName assocTypeQName, + QName assocQName, + QName nodeTypeQName) + throws InvalidNodeRefException, InvalidTypeException + { + return createNode(parentRef, + assocTypeQName, + assocQName, + nodeTypeQName, + new HashMap()); + } + + /** + * Creates a new, non-abstract, real node as a primary child of the given parent node. + * + * @param parentRef the parent node + * @param assocTypeQName the type of the association to create. This is used + * for verification against the data dictionary. + * @param assocQName the qualified name of the association + * @param nodeTypeQName a reference to the node type + * @param properties optional map of properties to keyed by their qualified names + * @return Returns a reference to the newly created child association + * @throws InvalidNodeRefException if the parent reference is invalid + * @throws InvalidTypeException if the node type reference is not recognised + * + * @see org.alfresco.service.cmr.dictionary.DictionaryService + */ + @SuppressWarnings("deprecation") + public ChildAssociationRef createNode( + NodeRef parentRef, + QName assocTypeQName, + QName assocQName, + QName nodeTypeQName, + Map properties) + throws InvalidNodeRefException, InvalidTypeException + { + // AVM stores only allow simple child associations. + if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) + { + throw new InvalidTypeException(assocTypeQName); + } + String nodeName = assocQName.getLocalName(); + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); + int version = avmVersionPath.getFirst(); + if (version >= 0) + { + throw new InvalidNodeRefException("Read only store.", parentRef); + } + String avmPath = avmVersionPath.getSecond(); + // Invoke policy behavior. + // invokeBeforeUpdateNode(parentRef); + // invokeBeforeCreateNode(parentRef, assocTypeQName, assocQName, nodeTypeQName); + // Look up the type definition in the dictionary. + TypeDefinition nodeTypeDef = dictionaryService.getType(nodeTypeQName); + // Do the creates for supported types, or error out. + try + { + if (nodeTypeQName.equals(WCMModel.TYPE_AVM_PLAIN_FOLDER) || + nodeTypeQName.equals(ContentModel.TYPE_FOLDER)) + { + fAVMService.createDirectory(avmPath, nodeName); + } + else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_PLAIN_CONTENT) || + nodeTypeQName.equals(ContentModel.TYPE_CONTENT)) + { + OutputStream os = fAVMService.createFile(avmPath, nodeName); + try + { + if (os != null) { os.close(); } + } + catch (IOException ioe) + { + logger.warn("Failed to close output stream when creating file '"+AVMUtil.extendAVMPath(avmPath, nodeName)+"'"+ioe.getMessage()); + } + } + else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_LAYERED_CONTENT)) + { + NodeRef indirection = (NodeRef)properties.get(WCMModel.PROP_AVM_FILE_INDIRECTION); + if (indirection == null) + { + throw new InvalidTypeException("No Indirection Property", nodeTypeQName); + } + Pair indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection); + fAVMService.createLayeredFile(indVersionPath.getSecond(), avmPath, nodeName); + } + else if (nodeTypeQName.equals(WCMModel.TYPE_AVM_LAYERED_FOLDER)) + { + NodeRef indirection = (NodeRef)properties.get(WCMModel.PROP_AVM_DIR_INDIRECTION); + if (indirection == null) + { + throw new InvalidTypeException("No Indirection Property.", nodeTypeQName); + } + Pair indVersionPath = AVMNodeConverter.ToAVMVersionPath(indirection); + fAVMService.createLayeredDirectory(indVersionPath.getSecond(), avmPath, nodeName); + } + else + { + throw new InvalidTypeException("Invalid node type for AVM.", nodeTypeQName); + } + properties.putAll(getDefaultProperties(nodeTypeDef)); + addDefaultAspects(nodeTypeDef, avmPath, properties); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmPath + " not found.", parentRef); + } + catch (AVMExistsException e) + { + throw new InvalidNodeRefException("Child " + nodeName + " exists", parentRef); + } + String newAVMPath = AVMNodeConverter.ExtendAVMPath(avmPath, nodeName); + NodeRef childRef = AVMNodeConverter.ToNodeRef(-1, newAVMPath); + properties.putAll(getDefaultProperties(nodeTypeDef)); + addDefaultAspects(nodeTypeDef, newAVMPath, properties); + Map props = new HashMap(); + for (Map.Entry entry : properties.entrySet()) + { + QName propertyQName = entry.getKey(); + if (isBuiltInProperty(propertyQName)) + { + continue; + } + Serializable value = entry.getValue(); + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + props.put(propertyQName, propertyValue); + } + fAVMService.setNodeProperties(newAVMPath, props); + ChildAssociationRef ref = + new ChildAssociationRef(assocTypeQName, + parentRef, + assocQName, + childRef, + true, + -1); +// invokeOnCreateNode(ref); +// invokeOnUpdateNode(parentRef); +// if (properties.size() != 0) +// { +// invokeOnUpdateProperties(childRef, new HashMap(), properties); +// } + return ref; + } + + /** + * Moves the primary location of the given node. + *

+ * This involves changing the node's primary parent and possibly the name of the + * association referencing it. + *

+ * If the new parent is in a different store from the original, then the entire + * node hierarchy is moved to the new store. Inter-store associations are not + * affected. + * + * @param nodeToMoveRef the node to move + * @param newParentRef the new parent of the moved node + * @param assocTypeQName the type of the association to create. This is used + * for verification against the data dictionary. + * @param assocQName the qualified name of the new child association + * @return Returns a reference to the newly created child association + * @throws InvalidNodeRefException if either the parent node or move node reference is invalid + * @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add + * + * @see #getPrimaryParent(NodeRef) + */ + public ChildAssociationRef moveNode( + NodeRef nodeToMoveRef, + NodeRef newParentRef, + QName assocTypeQName, + QName assocQName) + throws InvalidNodeRefException + { + // AVM stores only allow simple child associations. + if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) + { + throw new InvalidTypeException(assocTypeQName); + } + // Extract the parts from the source. + Pair src = AVMNodeConverter.ToAVMVersionPath(nodeToMoveRef); + int srcVersion = src.getFirst(); + if (srcVersion >= 0) + { + throw new InvalidNodeRefException("Read Only Store.", nodeToMoveRef); + } + String srcPath = src.getSecond(); + String [] splitSrc = null; + try + { + splitSrc = AVMNodeConverter.SplitBase(srcPath); + } + catch (AVMException e) + { + throw new InvalidNodeRefException("Invalid src path.", nodeToMoveRef); + } + String srcParent = splitSrc[0]; + if (srcParent == null) + { + throw new InvalidNodeRefException("Cannot rename root node.", nodeToMoveRef); + } + String srcName = splitSrc[1]; + // Extract and setup the parts of the destination. + Pair dst = AVMNodeConverter.ToAVMVersionPath(newParentRef); + if (dst.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read Only Store.", newParentRef); + } + String dstParent = dst.getSecond(); + String dstName = assocQName.getLocalName(); + // TODO Invoke policy behavior. Not quite sure how to translate this. + NodeRef oldParentRef = AVMNodeConverter.ToNodeRef(-1, srcParent); + ChildAssociationRef oldAssocRef = + new ChildAssociationRef(assocTypeQName, + oldParentRef, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, srcName), + nodeToMoveRef, + true, + -1); +// invokeBeforeDeleteChildAssociation(oldAssocRef); + String dstPath = AVMNodeConverter.ExtendAVMPath(dstParent, dstName); + NodeRef newChildRef = AVMNodeConverter.ToNodeRef(-1, dstPath); +// invokeBeforeUpdateNode(oldParentRef); +// invokeBeforeUpdateNode(newParentRef); + // Actually perform the rename and return a pseudo + // ChildAssociationRef. + try + { + fAVMService.rename(srcParent, srcName, dstParent, dstName); + ChildAssociationRef newAssocRef = + new ChildAssociationRef(assocTypeQName, + newParentRef, + assocQName, + newChildRef, + true, + -1); + invokeOnMoveNode(oldAssocRef, newAssocRef); +// invokeOnCreateChildAssociation(newAssocRef); +// invokeOnDeleteChildAssociation(oldAssocRef); +// invokeOnUpdateNode(oldParentRef); +// invokeOnUpdateNode(newParentRef); + return newAssocRef; + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException("Non existent node.", nodeToMoveRef); + } + catch (AVMExistsException e) + { + throw new InvalidNodeRefException("Target already exists.", newParentRef); + } + catch (AVMException e) + { + throw new InvalidNodeRefException("Illegal move.", nodeToMoveRef); + } + } + + /** + * Set the ordering index of the child association. This affects the ordering of + * of the return values of methods that return a set of children or child + * associations. + * + * @param childAssocRef the child association that must be moved in the order + * @param index an arbitrary index that will affect the return order + * + * @see #getChildAssocs(NodeRef) + * @see #getChildAssocs(NodeRef, QNamePattern, QNamePattern) + * @see ChildAssociationRef#getNthSibling() + */ + public void setChildAssociationIndex( + ChildAssociationRef childAssocRef, + int index) + throws InvalidChildAssociationRefException + { + // TODO We'll keep this a no-op unless there's a + // compelling reason to implement this capability + // for the AVM repository. + } + + /** + * @param nodeRef + * @return Returns the type name + * @throws InvalidNodeRefException if the node could not be found + * + * @see org.alfresco.service.cmr.dictionary.DictionaryService + */ + public QName getType(NodeRef nodeRef) throws InvalidNodeRefException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(), + avmVersionPath.getSecond()); + if (desc == null) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + if (desc.isPlainDirectory()) + { + return WCMModel.TYPE_AVM_PLAIN_FOLDER; + } + else if (desc.isPlainFile()) + { + return WCMModel.TYPE_AVM_PLAIN_CONTENT; + } + else if (desc.isLayeredDirectory()) + { + return WCMModel.TYPE_AVM_LAYERED_FOLDER; + } + else + { + return WCMModel.TYPE_AVM_LAYERED_CONTENT; + } + } + + /** + * Re-sets the type of the node. Can be called in order specialise a node to a sub-type. + * + * This should be used with caution since calling it changes the type of the node and thus + * implies a different set of aspects, properties and associations. It is the calling codes + * responsibility to ensure that the node is in a approriate state after changing the type. + * + * @param nodeRef the node reference + * @param typeQName the type QName + * + * @since 1.1 + */ + public void setType(NodeRef nodeRef, QName typeQName) throws InvalidNodeRefException + { + throw new UnsupportedOperationException("AVM Types are immutable."); + } + + /** + * Applies an aspect to the given node. After this method has been called, + * the node with have all the aspect-related properties present + * + * @param nodeRef + * @param aspectTypeQName the aspect to apply to the node + * @param aspectProperties a minimum of the mandatory properties required for + * the aspect + * @throws InvalidNodeRefException + * @throws InvalidAspectException if the class reference is not to a valid aspect + * + * @see org.alfresco.service.cmr.dictionary.DictionaryService#getAspect(QName) + * @see org.alfresco.service.cmr.dictionary.ClassDefinition#getProperties() + */ + public void addAspect( + NodeRef nodeRef, + QName aspectTypeQName, + Map aspectProperties) + throws InvalidNodeRefException, InvalidAspectException + { + // Check that the aspect exists. + AspectDefinition aspectDef = this.dictionaryService.getAspect(aspectTypeQName); + if (aspectDef == null) + { + throw new InvalidAspectException("The aspect is invalid: " + aspectTypeQName, + aspectTypeQName); + } + // Invoke policy behaviors. +// invokeBeforeUpdateNode(nodeRef); +// invokeBeforeAddAspect(nodeRef, aspectTypeQName); + // Crack the nodeRef. + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + if (version >= 0) + { + throw new InvalidNodeRefException("Read Only node.", nodeRef); + } + String avmPath = avmVersionPath.getSecond(); + // Accumulate properties. + Map properties = new HashMap(); + // Add the supplied properties. + if (aspectProperties != null) + { + properties.putAll(aspectProperties); + } + // Now set any unspecified default properties for the aspect. + Map defaultProperties = getDefaultProperties(aspectDef); + properties.putAll(defaultProperties); + // Now add any cascading aspects. + addDefaultAspects(aspectDef, avmPath, properties); + // Set the property values on the AVM Node. + if (properties.size() != 0) + { + Map props = new HashMap(); + for (Map.Entry entry : properties.entrySet()) + { + QName propertyQName = entry.getKey(); + if (isBuiltInProperty(propertyQName)) + { + continue; + } + Serializable value = entry.getValue(); + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + props.put(propertyQName, propertyValue); + } + if (props.size() != 0) + { + fAVMService.setNodeProperties(avmPath, props); + } + } + if (isBuiltinAspect(aspectTypeQName)) + { + // No more work to do in this case. + return; + } + try + { + fAVMService.addAspect(avmPath, aspectTypeQName); + // Invoke policy behaviors. +// invokeOnUpdateNode(nodeRef); +// invokeOnAddAspect(nodeRef, aspectTypeQName); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(nodeRef); + } + } + + /** + * Add any aspects that are mandatory for the ClassDefinition. + * @param classDef The ClassDefinition. + * @param path The path to the AVMNode. + * @param properties The in/out map of accumulated properties. + */ + private void addDefaultAspects(ClassDefinition classDef, String path, + Map properties) + { + NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, path); + // Get mandatory aspects. + List defaultAspectDefs = classDef.getDefaultAspects(); + // add all the aspects (and there dependent aspects recursively). + for (AspectDefinition def : defaultAspectDefs) + { +// invokeBeforeAddAspect(nodeRef, def.getName()); + addAspect(nodeRef, def.getName(), Collections.emptyMap()); + properties.putAll(getDefaultProperties(def)); +// invokeOnAddAspect(nodeRef, def.getName()); + // recurse + addDefaultAspects(def, path, properties); + } + } + + /** + * Remove an aspect and all related properties from a node + * + * @param nodeRef + * @param aspectTypeQName the type of aspect to remove + * @throws InvalidNodeRefException if the node could not be found + * @throws InvalidAspectException if the the aspect is unknown or if the + * aspect is mandatory for the class of the node + */ + public void removeAspect(NodeRef nodeRef, QName aspectTypeQName) + throws InvalidNodeRefException, InvalidAspectException + { + // Invoke policy behaviors. +// invokeBeforeUpdateNode(nodeRef); +// invokeBeforeRemoveAspect(nodeRef, aspectTypeQName); + AspectDefinition def = dictionaryService.getAspect(aspectTypeQName); + if (def == null) + { + throw new InvalidAspectException(aspectTypeQName); + } + if (isBuiltinAspect(aspectTypeQName)) + { + // TODO shouldn't we be throwing some kind of exception here. + return; + } + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + if (version >= 0) + { + throw new InvalidNodeRefException("Read Only Node.", nodeRef); + } + String path = avmVersionPath.getSecond(); + try + { + if (fAVMService.hasAspect(-1, path, aspectTypeQName)) + { + fAVMService.removeAspect(path, aspectTypeQName); + Map propDefs = def.getProperties(); + for (QName propertyName : propDefs.keySet()) + { + fAVMService.deleteNodeProperty(path, propertyName); + } + } + // Invoke policy behaviors. +// invokeOnUpdateNode(nodeRef); +// invokeOnRemoveAspect(nodeRef, aspectTypeQName); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(nodeRef); + } + } + + /** + * Determines if a given aspect is present on a node. Aspects may only be + * removed if they are NOT mandatory. + * + * @param nodeRef + * @param aspectTypeQName + * @return Returns true if the aspect has been applied to the given node, + * otherwise false + * @throws InvalidNodeRefException if the node could not be found + * @throws InvalidAspectException if the aspect reference is invalid + */ + public boolean hasAspect(NodeRef nodeRef, QName aspectTypeQName) + throws InvalidNodeRefException, InvalidAspectException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + String path = avmVersionPath.getSecond(); + if (isBuiltinAspect(aspectTypeQName)) + { + return true; + } + return fAVMService.hasAspect(version, path, aspectTypeQName); + } + + private static QName [] fgBuiltinAspects = new QName[] { ContentModel.ASPECT_AUDITABLE, + ContentModel.ASPECT_REFERENCEABLE }; + + private boolean isBuiltinAspect(QName aspectQName) + { + for (QName builtin : fgBuiltinAspects) + { + if (builtin.equals(aspectQName)) + { + return true; + } + } + return false; + } + + /** + * @param nodeRef + * @return Returns a set of all aspects applied to the node, including mandatory + * aspects + * @throws InvalidNodeRefException if the node could not be found + */ + public Set getAspects(NodeRef nodeRef) throws InvalidNodeRefException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + String path = avmVersionPath.getSecond(); + Set result = new HashSet(); + // Add the builtin ones. + for (QName name : fgBuiltinAspects) + { + result.add(name); + } + try + { + for (QName name : fAVMService.getAspects(version, path)) + { + result.add(name); + } + return result; + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(nodeRef); + } + } + + /** + * Deletes the given node. + *

+ * All associations (both children and regular node associations) + * will be deleted, and where the given node is the primary parent, + * the children will also be cascade deleted. + * + * @param nodeRef reference to a node within a store + * @throws InvalidNodeRefException if the reference given is invalid + */ + public void deleteNode(NodeRef nodeRef) throws InvalidNodeRefException + { + // Invoke policy behaviors. +// invokeBeforeDeleteNode(nodeRef); + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + if (avmVersionPath.getFirst() != -1) + { + throw new InvalidNodeRefException("Read only store.", nodeRef); + } + String [] avmPathBase = AVMNodeConverter.SplitBase(avmVersionPath.getSecond()); + if (avmPathBase[0] == null) + { + throw new InvalidNodeRefException("Cannot delete root node.", nodeRef); + } + try + { +// QName nodeTypeQName = getType(nodeRef); +// Set aspects = getAspects(nodeRef); + fAVMService.removeNode(avmPathBase[0], avmPathBase[1]); +// ChildAssociationRef childAssocRef = +// new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, +// AVMNodeConverter.ToNodeRef(-1, avmPathBase[0]), +// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, +// avmPathBase[1]), +// nodeRef); +// invokeOnDeleteNode(childAssocRef, nodeTypeQName, aspects, false); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() +" not found.", nodeRef); + } + } + + /** + * Makes a parent-child association between the given nodes. Both nodes must belong to the same store. + *

+ * + * @param parentRef + * @param childRef + * @param assocTypeQName the qualified name of the association type as defined in the datadictionary + * @param qname the qualified name of the association + * @return Returns a reference to the newly created child association + * @throws InvalidNodeRefException if the parent or child nodes could not be found + * @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add + */ + public ChildAssociationRef addChild( + NodeRef parentRef, + NodeRef childRef, + QName assocTypeQName, + QName qname) throws InvalidNodeRefException + { + return addChild(Collections.singletonList(parentRef), childRef, assocTypeQName, qname).get(0); + } + + /** + * Associates a given child node with a given collection of parents. All nodes must belong to the same store. + *

+ * + * + * @param parentRefs + * @param childRef + * @param assocTypeQName the qualified name of the association type as defined in the datadictionary + * @param qname the qualified name of the association + * @return Returns a reference to the newly created child association + * @throws InvalidNodeRefException if the parent or child nodes could not be found + * @throws CyclicChildRelationshipException if the child partakes in a cyclic relationship after the add + */ + public List addChild( + Collection parentRefs, + NodeRef childRef, + QName assocTypeQName, + QName qname) throws InvalidNodeRefException + { + Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); + AVMNodeDescriptor child = fAVMService.lookup(childVersionPath.getFirst(), + childVersionPath.getSecond()); + if (child == null) + { + throw new InvalidNodeRefException(childVersionPath.getSecond() + " not found.", childRef); + } + + List childAssociationRefs = new ArrayList(parentRefs.size()); + for (NodeRef parentRef : parentRefs) + { + Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); + if (parentVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read Only.", parentRef); + } + try + { + fAVMService.link(parentVersionPath.getSecond(), qname.getLocalName(), child); + ChildAssociationRef newChild = new ChildAssociationRef(assocTypeQName, parentRef, qname, + AVMNodeConverter.ToNodeRef(-1, AVMNodeConverter.ExtendAVMPath(parentVersionPath.getSecond(), + qname.getLocalName()))); + childAssociationRefs.add(newChild); + } + catch (AVMException e) + { + throw new InvalidNodeRefException("Could not link.", childRef); + } + } + return childAssociationRefs; + } + + /** + * Severs all parent-child relationships between two nodes. + *

+ * The child node will be cascade deleted if one of the associations was the + * primary association, i.e. the one with which the child node was created. + * + * @param parentRef the parent end of the association + * @param childRef the child end of the association + * @throws InvalidNodeRefException if the parent or child nodes could not be found + */ + public void removeChild(NodeRef parentRef, NodeRef childRef) throws InvalidNodeRefException + { + Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); + if (parentVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", parentRef); + } + Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); + if (childVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", childRef); + } + String parentPath = parentVersionPath.getSecond(); + String childPath = childVersionPath.getSecond(); + String [] childPathBase = AVMNodeConverter.SplitBase(childPath); + if (childPathBase[0] == null || !childPathBase[0].equals(parentPath)) + { + throw new InvalidNodeRefException(childPath + " not a child of " + parentPath, childRef); + } + try + { +// ChildAssociationRef assocRef = +// new ChildAssociationRef(ContentModel.ASSOC_CHILDREN, +// AVMNodeConverter.ToNodeRef(-1, parentPath), +// QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, +// childPathBase[1]), +// AVMNodeConverter.ToNodeRef(-1, childPath)); +// invokeBeforeDeleteChildAssociation(assocRef); + fAVMService.removeNode(childPathBase[0], childPathBase[1]); +// invokeOnDeleteChildAssociation(assocRef); +// invokeOnUpdateNode(AVMNodeConverter.ToNodeRef(-1, parentPath)); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(childPathBase[1] + " not found in " + childPathBase[0], + childRef); + } + } + + /** + * TODO: Check implementation + */ + public boolean removeChildAssociation(ChildAssociationRef childAssocRef) + { + NodeRef parentRef = childAssocRef.getParentRef(); + NodeRef childRef = childAssocRef.getChildRef(); + Pair parentVersionPath = AVMNodeConverter.ToAVMVersionPath(parentRef); + if (parentVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", parentRef); + } + Pair childVersionPath = AVMNodeConverter.ToAVMVersionPath(childRef); + if (childVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", childRef); + } + String parentPath = parentVersionPath.getSecond(); + String childPath = childVersionPath.getSecond(); + String [] childPathBase = AVMNodeConverter.SplitBase(childPath); + if (childPathBase[0] == null || !childPathBase[0].equals(parentPath)) + { + return false; + } + try + { + fAVMService.removeNode(childPathBase[0], childPathBase[1]); + return true; + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException("Not found.", childRef); + } + } + + /** + * TODO: Implement + */ + public boolean removeSecondaryChildAssociation(ChildAssociationRef childAssocRef) + { + throw new UnsupportedOperationException(); + } + + /** + * @param nodeRef + * @return Returns all properties keyed by their qualified name + * @throws InvalidNodeRefException if the node could not be found + */ + public Map getProperties(NodeRef nodeRef) throws InvalidNodeRefException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + Map props = null; + AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(), + avmVersionPath.getSecond()); + try + { + props = fAVMService.getNodeProperties(avmVersionPath.getFirst(), + avmVersionPath.getSecond()); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + Map result = new HashMap(); + for (QName qName : props.keySet()) + { + PropertyValue value = props.get(qName); + PropertyDefinition def = dictionaryService.getProperty(qName); + result.put(qName, makeSerializableValue(def, value)); + } + // Now spoof properties that are built in. + result.put(ContentModel.PROP_CREATED, new Date(desc.getCreateDate())); + result.put(ContentModel.PROP_CREATOR, desc.getCreator()); + result.put(ContentModel.PROP_MODIFIED, new Date(desc.getModDate())); + result.put(ContentModel.PROP_MODIFIER, desc.getLastModifier()); + result.put(ContentModel.PROP_OWNER, desc.getOwner()); + result.put(ContentModel.PROP_NAME, desc.getName()); + result.put(ContentModel.PROP_NODE_UUID, "UNKNOWN"); + result.put(ContentModel.PROP_NODE_DBID, new Long(desc.getId())); + result.put(ContentModel.PROP_STORE_PROTOCOL, "avm"); + result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier()); + if (desc.isLayeredDirectory()) + { + result.put(WCMModel.PROP_AVM_DIR_INDIRECTION, + AVMNodeConverter.ToNodeRef(-1, desc.getIndirection())); + } + if (desc.isLayeredFile()) + { + result.put(WCMModel.PROP_AVM_FILE_INDIRECTION, + AVMNodeConverter.ToNodeRef(-1, desc.getIndirection())); + } + if (desc.isFile()) + { + try + { + ContentData contentData = fAVMService.getContentDataForRead(avmVersionPath.getFirst(), + avmVersionPath.getSecond()); + result.put(ContentModel.PROP_CONTENT, contentData); + } + catch (AVMException e) + { + // TODO For now ignore. + } + } + return result; + } + + /** + * @param nodeRef + * @param qname the qualified name of the property + * @return Returns the value of the property, or null if not yet set + * @throws InvalidNodeRefException if the node could not be found + */ + public Serializable getProperty(NodeRef nodeRef, QName qname) throws InvalidNodeRefException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + if (isBuiltInProperty(qname)) + { + return getBuiltInProperty(avmVersionPath, qname, nodeRef); + } + try + { + PropertyValue value = fAVMService.getNodeProperty(avmVersionPath.getFirst(), + avmVersionPath.getSecond(), + qname); + if (value == null) + { + return null; + } + PropertyDefinition def = this.dictionaryService.getProperty(qname); + return makeSerializableValue(def, value); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + } + + /** + * {@inheritDoc} + */ + public void removeProperty(NodeRef nodeRef, QName qname) throws InvalidNodeRefException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + if (isBuiltInProperty(qname)) + { + // Ignore + return; + } + try + { + fAVMService.deleteNodeProperty(avmVersionPath.getSecond(), qname); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + } + + /** + * A Helper to spoof built in properties. + * @param avmVersionPath The broken out version and path from a NodeRef. + * @param qName The name of the property to retrieve. + * @param nodeRef The original NodeRef (for error reporting). + * @return The property value. + */ + private Serializable getBuiltInProperty(Pair avmVersionPath, + QName qName, + NodeRef nodeRef) + { + if (qName.equals(ContentModel.PROP_CONTENT)) + { + try + { + ContentData contentData = + fAVMService.getContentDataForRead(avmVersionPath.getFirst(), + avmVersionPath.getSecond()); + return contentData; + } + catch (AVMException e) + { + // TODO This seems very wrong. Do something better + // sooner rather than later. + return null; + } + } + AVMNodeDescriptor desc = fAVMService.lookup(avmVersionPath.getFirst(), + avmVersionPath.getSecond()); + if (desc == null) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + if (qName.equals(ContentModel.PROP_CREATED)) + { + return new Date(desc.getCreateDate()); + } + else if (qName.equals(ContentModel.PROP_CREATOR)) + { + return desc.getCreator(); + } + else if (qName.equals(ContentModel.PROP_MODIFIED)) + { + return new Date(desc.getModDate()); + } + else if (qName.equals(ContentModel.PROP_MODIFIER)) + { + return desc.getLastModifier(); + } + else if (qName.equals(ContentModel.PROP_OWNER)) + { + return desc.getOwner(); + } + else if (qName.equals(ContentModel.PROP_NAME)) + { + return desc.getName(); + } + else if (qName.equals(ContentModel.PROP_NODE_UUID)) + { + return "UNKNOWN"; + } + else if (qName.equals(ContentModel.PROP_NODE_DBID)) + { + return new Long(desc.getId()); + } + else if (qName.equals(ContentModel.PROP_STORE_PROTOCOL)) + { + return "avm"; + } + else if (qName.equals(ContentModel.PROP_STORE_IDENTIFIER)) + { + return nodeRef.getStoreRef().getIdentifier(); + } + else if (qName.equals(WCMModel.PROP_AVM_DIR_INDIRECTION)) + { + if (desc.isLayeredDirectory()) + { + return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()); + } + return null; + } + else if (qName.equals(WCMModel.PROP_AVM_FILE_INDIRECTION)) + { + if (desc.isLayeredFile()) + { + return AVMNodeConverter.ToNodeRef(-1, desc.getIndirection()); + } + return null; + } + else + { + logger.error("Invalid Built In Property: " + qName); + return null; + } + } + + /** + * Set the values of all properties to be an Serializable instances. + * The properties given must still fulfill the requirements of the class and + * aspects relevant to the node. + *

+ * NOTE: Null values are allowed. + * + * @param nodeRef + * @param properties all the properties of the node keyed by their qualified names + * @throws InvalidNodeRefException if the node could not be found + */ + public void setProperties(NodeRef nodeRef, Map properties) throws InvalidNodeRefException + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + if (avmVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", nodeRef); + } + // TODO Not sure this try block is necessary. + try + { + // Prepare fr policy invocation. + Map propsBefore = null; + if (fInvokePolicies) + { + propsBefore = getProperties(nodeRef); + } + // Remove all properties + fAVMService.deleteNodeProperties(avmVersionPath.getSecond()); + // Rebuild node properties + Map values = new HashMap(); + for (Map.Entry entry : properties.entrySet()) + { + QName propertyQName = entry.getKey(); + Serializable value = entry.getValue(); + // For AVM nodes is in place. + if (isBuiltInProperty(propertyQName)) + { + if (propertyQName.equals(ContentModel.PROP_CONTENT)) + { + AVMNodeDescriptor desc = fAVMService.lookup(-1, avmVersionPath.getSecond()); + if (desc == null) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + if (desc.isPlainFile()) + { + fAVMService.setContentData(avmVersionPath.getSecond(), + (ContentData)properties.get(propertyQName)); + } + } + } + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + values.put(propertyQName, propertyValue); + } + // Finally set node properties + fAVMService.setNodeProperties(avmVersionPath.getSecond(), values); + // Invoke policies + if (fInvokePolicies) + { + Map propsAfter = properties; + invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); + } + // Invoke policy behaviors. +// invokeOnUpdateNode(nodeRef); +// invokeOnUpdateProperties(nodeRef, oldProps, properties); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + } + + public void addProperties(NodeRef nodeRef, Map properties) + { + // Overwrite the current properties + Map currentProperties = getProperties(nodeRef); + currentProperties.putAll(properties); + setProperties(nodeRef, currentProperties); + } + + static QName [] fgBuiltinProperties = new QName [] + { + ContentModel.PROP_CREATED, + ContentModel.PROP_CREATOR, + ContentModel.PROP_MODIFIED, + ContentModel.PROP_MODIFIER, + ContentModel.PROP_OWNER, + ContentModel.PROP_CONTENT, + ContentModel.PROP_NAME, + ContentModel.PROP_NODE_UUID, + ContentModel.PROP_NODE_DBID, + ContentModel.PROP_STORE_PROTOCOL, + ContentModel.PROP_STORE_IDENTIFIER, + WCMModel.PROP_AVM_FILE_INDIRECTION, + WCMModel.PROP_AVM_DIR_INDIRECTION + }; + + /** + * Helper to distinguish built-in from generic properties. + * @param qName The name of the property to check. + * @return Whether qName is a built-in propety. + */ + private boolean isBuiltInProperty(QName qName) + { + for (QName name : fgBuiltinProperties) + { + if (name.equals(qName)) + { + return true; + } + } + return false; + } + + /** + * Sets the value of a property to be any Serializable instance. + * To remove a property value, use {@link #getProperties(NodeRef)}, remove the + * value and call {@link #setProperties(NodeRef, Map)}. + *

+ * NOTE: Null values are allowed. + * + * @param nodeRef + * @param qname the fully qualified name of the property + * @param propertyValue the value of the property - never null + * @throws InvalidNodeRefException if the node could not be found + */ + public void setProperty(NodeRef nodeRef, QName qname, Serializable value) throws InvalidNodeRefException + { + // Invoke policy behaviors. + // invokeBeforeUpdateNode(nodeRef); + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + if (avmVersionPath.getFirst() >= 0) + { + throw new InvalidNodeRefException("Read only store.", nodeRef); + } + + Map propsBefore = null; + if (fInvokePolicies) + { + propsBefore = getProperties(nodeRef); + } + + if (isBuiltInProperty(qname)) + { + if (qname.equals(ContentModel.PROP_CONTENT)) + { + try + { + fAVMService.setContentData(avmVersionPath.getSecond(), (ContentData)value); + if (fInvokePolicies) + { + Map propsAfter = new HashMap(propsBefore); + propsAfter.put(ContentModel.PROP_CONTENT, value); + invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); + } + } + catch (ClassCastException e) + { + throw new AVMException("Invalid ContentData.", e); + } + } + return; + } + try + { + + PropertyDefinition propertyDef = dictionaryService.getProperty(qname); + PropertyValue propertyValue = makePropertyValue(propertyDef, value); + fAVMService.setNodeProperty(avmVersionPath.getSecond(), qname, propertyValue); + if (fInvokePolicies) + { + Map propsAfter = new HashMap(propsBefore); + propsAfter.put(qname, value); + invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); + } + // Map propsAfter = getProperties(nodeRef); + // Invoke policy behaviors. + // invokeOnUpdateNode(nodeRef); + // invokeOnUpdateProperties(nodeRef, propsBefore, propsAfter); + } + catch (AVMNotFoundException e) + { + throw new InvalidNodeRefException(avmVersionPath.getSecond() + " not found.", nodeRef); + } + } + + /** + * @param nodeRef the child node + * @return Returns a list of all parent-child associations that exist where the given + * node is the child + * @throws InvalidNodeRefException if the node could not be found + * + * @see #getParentAssocs(NodeRef, QNamePattern, QNamePattern) + */ + public List getParentAssocs(NodeRef nodeRef) throws InvalidNodeRefException + { + // TODO OK, for now we'll simply return the single parent that corresponds + // to the path stuffed in the NodeRef. + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + String path = avmVersionPath.getSecond(); + List result = new ArrayList(); + String [] splitPath = AVMNodeConverter.SplitBase(path); + if (splitPath[0] == null) + { + return result; + } + result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(), + splitPath[0]), + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + splitPath[1]), + nodeRef, + true, + -1)); + return result; + } + + /** + * Gets all parent associations where the pattern of the association qualified + * name is a match + *

+ * The resultant list is ordered by (a) explicit index and (b) association creation time. + * + * @param nodeRef the child node + * @param typeQNamePattern the pattern that the type qualified name of the association must match + * @param qnamePattern the pattern that the qnames of the assocs must match + * @return Returns a list of all parent-child associations that exist where the given + * node is the child + * @throws InvalidNodeRefException if the node could not be found + * + * @see ChildAssociationRef#getNthSibling() + * @see #setChildAssociationIndex(ChildAssociationRef, int) + * @see QName + * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL + */ + public List getParentAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern) + throws InvalidNodeRefException + { + if (!typeQNamePattern.isMatch(ContentModel.ASSOC_CONTAINS)) + { + return new ArrayList(); + } + List result = getParentAssocs(nodeRef); + if (result.size() == 0) + { + return result; + } + if (qnamePattern.isMatch(result.get(0).getQName())) + { + return result; + } + return new ArrayList(); + } + + /** + * Get all child associations of the given node. + *

+ * The resultant list is ordered by (a) explicit index and (b) association creation time. + * + * @param nodeRef the parent node - usually a container + * @return Returns a collection of ChildAssocRef instances. If the + * node is not a container then the result will be empty. + * @throws InvalidNodeRefException if the node could not be found + * + * @see #getChildAssocs(NodeRef, QNamePattern, QNamePattern) + * @see #setChildAssociationIndex(ChildAssociationRef, int) + * @see ChildAssociationRef#getNthSibling() + */ + public List getChildAssocs(NodeRef nodeRef) throws InvalidNodeRefException + { + + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + String path = avmVersionPath.getSecond(); + List result = new ArrayList(); + SortedMap children = null; + try + { + children = + fAVMService.getDirectoryListing(version, + path); + } + catch (AVMNotFoundException e) + { + return result; + } + for (String name : children.keySet()) + { + result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + nodeRef, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + name), + AVMNodeConverter.ToNodeRef( + version, + AVMNodeConverter.ExtendAVMPath(path, name)), + true, + -1)); + } + return result; + } + + /** + * Gets all child associations where the pattern of the association qualified + * name is a match. + * + * @param nodeRef the parent node - usually a container + * @param typeQNamePattern the pattern that the type qualified name of the association must match + * @param qnamePattern the pattern that the qnames of the assocs must match + * @return Returns a list of ChildAssocRef instances. If the + * node is not a container then the result will be empty. + * @throws InvalidNodeRefException if the node could not be found + * + * @see QName + * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL + */ + public List getChildAssocs( + NodeRef nodeRef, + QNamePattern typeQNamePattern, + QNamePattern qnamePattern) + throws InvalidNodeRefException + { + List result = new ArrayList(); + if (!typeQNamePattern.isMatch(ContentModel.ASSOC_CONTAINS)) + { + return result; + } + // First check if we are matching on all + if (qnamePattern == null || !(qnamePattern instanceof QName)) + { + // Either null (always match) or we have to match on each, individually + List all = getChildAssocs(nodeRef); + for (ChildAssociationRef child : all) + { + if (qnamePattern == null || !qnamePattern.isMatch(child.getQName())) + { + continue; + } + result.add(child); + } + return result; + } + else + { + // We have a specific QName and therefore an exact path + QName qname = (QName) qnamePattern; + String name = qname.getLocalName(); + + // Resolve the container + Pair containerVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int containerVersion = containerVersionPath.getFirst(); + String containerPath = containerVersionPath.getSecond(); + try + { + // Get the descriptor for the container + AVMNodeDescriptor containerDescriptor = fAVMService.lookup(containerVersion, containerPath); + @SuppressWarnings("unused") // Might succeed or fail + AVMNodeDescriptor childDescriptor = fAVMService.lookup(containerDescriptor, name); + result.add( + new ChildAssociationRef( + ContentModel.ASSOC_CONTAINS, + nodeRef, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), + AVMNodeConverter.ToNodeRef( + containerVersion, + AVMNodeConverter.ExtendAVMPath(containerPath, name)), + true, + -1)); + } + catch (AVMNotFoundException e) + { + return result; + } + catch (AVMWrongTypeException e) + { + return result; + } + return result; + } + } + + @Override + public List getChildAssocs(NodeRef nodeRef, QNamePattern typeQName, QNamePattern qname, int maxResults, + boolean preload) throws InvalidNodeRefException + { + List result = getChildAssocs(nodeRef, typeQName, qname); + if (result.size() > maxResults) + { + return result.subList(0, maxResults); + } + return result; + } + + public List getChildAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, + QNamePattern qnamePattern, boolean preload) throws InvalidNodeRefException + { + return getChildAssocs(nodeRef, typeQNamePattern, qnamePattern); + } + + public List getChildAssocs(NodeRef nodeRef, Set childNodeTypes) + { + /* + * ETWOTWO-961 forced an implementation, but this is just a workaround. + * We do a listing and then keep files or folders looking specifically + * for cm:folder and cm:content types from childNodeTypes. + */ + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + String path = avmVersionPath.getSecond(); + List result = new ArrayList(); + SortedMap children = null; + try + { + children = + fAVMService.getDirectoryListing(version, + path); + } + catch (AVMNotFoundException e) + { + return result; + } + for (Map.Entry entry : children.entrySet()) + { + String name = entry.getKey(); + AVMNodeDescriptor descriptor = entry.getValue(); + if (descriptor.isFile()) + { + if (!childNodeTypes.contains(ContentModel.TYPE_CONTENT)) + { + continue; + } + } + else if (descriptor.isDirectory()) + { + if (!childNodeTypes.contains(ContentModel.TYPE_FOLDER)) + { + continue; + } + } + else + { + // Not a file or directory??? + continue; + } + result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + nodeRef, + QName.createQName( + NamespaceService.CONTENT_MODEL_1_0_URI, + name), + AVMNodeConverter.ToNodeRef( + version, + AVMNodeConverter.ExtendAVMPath(path, name)), + true, + -1)); + } + return result; + } + + /** + * getChildrenByName + */ + public List getChildrenByName(NodeRef nodeRef, QName assocTypeQName, Collection childNames) + { + final List results = new ArrayList(100); + + if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) + { + throw new UnsupportedOperationException("AVM getChildrenByName only supports ASSOCS_CONTAINS."); + } + + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + try + { + for(String childName : childNames) + { + AVMNodeDescriptor child = fAVMService.lookup(avmVersionPath.getFirst(), + AVMUtil.extendAVMPath(avmVersionPath.getSecond(), childName)); + + if (child != null) + { + NodeRef childRef = AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(), + child.getPath()); + QName childQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + childName); + ChildAssociationRef ref = new ChildAssociationRef(assocTypeQName, nodeRef, childQName, childRef); + + if(logger.isDebugEnabled()) + { + logger.debug("got a child node :" + ref); + } + results.add(ref); + } + } + return results; + } + catch (AVMException e) + { + logger.debug("exception in getChildrenByName ", e); + return results; + } + } + + + /** + * Get a child NodeRef by name. + * @param nodeRef The parent node. + * @param assocTypeQName The type of the Child Association. + * @param childName The name of the child to get. + */ + public NodeRef getChildByName(NodeRef nodeRef, QName assocTypeQName, String childName) + { + if (!assocTypeQName.equals(ContentModel.ASSOC_CONTAINS)) + { + return null; + } + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + try + { + AVMNodeDescriptor child = fAVMService.lookup(avmVersionPath.getFirst(), + AVMUtil.extendAVMPath(avmVersionPath.getSecond(), childName)); + if (child == null) + { + return null; + } + return AVMNodeConverter.ToNodeRef(avmVersionPath.getFirst(), + child.getPath()); + } + catch (AVMException e) + { + return null; + } + } + + /** + * Fetches the primary parent-child relationship. + *

+ * For a root node, the parent node reference will be null. + * + * @param nodeRef + * @return Returns the primary parent-child association of the node + * @throws InvalidNodeRefException if the node could not be found + */ + public ChildAssociationRef getPrimaryParent(NodeRef nodeRef) throws InvalidNodeRefException + { + List parents = getParentAssocs(nodeRef); + if (parents.size() == 0) + { + return new ChildAssociationRef(null, null, null, nodeRef); + } + return parents.get(0); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public AssociationRef createAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) + throws InvalidNodeRefException, AssociationExistsException + { + throw new UnsupportedOperationException("AVM does not support arbitrary associations."); + } + + /** + * @throws UnsupportedOperationException always + */ + @Override + public void setAssociations(NodeRef sourceRef, QName assocTypeQName, List targetRefs) + { + throw new UnsupportedOperationException("AVM does not support arbitrary associations."); + } + + /** + * + * @param sourceRef the associaton source node + * @param targetRef the association target node + * @param assocTypeQName the qualified name of the association type + * @throws InvalidNodeRefException if either of the nodes could not be found + */ + public void removeAssociation(NodeRef sourceRef, NodeRef targetRef, QName assocTypeQName) + throws InvalidNodeRefException + { + throw new UnsupportedOperationException("AVM does not support arbitrary associations."); + } + + /** + * Gets an association by ID. + * + * @param assocId + * the association id + * @return the association, or null if it does not exist + */ + public AssociationRef getAssoc(Long id) + { + return null; + } + + /** + * Fetches all associations from the given source where the associations' + * qualified names match the pattern provided. + * + * @param sourceRef the association source + * @param qnamePattern the association qname pattern to match against + * @return Returns a list of NodeAssocRef instances for which the + * given node is a source + * @throws InvalidNodeRefException if the source node could not be found + * + * @see QName + * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL + */ + public List getTargetAssocs(NodeRef sourceRef, QNamePattern qnamePattern) + throws InvalidNodeRefException + { + return new ArrayList(); + } + + /** + * Fetches all associations to the given target where the associations' + * qualified names match the pattern provided. + * + * @param targetRef the association target + * @param qnamePattern the association qname pattern to match against + * @return Returns a list of NodeAssocRef instances for which the + * given node is a target + * @throws InvalidNodeRefException + * + * @see QName + * @see org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL + */ + public List getSourceAssocs(NodeRef targetRef, QNamePattern qnamePattern) + throws InvalidNodeRefException + { + return new ArrayList(); + } + + /** + * The root node has an entry in the path(s) returned. For this reason, there + * will always be at least one path element in the returned path(s). + * The first element will have a null parent reference and qname. + * + * @param nodeRef + * @return Returns the path to the node along the primary node path + * @throws InvalidNodeRefException if the node could not be found + * + * @see #getPaths(NodeRef, boolean) + */ + public Path getPath(NodeRef nodeRef) throws InvalidNodeRefException + { + // TODO Review later. This may be wrong. + Path path = new Path(); + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + String currPath = avmVersionPath.getSecond(); + while (!currPath.endsWith("/")) + { + String [] splitPath = AVMNodeConverter.SplitBase(currPath); + String parentPath = splitPath[0]; + String name = splitPath[1]; + ChildAssociationRef caRef = + new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, + AVMNodeConverter.ToNodeRef(version, parentPath), + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + name), + AVMNodeConverter.ToNodeRef(version, currPath), + true, + -1); + path.prepend(new Path.ChildAssocElement(caRef)); + currPath = parentPath; + } + ChildAssociationRef caRef = new ChildAssociationRef(null, null, null, + AVMNodeConverter.ToNodeRef(version, + currPath)); + path.prepend(new Path.ChildAssocElement(caRef)); + return path; + } + + /** + * The root node has an entry in the path(s) returned. For this reason, there + * will always be at least one path element in the returned path(s). + * The first element will have a null parent reference and qname. + * + * @param nodeRef + * @param primaryOnly true if only the primary path must be retrieved. If true, the + * result will have exactly one entry. + * @return Returns a List of all possible paths to the given node + * @throws InvalidNodeRefException if the node could not be found + */ + public List getPaths(NodeRef nodeRef, boolean primaryOnly) throws InvalidNodeRefException + { + List result = new ArrayList(); + result.add(getPath(nodeRef)); + return result; + } + + /** + * Get the node where archived items will have gone when deleted from the given store. + * + * @param storeRef the store that items were deleted from + * @return Returns the archive node parent + */ + public NodeRef getStoreArchiveNode(StoreRef storeRef) + { + throw new UnsupportedOperationException("AVM does not support this operation."); + } + + /** + * Restore an individual node (along with its sub-tree nodes) to the target location. + * The archived node must have the {@link org.alfresco.model.ContentModel#ASPECT_ARCHIVED archived aspect} + * set against it. + * + * @param archivedNodeRef the archived node + * @param destinationParentNodeRef the parent to move the node into + * or null to use the original + * @param assocTypeQName the primary association type name to use in the new location + * or null to use the original + * @param assocQName the primary association name to use in the new location + * or null to use the original + * @return Returns the reference to the newly created node + */ + public NodeRef restoreNode( + NodeRef archivedNodeRef, + NodeRef destinationParentNodeRef, + QName assocTypeQName, + QName assocQName) + { + throw new UnsupportedOperationException("AVM does not support this operation."); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.repository.NodeService#getChildAssocsWithoutParentAssocsOfType(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) + */ + public Collection getChildAssocsWithoutParentAssocsOfType(NodeRef parent, QName assocTypeQName) + { + throw new UnsupportedOperationException("AVM does not support this operation."); + } + + public Long getNodeAclId(NodeRef nodeRef) throws InvalidNodeRefException + { + throw new UnsupportedOperationException("getNodeAclId is unsupported for AVMNodeService"); + } + + @Override + public List getChildAssocsByPropertyValue( + NodeRef nodeRef, QName propertyQName, Serializable value) + { + throw new UnsupportedOperationException("AVM does not support this operation."); + } + + @Override + public int countChildAssocs(NodeRef nodeRef, boolean isPrimary) throws InvalidNodeRefException + { + throw new UnsupportedOperationException("AVM does not support this operation."); + } + +} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java b/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java deleted file mode 100644 index 071502bc29..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMNodeUnwrapper.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import org.hibernate.proxy.HibernateProxy; - -/** - * Utility for unwrapping (getting the actual instance of) an AVMNode from what - * may be a HibernateProxy. Bitter Hibernate note: Hibernate proxies for polymorphic - * types are fundamentally broken. - * @author britt - * - * @deprecated - */ -public class AVMNodeUnwrapper -{ - /** - * @deprecated - */ - public static AVMNode Unwrap(AVMNode node) - { - if (node instanceof HibernateProxy) - { - return (AVMNode)((HibernateProxy)node).getHibernateLazyInitializer().getImplementation(); - } - return node; - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java deleted file mode 100644 index 6b4cc1e853..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ /dev/null @@ -1,3472 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import org.alfresco.model.WCMModel; -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.content.ContentStore; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.avm.AVMStoreEntity; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMCycleException; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.AVMWrongTypeException; -import org.alfresco.service.cmr.avm.LayeringDescriptor; -import org.alfresco.service.cmr.avm.VersionDescriptor; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.security.AccessStatus; -import org.alfresco.service.cmr.security.PermissionContext; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.FileNameValidator; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This or AVMStore are the implementors of the operations specified by AVMService. - * - * @author britt - */ -public class AVMRepository -{ - /** The i18n'ized messages */ - private static final String MSG_CYCLE_ON_CREATE = "avm.cycle.create"; - private static final String MSG_CYCLE_ON_LOOKUP = "avm.cycle.lookup"; - - private static Log fgLogger = LogFactory.getLog(AVMRepository.class); - - /** - * The single instance of AVMRepository. - */ - private static AVMRepository fgInstance; - - /** - * The current lookup count. - */ - private ThreadLocal fLookupCount; - - /** - * Reference to the ContentStoreImpl - */ - private ContentStore fContentStore; - - /** - * The Lookup Cache instance. - */ - private LookupCache fLookupCache; - - private AVMStoreDAO fAVMStoreDAO; - - private AVMNodeDAO fAVMNodeDAO; - - private VersionRootDAO fVersionRootDAO; - - private VersionLayeredNodeEntryDAO fVersionLayeredNodeEntryDAO; - - private AVMStorePropertyDAO fAVMStorePropertyDAO; - - private ChildEntryDAO fChildEntryDAO; - - private PermissionService fPermissionService; - - // A bunch of TransactionListeners that do work for this. - - /** - * One for create store. - */ - private CreateStoreTxnListener fCreateStoreTxnListener; - - /** - * One for purge store. - */ - private PurgeStoreTxnListener fPurgeStoreTxnListener; - - /** - * One for create version. - */ - private CreateVersionTxnListener fCreateVersionTxnListener; - - /** - * One for purge version. - */ - private PurgeVersionTxnListener fPurgeVersionTxnListener; - - /** - * Create a new one. - */ - public AVMRepository() - { - fLookupCount = new ThreadLocal(); - fgInstance = this; - } - - /** - * Set the ContentService. - */ - public void setContentStore(ContentStore store) - { - fContentStore = store; - } - - /** - * Set the Lookup Cache instance. - * - * @param cache - * The instance to set. - */ - public void setLookupCache(LookupCache cache) - { - fLookupCache = cache; - } - - public void setCreateStoreTxnListener(CreateStoreTxnListener listener) - { - fCreateStoreTxnListener = listener; - } - - public void setPurgeStoreTxnListener(PurgeStoreTxnListener listener) - { - fPurgeStoreTxnListener = listener; - } - - public void setCreateVersionTxnListener(CreateVersionTxnListener listener) - { - fCreateVersionTxnListener = listener; - } - - public void setPurgeVersionTxnListener(PurgeVersionTxnListener listener) - { - fPurgeVersionTxnListener = listener; - } - - public void setAvmStoreDAO(AVMStoreDAO dao) - { - fAVMStoreDAO = dao; - } - - public void setAvmNodeDAO(AVMNodeDAO dao) - { - fAVMNodeDAO = dao; - } - - public void setVersionRootDAO(VersionRootDAO dao) - { - fVersionRootDAO = dao; - } - - public void setVersionLayeredNodeEntryDAO(VersionLayeredNodeEntryDAO dao) - { - fVersionLayeredNodeEntryDAO = dao; - } - - public void setAvmStorePropertyDAO(AVMStorePropertyDAO dao) - { - fAVMStorePropertyDAO = dao; - } - - public void setChildEntryDAO(ChildEntryDAO dao) - { - fChildEntryDAO = dao; - } - - public void setPermissionService(PermissionService service) - { - fPermissionService = service; - } - - /** - * Create a file. - * - * @param path - * The path to the containing directory. - * @param name - * The name for the new file. - */ - public OutputStream createFile(String path, String name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - OutputStream out = store.createFile(pathParts[1], name); - return out; - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Create a file with the given File as content. - * - * @param path - * The path to the containing directory. - * @param name - * The name to give the file. - * @param data - * The file contents. - */ - public void createFile(String path, String name, File data, List aspects, Map properties) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.createFile(pathParts[1], name, data, aspects, properties); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Create a new directory. - * - * @param path - * The path to the containing directory. - * @param name - * The name to give the directory. - */ - public void createDirectory(String path, String name, List aspects, Map properties) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.createDirectory(pathParts[1], name, aspects, properties); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Create a new directory. This assumes that the parent is already copied and therefore should only be used with - * great care. - * - * @param parent - * The parent node. - * @param name - * The name of the new directory. - * @return A descriptor for the newly created directory. - */ - public AVMNodeDescriptor createDirectory(AVMNodeDescriptor parent, String name) - { - AVMNode node = fAVMNodeDAO.getByID(parent.getId()); - if (node == null) - { - throw new AVMNotFoundException(parent.getId() + " not found."); - } - if (!(node instanceof DirectoryNode)) - { - throw new AVMWrongTypeException("Not a directory."); - } - if (!can(null, node, PermissionService.CREATE_CHILDREN, true)) - { - throw new AccessDeniedException("Not allowed to write in: " + parent); - } - // We need the store to do anything so... - String[] pathParts = SplitPath(parent.getPath()); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - DirectoryNode dir = (DirectoryNode) node; - DirectoryNode child = null; - Long parentAcl = dir.getAcl() == null ? null : dir.getAcl().getId(); - if (dir instanceof LayeredDirectoryNode) - { - // TODO - collapse save/update - child = new LayeredDirectoryNodeImpl((String) null, store, null, parentAcl, ACLCopyMode.INHERIT); - ((LayeredDirectoryNode) child).setPrimaryIndirection(false); - ((LayeredDirectoryNode) child).setLayerID(parent.getLayerID()); - - child.copyACLs(dir, ACLCopyMode.INHERIT); - - AVMDAOs.Instance().fAVMNodeDAO.update(child); - } - else - { - child = new PlainDirectoryNodeImpl(store); - - child.copyACLs(dir, ACLCopyMode.INHERIT); - - AVMDAOs.Instance().fAVMNodeDAO.save(child); - } - - dir.putChild(name, child); - - fLookupCache.onWrite(pathParts[0]); - AVMNodeDescriptor desc = child.getDescriptor(parent.getPath(), name, parent.getIndirection(), parent.getIndirectionVersion()); - return desc; - } - - /** - * Create a new layered directory. - * - * @param srcPath - * The target indirection for the new layered directory. - * @param dstPath - * The path to the containing directory. - * @param name - * The name for the new directory. - */ - public void createLayeredDirectory(String srcPath, String dstPath, String name) - { - if (dstPath.indexOf(srcPath) == 0) - { - throw new AVMCycleException(MSG_CYCLE_ON_CREATE); - } - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(dstPath); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.createLayeredDirectory(srcPath, pathParts[1], name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Create a new layered file. - * - * @param srcPath - * The target indirection for the new layered file. - * @param dstPath - * The path to the containing directory. - * @param name - * The name of the new layered file. - */ - public void createLayeredFile(String srcPath, String dstPath, String name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(dstPath); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.createLayeredFile(srcPath, pathParts[1], name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Create a new AVMStore. - * - * @param name - * The name to give the new AVMStore. - */ - public void createAVMStore(String name) - { - createAVMStore(name, null); - } - - public void createAVMStore(String name, Map props) - { - AlfrescoTransactionSupport.bindListener(fCreateStoreTxnListener); - if (getAVMStoreByName(name) != null) - { - throw new AVMExistsException("AVMStore exists: " + name); - } - // Newing up the object causes it to be written to the db. - AVMStore rep = new AVMStoreImpl(this, name); - - // Special handling for AVMStore creation. - AVMNode rootNode = rep.getRoot(); - rootNode.setStoreNew(null); - fAVMNodeDAO.update(rootNode); - - - if (props != null) - { - setStoreProperties(name, props); - } - - fCreateStoreTxnListener.storeCreated(name); - } - - /** - * Create a new branch. - * - * @param version - * The version to branch off. - * @param srcPath - * The path to make a branch from. - * @param dstPath - * The containing directory. - * @param name - * The name of the new branch. - */ - public void createBranch(int version, String srcPath, String dstPath, String name) - { - if (dstPath.indexOf(srcPath) == 0) - { - throw new AVMCycleException(MSG_CYCLE_ON_CREATE); - } - // Lookup the src node. - fLookupCount.set(1); - String[] pathParts; - Lookup sPath; - List layeredEntries = null; - try - { - pathParts = SplitPath(srcPath); - AVMStore srcRepo = getAVMStoreByName(pathParts[0]); - if (srcRepo == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - if (version < 0) - { - fLookupCache.onSnapshot(pathParts[0]); - version = srcRepo.createSnapshot("Branch Snapshot", null, new HashMap()).get(pathParts[0]); - } - sPath = srcRepo.lookup(version, pathParts[1], false, false); - if (sPath == null) - { - throw new AVMNotFoundException("Path not found."); - } - VersionRoot lastVersion = fVersionRootDAO.getByVersionID(srcRepo, version); - layeredEntries = fVersionLayeredNodeEntryDAO.get(lastVersion); - } - finally - { - fLookupCount.set(null); - } - // Lookup the destination directory. - fLookupCount.set(1); - try - { - pathParts = SplitPath(dstPath); - AVMStore dstRepo = getAVMStoreByName(pathParts[0]); - if (dstRepo == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true); - if (dPath == null) - { - throw new AVMNotFoundException("Path not found."); - } - DirectoryNode dirNode = (DirectoryNode) dPath.getCurrentNode(); - if (!can(dstRepo, dirNode, PermissionService.ADD_CHILDREN, dPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not permitted to add children: " + dstPath); - } - AVMNode srcNode = sPath.getCurrentNode(); - AVMNode dstNode = null; - // We do different things depending on what kind of thing we're - // branching from. I'd be considerably happier if we disallowed - // certain scenarios, but Jon won't let me :P (bhp). - - Long inheritAcl = srcNode.getAcl() == null ? null : srcNode.getAcl().getId(); - - if (srcNode.getType() == AVMNodeType.PLAIN_DIRECTORY) - { - dstNode = new PlainDirectoryNodeImpl((PlainDirectoryNode) srcNode, dstRepo, inheritAcl, ACLCopyMode.INHERIT); - } - else if (srcNode.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - dstNode = new LayeredDirectoryNodeImpl((LayeredDirectoryNode) srcNode, dstRepo, sPath, false, inheritAcl, ACLCopyMode.INHERIT); - - // note: re-use generated node id as a layer id - ((LayeredDirectoryNode) dstNode).setLayerID(dstNode.getId()); - - AVMDAOs.Instance().fAVMNodeDAO.update(dstNode); - } - else if (srcNode.getType() == AVMNodeType.LAYERED_FILE) - { - dstNode = new LayeredFileNodeImpl((LayeredFileNode) srcNode, dstRepo, inheritAcl, ACLCopyMode.INHERIT); - } - else - // This is a plain file. - { - dstNode = new PlainFileNodeImpl((PlainFileNode) srcNode, dstRepo, inheritAcl, ACLCopyMode.INHERIT); - } - // dstNode.setVersionID(dstRepo.getNextVersionID()); - dstNode.setAncestor(srcNode); - dirNode.putChild(name, dstNode); - // dirNode.updateModTime(); - String beginingPath = AVMUtil.normalizePath(srcPath); - String finalPath = AVMUtil.extendAVMPath(dstPath, name); - finalPath = AVMUtil.normalizePath(finalPath); - VersionRoot latestVersion = fVersionRootDAO.getMaxVersion(dstRepo); - for (VersionLayeredNodeEntry entry : layeredEntries) - { - String path = entry.getPath(); - if (!path.startsWith(srcPath)) - { - continue; - } - String newPath = finalPath + path.substring(beginingPath.length()); - VersionLayeredNodeEntry newEntry = new VersionLayeredNodeEntryImpl(latestVersion, newPath); - fVersionLayeredNodeEntryDAO.save(newEntry); - } - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get an output stream to a file. - * - * @param path - * The full path to the file. - * @return An OutputStream. - */ - public OutputStream getOutputStream(String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - OutputStream out = store.getOutputStream(pathParts[1]); - return out; - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get a content reader from a file node. - * - * @param version - * The version of the file. - * @param path - * The path to the file. - * @return A ContentReader. - */ - public ContentReader getContentReader(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getContentReader(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get a ContentWriter to a file node. - * - * @param path - * The path to the file. - * @param update true if the property must be updated atomically when the content write - * stream is closed (attaches a listener to the stream); false if the client code - * will perform the updates itself. - * @return A ContentWriter. - */ - public ContentWriter createContentWriter(String path, boolean update) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - ContentWriter writer = store.createContentWriter(pathParts[1], update); - return writer; - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Rename a node. - * - * @param srcPath - * Source containing directory. - * @param srcName - * Source name. - * @param dstPath - * Destination containing directory. - * @param dstName - * Destination name. - */ - public void rename(String srcPath, String srcName, String dstPath, String dstName) - { - String extDst = AVMUtil.extendAVMPath(dstPath, ""); - String extSrc = AVMUtil.extendAVMPath(AVMUtil.extendAVMPath(srcPath, srcName), ""); - if (extDst.indexOf(extSrc) == 0) - { - throw new AVMCycleException(MSG_CYCLE_ON_CREATE); - } - fLookupCount.set(1); - String[] pathParts; - Lookup sPath; - DirectoryNode srcDir; - AVMNode srcNode; - try - { - pathParts = SplitPath(srcPath); - AVMStore srcRepo = getAVMStoreByName(pathParts[0]); - if (srcRepo == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - sPath = srcRepo.lookupDirectory(-1, pathParts[1], true); - if (sPath == null) - { - throw new AVMNotFoundException("Path not found."); - } - srcDir = (DirectoryNode) sPath.getCurrentNode(); - - Pair temp = srcDir.lookupChild(sPath, srcName, false); - srcNode = (temp == null) ? null : temp.getFirst(); - if (srcNode == null) - { - throw new AVMNotFoundException("Not found: " + srcName); - } - if (!can(srcRepo, srcNode, PermissionService.DELETE_NODE, false)) - { - throw new AccessDeniedException("Not allowed to delete target: " + srcPath); - } - - fLookupCache.onDelete(pathParts[0]); - } - finally - { - fLookupCount.set(null); - } - fLookupCount.set(1); - try - { - pathParts = SplitPath(dstPath); - AVMStore dstRepo = getAVMStoreByName(pathParts[0]); - if (dstRepo == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true); - if (dPath == null) - { - throw new AVMNotFoundException("Path not found."); - } - DirectoryNode dstDir = (DirectoryNode) dPath.getCurrentNode(); - if (!can(dstRepo, dstDir, PermissionService.ADD_CHILDREN, dPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + dstPath); - } - Pair temp = dstDir.lookupChild(dPath, dstName, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - - boolean renameCase = false; - if (child != null && child.getType() != AVMNodeType.DELETED_NODE) - { - String avmSrcPath = AVMUtil.extendAVMPath(srcPath, srcName); - String avmDstPath = AVMUtil.extendAVMPath(dstPath, dstName); - - if ((avmSrcPath.equalsIgnoreCase(avmDstPath)) && (! srcName.equals(dstName))) - { - // specific rename 'case' only (within a store) - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("rename: only change case: from "+avmSrcPath+" to "+avmDstPath); - } - renameCase = true; - } - else - { - throw new AVMExistsException("Node exists: " + dstName); - } - } - - if (! renameCase) - { - // general rename/move - - Long parentAcl = dstDir.getAcl() == null ? null : dstDir.getAcl().getId(); - - AVMNode dstNode = null; - // We've passed the check, so we can go ahead and do the rename. - if (srcNode.getType() == AVMNodeType.PLAIN_DIRECTORY) - { - // If the source is layered then the renamed thing needs to be layered also. - if (sPath.isLayered()) - { - // If this is a rename happening in the same layer we make a new - // OverlayedDirectoryNode that is not a primary indirection layer. - // Otherwise we do make the new OverlayedDirectoryNode a primary - // Indirection layer. This complexity begs the question of whether - // we should allow renames from within one layer to within another - // layer. Allowing it makes the logic absurdly complex. - if (dPath.isLayered() && dPath.getTopLayer().equals(sPath.getTopLayer())) - { - dstNode = new LayeredDirectoryNodeImpl((PlainDirectoryNode) srcNode, dstRepo, sPath, true, parentAcl, ACLCopyMode.COPY); - ((LayeredDirectoryNode) dstNode).setLayerID(sPath.getTopLayer().getLayerID()); - } - else - { - dstNode = new LayeredDirectoryNodeImpl((DirectoryNode) srcNode, dstRepo, sPath, srcName, parentAcl, ACLCopyMode.COPY); - - // note: re-use generated node id as a layer id - ((LayeredDirectoryNode) dstNode).setLayerID(dstNode.getId()); - } - - AVMDAOs.Instance().fAVMNodeDAO.update(dstNode); - } - else - { - dstNode = new PlainDirectoryNodeImpl((PlainDirectoryNode) srcNode, dstRepo, parentAcl, ACLCopyMode.COPY); - } - } - else if (srcNode.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - if (!sPath.isLayered() || (sPath.isInThisLayer() && srcDir.getType() == AVMNodeType.LAYERED_DIRECTORY && ((LayeredDirectoryNode) srcDir).directlyContains(srcNode))) - { - Lookup srcLookup = lookup(-1, srcPath + "/" + srcName, true); - // Use the simple 'copy' constructor. - dstNode = new LayeredDirectoryNodeImpl((LayeredDirectoryNode) srcNode, dstRepo, srcLookup, true, parentAcl, ACLCopyMode.COPY); - ((LayeredDirectoryNode) dstNode).setLayerID(((LayeredDirectoryNode) srcNode).getLayerID()); - } - else - { - // If the source node is a primary indirection, then the 'copy' constructor - // is used. Otherwise the alternate constructor is called and its - // indirection is calculated from it's source context. - if (((LayeredDirectoryNode) srcNode).getPrimaryIndirection()) - { - Lookup srcLookup = lookup(-1, srcPath + "/" + srcName, true); - dstNode = new LayeredDirectoryNodeImpl((LayeredDirectoryNode) srcNode, dstRepo, srcLookup, true, parentAcl, ACLCopyMode.COPY); - } - else - { - dstNode = new LayeredDirectoryNodeImpl((DirectoryNode) srcNode, dstRepo, sPath, srcName, parentAcl, ACLCopyMode.COPY); - } - // What needs to be done here is dependent on whether the - // rename is to a layered context. If so then it should get the layer id - // of its destination parent. Otherwise it should get a new layer - // id. - if (dPath.isLayered()) - { - ((LayeredDirectoryNode) dstNode).setLayerID(dPath.getTopLayer().getLayerID()); - } - else - { - // note: re-use generated node id as a layer id - ((LayeredDirectoryNode) dstNode).setLayerID(dstNode.getId()); - } - } - - AVMDAOs.Instance().fAVMNodeDAO.update(dstNode); - } - else if (srcNode.getType() == AVMNodeType.LAYERED_FILE) - { - dstNode = new LayeredFileNodeImpl((LayeredFileNode) srcNode, dstRepo, parentAcl, ACLCopyMode.COPY); - } - else - // This is a plain file node. - { - dstNode = new PlainFileNodeImpl((PlainFileNode) srcNode, dstRepo, parentAcl, ACLCopyMode.COPY); - } - - srcDir.removeChild(sPath, srcName); - // srcDir.updateModTime(); - // dstNode.setVersionID(dstRepo.getNextVersionID()); - if (child != null) - { - dstNode.setAncestor(child); - } - - //dstDir.updateModTime(); - dstDir.putChild(dstName, dstNode); - if (child == null) - { - dstNode.setAncestor(srcNode); - } - } - else - { - // specific rename 'case' only (within a store) - - forceCopy(AVMUtil.extendAVMPath(srcPath, srcName)); - - Pair result = srcDir.lookupChildEntry(sPath, srcName, false); - if (result != null) - { - ChildKey key = result.getFirst().getKey(); - key.setName(srcName); - AVMDAOs.Instance().fChildEntryDAO.rename(key, dstName); - } - } - - fLookupCache.onWrite(pathParts[0]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Uncover a deleted name in a layered directory. - * - * @param dirPath - * The path to the layered directory. - * @param name - * The name to uncover. - */ - public void uncover(String dirPath, String name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(dirPath); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.uncover(pathParts[1], name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Create a snapshot of a single AVMStore. - * - * @param store - * The name of the repository. - * @param tag - * The short description. - * @param description - * The thick description. - * @return The version id of the newly snapshotted repository. - */ - public Map createSnapshot(String storeName, String tag, String description) - { - AlfrescoTransactionSupport.bindListener(fCreateVersionTxnListener); - AVMStore store = getAVMStoreByName(storeName); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+storeName); - } - Map result = store.createSnapshot(tag, description, new HashMap()); - for (Map.Entry entry : result.entrySet()) - { - fLookupCache.onSnapshot(entry.getKey()); - fCreateVersionTxnListener.versionCreated(entry.getKey(), entry.getValue()); - } - return result; - } - - /** - * Remove a node and everything underneath it. - * - * @param path - * The path to the containing directory. - * @param name - * The name of the node to remove. - */ - public void remove(String path, String name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onDelete(pathParts[0]); - store.removeNode(pathParts[1], name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get rid of all content that lives only in the given AVMStore. Also removes the AVMStore. - * - * @param name - * The name of the AVMStore to purge. - */ - public void purgeAVMStore(String name) - { - AlfrescoTransactionSupport.bindListener(fPurgeStoreTxnListener); - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - fLookupCache.onDelete(name); - AVMNode root = store.getRoot(); - // TODO Probably a special PermissionService.PURGE is needed. - if (!can(store, root, PermissionService.DELETE_CHILDREN, true)) - { - throw new AccessDeniedException("Not allowed to purge: " + name); - } - - root.setIsRoot(false); - fAVMNodeDAO.update(root); - - List vRoots = fVersionRootDAO.getAllInAVMStore(store); - for (VersionRoot vr : vRoots) - { - AVMNode node = fAVMNodeDAO.getByID(vr.getRoot().getId()); - - node.setIsRoot(false); - fAVMNodeDAO.update(node); - - fVersionLayeredNodeEntryDAO.delete(vr); - fVersionRootDAO.delete(vr); - } - List newGuys = fAVMNodeDAO.getNewInStore(store); - for (AVMNode newGuy : newGuys) - { - newGuy.setStoreNew(null); - - fAVMNodeDAO.update(newGuy); - } - fAVMStorePropertyDAO.delete(store); - fAVMStoreDAO.delete(store); - fAVMStoreDAO.invalidateCache(); - fPurgeStoreTxnListener.storePurged(name); - - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Purged store: "+name); - } - } - - /** - * Remove all content specific to a AVMRepository and version. - * - * @param name - * The name of the AVMStore. - * @param version - * The version to purge. - */ - public void purgeVersion(String name, int version) - { - AlfrescoTransactionSupport.bindListener(fPurgeVersionTxnListener); - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - fLookupCache.onDelete(name); - store.purgeVersion(version); - fPurgeVersionTxnListener.versionPurged(name, version); - - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Purged version: "+name+" "+version); - } - } - - /** - * Get an input stream from a file. - * - * @param version - * The version to look under. - * @param path - * The path to the file. - * @return An InputStream. - */ - public InputStream getInputStream(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getInputStream(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - public InputStream getInputStream(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (!(node instanceof FileNode)) - { - throw new AVMWrongTypeException(desc + " is not a File."); - } - if (!can(null, node, PermissionService.READ_CONTENT, false)) - { - throw new AccessDeniedException("Not allowed to read content: " + desc); - } - FileNode file = (FileNode) node; - ContentData data = file.getContentData(null); - if (data == null) - { - throw new AVMException(desc + " has no content."); - } - ContentReader reader = fContentStore.getReader(data.getContentUrl()); - return reader.getContentInputStream(); - } - - /** - * Get a listing of a directory. - * - * @param version - * The version to look under. - * @param path - * The path to the directory. - * @param includeDeleted - * Whether to see DeletedNodes. - * @return A List of FolderEntries. - */ - public SortedMap getListing(int version, String path, boolean includeDeleted) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getListing(version, pathParts[1], includeDeleted); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the list of nodes directly contained in a directory. - * - * @param version - * The version to look under. - * @param path - * The path to the directory to list. - * @return A Map of names to descriptors. - */ - public SortedMap getListingDirect(int version, String path, boolean includeDeleted) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getListingDirect(version, pathParts[1], includeDeleted); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the list of nodes directly contained in a directory. - * - * @param dir - * The descriptor to the directory node. - * @param includeDeleted - * Whether to include deleted children. - * @return A Map of names to descriptors. - */ - public SortedMap getListingDirect(AVMNodeDescriptor dir, boolean includeDeleted) - { - AVMNode node = fAVMNodeDAO.getByID(dir.getId()); - if (node == null) - { - throw new AVMBadArgumentException("Invalid Node."); - } - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - throw new AccessDeniedException("Not allowed to read children: " + dir); - } - if (node.getType() == AVMNodeType.PLAIN_DIRECTORY) - { - return getListing(dir, includeDeleted); - } - if (node.getType() != AVMNodeType.LAYERED_DIRECTORY) - { - throw new AVMWrongTypeException("Not a directory."); - } - LayeredDirectoryNode dirNode = (LayeredDirectoryNode) node; - return dirNode.getListingDirect(dir, includeDeleted); - } - - /** - * Get a directory listing from a directory node descriptor. - * - * @param dir - * The directory node descriptor. - * @return A SortedMap listing. - */ - public SortedMap getListing(AVMNodeDescriptor dir, boolean includeDeleted) - { - fLookupCount.set(1); - try - { - AVMNode node = fAVMNodeDAO.getByID(dir.getId()); - if (node == null) - { - throw new AVMBadArgumentException("Invalid Node."); - } - if (node.getType() != AVMNodeType.LAYERED_DIRECTORY && node.getType() != AVMNodeType.PLAIN_DIRECTORY) - { - throw new AVMWrongTypeException("Not a directory."); - } - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - throw new AccessDeniedException("Not allowed to read children: " + dir); - } - DirectoryNode dirNode = (DirectoryNode) node; - SortedMap listing = dirNode.getListing(dir, includeDeleted); - return listing; - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get a directory listing from a directory node descriptor fo children that match the given pattern - * - * @param dir - * The directory node descriptor. - * @return A SortedMap listing. - */ - public SortedMap getListing(AVMNodeDescriptor dir, String childNamePattern, boolean includeDeleted) - { - fLookupCount.set(1); - try - { - AVMNode node = fAVMNodeDAO.getByID(dir.getId()); - if (node == null) - { - throw new AVMBadArgumentException("Invalid Node."); - } - if (node.getType() != AVMNodeType.LAYERED_DIRECTORY && node.getType() != AVMNodeType.PLAIN_DIRECTORY) - { - throw new AVMWrongTypeException("Not a directory."); - } - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - throw new AccessDeniedException("Not allowed to read children: " + dir); - } - DirectoryNode dirNode = (DirectoryNode) node; - SortedMap listing = dirNode.getListing(dir, childNamePattern, includeDeleted); - return listing; - } - finally - { - fLookupCount.set(null); - } - } - - - /** - * Get the names of deleted nodes in a directory. - * - * @param version - * The version to look under. - * @param path - * The path to the directory. - * @return A List of names. - */ - public List getDeleted(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getDeleted(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get descriptors of all AVMStores. - * - * @return A list of all descriptors. - */ - public List getAVMStores() - { - List storeEntities = AVMDAOs.Instance().newAVMStoreDAO.getAllStores(); - - List result = new ArrayList(storeEntities.size()); - for (AVMStoreEntity storeEntity : storeEntities) - { - AVMStoreImpl store = new AVMStoreImpl(); - store.setId(storeEntity.getId()); - store.setName(storeEntity.getName()); - result.add(store.getDescriptor()); - } - - return result; - } - - /** - * Get a descriptor for an AVMStore. - * - * @param name - * The name to get. - * @return The descriptor. - */ - public AVMStoreDescriptor getAVMStore(String name) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - return null; - } - return store.getDescriptor(); - } - - /** - * Get all version for a given AVMStore. - * - * @param name - * The name of the AVMStore. - * @return A Set will all the version ids. - */ - public List getAVMStoreVersions(String name) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getVersions(); - } - - /** - * Get the set of versions between (inclusive) of the given dates. From or to may be null but not both. - * - * @param name - * The name of the AVMRepository. - * @param from - * The earliest date. - * @param to - * The latest date. - * @return The Set of version IDs. - */ - public List getAVMStoreVersions(String name, Date from, Date to) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getVersions(from, to); - } - - /** - * Get the indirection path for a layered node. - * - * @param version - * The version to look under. - * @param path - * The path to the node. - * @return The indirection path. - */ - public String getIndirectionPath(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getIndirectionPath(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the next version id for the given AVMStore. - * - * @param name - * The name of the AVMStore. - * @return The next version id. - */ - public int getLatestVersionID(String name) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getNextVersionID(); - } - - /** - * Get the latest extant snapshotted version id. - * - * @param name - * The store name. - */ - public int getLatestSnapshotID(String name) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getLastVersionID(); - } - - /** - * Get an AVMStore by name. - * - * @param name - * The name of the AVMStore. - * @return The AVMStore. - */ - private AVMStore getAVMStoreByName(String name) - { - AVMStore store = fAVMStoreDAO.getByName(name); - return store; - } - - /** - * Get a descriptor for an AVMStore root. - * - * @param version - * The version to get. - * @param name - * The name of the AVMStore. - * @return The descriptor for the root. - */ - public AVMNodeDescriptor getAVMStoreRoot(int version, String name) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Not found: " + name); - } - return store.getRoot(version); - } - - // TODO Fix this awful mess regarding cycle detection. - /** - * Lookup a node. - * - * @param version - * The version to look under. - * @param path - * The path to lookup. - * @param includeDeleted - * Whether to see DeletedNodes. - * @return A lookup object. - */ - public Lookup lookup(int version, String path, boolean includeDeleted) - { - Integer count = fLookupCount.get(); - try - { - if (count == null) - { - fLookupCount.set(1); - } - else - { - fLookupCount.set(count + 1); - } - if (fLookupCount.get() > 50) - { - throw new AVMCycleException(MSG_CYCLE_ON_LOOKUP); - } - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - return null; - } - return store.lookup(version, pathParts[1], false, includeDeleted); - } - finally - { - if (count == null) - { - fLookupCount.set(null); - } - } - } - - /** - * Lookup a descriptor from a directory descriptor. - * - * @param dir - * The directory descriptor. - * @param name - * The name of the child to lookup. - * @return The child's descriptor. - */ - public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, boolean includeDeleted) - { - fLookupCount.set(1); - try - { - AVMNode node = fAVMNodeDAO.getByID(dir.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not found: " + dir.getId()); - } - if (node.getType() != AVMNodeType.LAYERED_DIRECTORY && node.getType() != AVMNodeType.PLAIN_DIRECTORY) - { - throw new AVMWrongTypeException("Not a directory."); - } - DirectoryNode dirNode = (DirectoryNode) node; - if (!can(null, dirNode, PermissionService.READ_CHILDREN, false)) - { - throw new AccessDeniedException("Not allowed to read children: " + dir); - } - return dirNode.lookupChild(dir, name, includeDeleted); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get all the paths to a particular node. - * - * @param desc - * The node descriptor. - * @return The list of version, paths. - */ - public List> getPaths(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not found: " + desc); - } - List> paths = new ArrayList>(); - List components = new ArrayList(); - recursiveGetPaths(node, components, paths); - return paths; - } - - /** - * Get a single valid path for a node. - * - * @param desc - * The node descriptor. - * @return A version, path - */ - public Pair getAPath(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Could not find node: " + desc); - } - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Getting A Path for: " + desc); - } - List components = new ArrayList(); - return recursiveGetAPath(node, components); - } - - /** - * Get all paths for a node reachable by HEAD. - * - * @param desc - * The node descriptor. - * @return A List of all the version, path Pairs that match. - */ - public List> getHeadPaths(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not found: " + desc.getPath()); - } - List> paths = new ArrayList>(); - List components = new ArrayList(); - recursiveGetHeadPaths(node, components, paths); - return paths; - } - - /** - * Gets all the pass from to the given node starting from the give version root. - * - * @param version - * The version root. - * @param node - * The node to get the paths of. - * @return A list of all paths in the given version to the node. - */ - public List getVersionPaths(VersionRoot version, AVMNode node) - { - List paths = new ArrayList(); - List components = new ArrayList(); - recursiveGetVersionPaths(node, components, paths, version.getRoot(), version.getAvmStore().getName()); - return paths; - } - - /** - * Helper to get all version paths. - * - * @param node - * The current node we are examining. - * @param components - * The current path components. - * @param paths - * The list to contain found paths. - * @param root - * The root node of the version. - * @param storeName - * The name of the store. - */ - private void recursiveGetVersionPaths(AVMNode node, List components, List paths, DirectoryNode root, String storeName) - { - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - return; - } - if (node.equals(root)) - { - paths.add(this.makePath(components, storeName)); - return; - } - List entries = fChildEntryDAO.getByChild(node); - for (ChildEntry entry : entries) - { - String name = entry.getKey().getName(); - components.add(name); - AVMNode parent = entry.getKey().getParent(); - recursiveGetVersionPaths(parent, components, paths, root, storeName); - components.remove(components.size() - 1); - } - } - - /** - * Get all paths in a particular store in the head version for a particular node. - * - * @param desc - * The node descriptor. - * @param store - * The name of the store. - * @return All matching paths. - */ - public List> getPathsInStoreHead(AVMNodeDescriptor desc, String store) - { - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not found: " + desc); - } - List> paths = new ArrayList>(); - List components = new ArrayList(); - recursiveGetPathsInStoreHead(node, components, paths, st.getRoot(), store); - return paths; - } - - /** - * Do the actual work. - * - * @param node - * The current node. - * @param components - * The currently accumulated path components. - * @param paths - * The list to put full paths in. - */ - private void recursiveGetPaths(AVMNode node, List components, List> paths) - { - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - return; - } - if (node.getIsRoot()) - { - AVMStore store = fAVMStoreDAO.getByRoot(node); - if (store != null) - { - addPath(components, -1, store.getName(), paths); - } - VersionRoot vr = fVersionRootDAO.getByRoot(node); - if (vr != null) - { - addPath(components, vr.getVersionID(), vr.getAvmStore().getName(), paths); - } - return; - } - List entries = fChildEntryDAO.getByChild(node); - for (ChildEntry entry : entries) - { - String name = entry.getKey().getName(); - components.add(name); - AVMNode parent = entry.getKey().getParent(); - recursiveGetPaths(parent, components, paths); - components.remove(components.size() - 1); - } - } - - /** - * Do the work of getting one path for a node. - * - * @param node - * The node to get the path of. - * @param components - * The storage for path components. - * @return A path or null. - */ - private Pair recursiveGetAPath(AVMNode node, List components) - { - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - return null; - } - if (node.getIsRoot()) - { - AVMStore store = fAVMStoreDAO.getByRoot(node); - if (store != null) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Found path in HEAD of: " + store.getName()); - } - return new Pair(-1, makePath(components, store.getName())); - } - VersionRoot vr = fVersionRootDAO.getByRoot(node); - if (vr != null) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Found path in version " + vr.getVersionID() + " in: " + vr.getAvmStore().getName()); - } - return new Pair(vr.getVersionID(), makePath(components, vr.getAvmStore().getName())); - } - return null; - } - List entries = fChildEntryDAO.getByChild(node); - for (ChildEntry entry : entries) - { - String name = entry.getKey().getName(); - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Found component: " + name); - } - components.add(name); - Pair path = recursiveGetAPath(entry.getKey().getParent(), components); - if (path != null) - { - return path; - } - components.remove(components.size() - 1); - } - return null; - } - - /** - * Do the actual work. - * - * @param node - * The current node. - * @param components - * The currently accumulated path components. - * @param paths - * The list to put full paths in. - */ - private void recursiveGetHeadPaths(AVMNode node, List components, List> paths) - { - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - return; - } - if (node.getIsRoot()) - { - AVMStore store = fAVMStoreDAO.getByRoot(node); - if (store != null) - { - addPath(components, -1, store.getName(), paths); - return; - } - return; - } - List entries = fChildEntryDAO.getByChild(node); - for (ChildEntry entry : entries) - { - String name = entry.getKey().getName(); - components.add(name); - AVMNode parent = entry.getKey().getParent(); - recursiveGetHeadPaths(parent, components, paths); - components.remove(components.size() - 1); - } - } - - /** - * Do the actual work. - * - * @param node - * The current node. - * @param components - * The currently accumulated path components. - * @param paths - * The list to put full paths in. - */ - private void recursiveGetPathsInStoreHead(AVMNode node, List components, List> paths, DirectoryNode root, String storeName) - { - if (!can(null, node, PermissionService.READ_CHILDREN, false)) - { - return; - } - if (node.equals(root)) - { - addPath(components, -1, storeName, paths); - return; - } - List entries = fChildEntryDAO.getByChild(node); - for (ChildEntry entry : entries) - { - String name = entry.getKey().getName(); - components.add(name); - AVMNode parent = entry.getKey().getParent(); - recursiveGetHeadPaths(parent, components, paths); - components.remove(components.size() - 1); - } - } - - /** - * Add a path to the list. - * - * @param components - * The path name components. - * @param version - * The version id. - * @param storeName - * The name of the - * @param paths - * The List to add to. - */ - private void addPath(List components, int version, String storeName, List> paths) - { - paths.add(new Pair(version, makePath(components, storeName))); - } - - /** - * Alternate version. - * - * @param components - * @param storeName - * @param paths - */ - private void addPath(List components, String storeName, List paths) - { - paths.add(makePath(components, storeName)); - } - - /** - * Helper for generating paths. - * - * @param components - * The path components. - * @param storeName - * The store that the path is in. - * @return The path. - */ - private String makePath(List components, String storeName) - { - StringBuilder pathBuilder = new StringBuilder(); - pathBuilder.append(storeName); - pathBuilder.append(":"); - if (components.size() == 0) - { - pathBuilder.append("/"); - return pathBuilder.toString(); - } - for (int i = components.size() - 1; i >= 0; i--) - { - pathBuilder.append("/"); - pathBuilder.append(components.get(i)); - } - return pathBuilder.toString(); - } - - /** - * Get information about layering of a path. - * - * @param version - * The version to look under. - * @param path - * The full avm path. - * @return A LayeringDescriptor. - */ - public LayeringDescriptor getLayeringInfo(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - Lookup lookup = store.lookup(version, pathParts[1], false, true); - if (lookup == null) - { - throw new AVMNotFoundException("Path not found."); - } - if (!can(store, lookup.getCurrentNode(), PermissionService.READ_PROPERTIES, false)) - { - throw new AccessDeniedException("Not allowed to read properties: " + path); - } - return new LayeringDescriptor(!lookup.getDirectlyContained(), lookup.getAVMStore().getDescriptor(), lookup.getFinalStore().getDescriptor()); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Lookup a directory specifically. - * - * @param version - * The version to look under. - * @param path - * The path to lookup. - * @return A lookup object. - */ - public Lookup lookupDirectory(int version, String path) - { - Integer count = fLookupCount.get(); - try - { - if (count == null) - { - fLookupCount.set(1); - } - fLookupCount.set(fLookupCount.get() + 1); - if (fLookupCount.get() > 50) - { - throw new AVMCycleException(MSG_CYCLE_ON_LOOKUP); - } - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - return null; - } - return store.lookupDirectory(version, pathParts[1], false); - } - finally - { - if (count == null) - { - fLookupCount.set(null); - } - } - } - - /** - * Utility to split a path, foo:bar/baz into its repository and path parts. - * - * @param path - * The fully qualified path. - * @return The repository name and the repository path. - */ - private String[] SplitPath(String path) - { - return AVMUtil.splitPath(path); - } - - /** - * Make a directory into a primary indirection. - * - * @param path - * The full path. - */ - public void makePrimary(String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.makePrimary(pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Change what a layered directory points at. - * - * @param path - * The full path to the layered directory. - * @param target - * The new target path. - */ - public void retargetLayeredDirectory(String path, String target) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.retargetLayeredDirectory(pathParts[1], target); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the history chain for a node. - * - * @param desc - * The node to get history of. - * @param count - * The maximum number of ancestors to traverse. Negative means all. - * @return A List of ancestors. - */ - public List getHistory(AVMNodeDescriptor desc, int count) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not found."); - } - if (!can(null, node, PermissionService.READ_PROPERTIES, false)) - { - throw new AccessDeniedException("Not allowed to read properties: " + desc); - } - if (count < 0) - { - count = Integer.MAX_VALUE; - } - List history = new ArrayList(); - for (int i = 0; i < count; i++) - { - AVMNode ancNode = node.getAncestor(); - if (ancNode == null) - { - break; - } - if (!can(null, ancNode, PermissionService.READ_PROPERTIES, false)) - { - break; - } - if ((node.getType() == AVMNodeType.LAYERED_FILE) && (ancNode.getType() == AVMNodeType.PLAIN_FILE)) - { - break; - } - history.add(ancNode.getDescriptor("UNKNOWN", "UNKNOWN", "UNKNOWN", -1)); - node = ancNode; - } - return history; - } - - /** - * Set the opacity of a layered directory. An opaque directory hides the things it points to via indirection. - * - * @param path - * The path to the layered directory. - * @param opacity - * True is opaque; false is not. - */ - public void setOpacity(String path, boolean opacity) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setOpacity(pathParts[1], opacity); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set a property on a node. - * - * @param path - * The path to the node. - * @param name - * The name of the property. - * @param value - * The value of the property. - */ - public void setNodeProperty(String path, QName name, PropertyValue value) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setNodeProperty(pathParts[1], name, value); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set a collection of properties at once. - * - * @param path - * The path to the node. - * @param properties - * The Map of QNames to PropertyValues. - */ - public void setNodeProperties(String path, Map properties) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setNodeProperties(pathParts[1], properties); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get a property by name for a node. - * - * @param version - * The version to look under. - * @param path - * The path to the node. - * @param name - * The name of the property. - * @return The PropertyValue or null if it does not exist. - */ - public PropertyValue getNodeProperty(int version, String path, QName name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getNodeProperty(version, pathParts[1], name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get a Map of all the properties of a node. - * - * @param version - * The version to look under. - * @param path - * The path to the node. - * @return A Map of QNames to PropertyValues. - */ - public Map getNodeProperties(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getNodeProperties(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Delete a single property from a node. - * - * @param path - * The path to the node. - * @param name - * The name of the property. - */ - public void deleteNodeProperty(String path, QName name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.deleteNodeProperty(pathParts[1], name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Delete all properties on a node. - * - * @param path - * The path to the node. - */ - public void deleteNodeProperties(String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.deleteNodeProperties(pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set a property on a store. Overwrites if property exists. - * - * @param store - * The AVMStore. - * @param name - * The QName. - * @param value - * The PropertyValue to set. - */ - public void setStoreProperty(String store, QName name, PropertyValue value) - { - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - st.setProperty(name, value); - } - - /** - * Set a group of properties on a store. Overwrites any properties that exist. - * - * @param store - * The AVMStore. - * @param props - * The properties to set. - */ - public void setStoreProperties(String store, Map props) - { - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - st.setProperties(props); - } - - /** - * Get a property from a store. - * - * @param store - * The name of the store. - * @param name - * The property - * @return The property value or null if non-existent. - */ - public PropertyValue getStoreProperty(String store, QName name) - { - if (store == null) - { - throw new AVMBadArgumentException("Null store name."); - } - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - return st.getProperty(name); - } - - /** - * Queries a given store for properties with keys that match a given pattern. - * - * @param store - * The name of the store. - * @param keyPattern - * The sql 'like' pattern, inserted into a QName. - * @return A Map of the matching key value pairs. - */ - public Map queryStorePropertyKey(String store, QName keyPattern) - { - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - - return fAVMStorePropertyDAO.queryByKeyPattern(st, keyPattern); - } - - /** - * Queries all AVM stores for properties with keys that match a given pattern. - * - * @param keyPattern - * The sql 'like' pattern, inserted into a QName. - * @return A List of Pairs of Store name, Map.Entry. - */ - public Map> queryStoresPropertyKeys(QName keyPattern) - { - return fAVMStorePropertyDAO.queryByKeyPattern(keyPattern); - } - - /** - * Get all the properties for a store. - * - * @param store - * The name of the Store. - * @return A Map of all the properties. - */ - public Map getStoreProperties(String store) - { - if (store == null) - { - throw new AVMBadArgumentException("Null store name."); - } - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - return st.getProperties(); - } - - /** - * Delete a property from a store. - * - * @param store - * The name of the store. - * @param name - * The name of the property. - */ - public void deleteStoreProperty(String store, QName name) - { - AVMStore st = getAVMStoreByName(store); - if (st == null) - { - throw new AVMNotFoundException("Store not found: "+store); - } - st.deleteProperty(name); - } - - /** - * Get the common ancestor of two nodes if one exists. Unfortunately this is a quadratic problem, taking time - * proportional to the product of the lengths of the left and right history chains. - * - * @param left - * The first node. - * @param right - * The second node. - * @return The common ancestor. There are four possible results. Null means that there is no common ancestor. Left - * returned means that left is strictly an ancestor of right. Right returned means that right is strictly an - * ancestor of left. Any other non null return is the common ancestor and indicates that left and right are - * in conflict. - */ - public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, AVMNodeDescriptor right) - { - AVMNode lNode = fAVMNodeDAO.getByID(left.getId()); - AVMNode rNode = fAVMNodeDAO.getByID(right.getId()); - if (lNode == null || rNode == null) - { - throw new AVMNotFoundException("Node not found."); - } - if (!can(null, lNode, PermissionService.READ_PROPERTIES, false)) - { - throw new AccessDeniedException("Not allowed to read properties: " + left); - } - if (!can(null, rNode, PermissionService.READ_PROPERTIES, false)) - { - throw new AccessDeniedException("Not allowed to read properties: " + right); - } - // TODO Short changing the permissions checking here. I'm not sure - // if that's OK. - List leftHistory = new ArrayList(); - List rightHistory = new ArrayList(); - while (lNode != null || rNode != null) - { - boolean checkRight = false; - if (lNode != null) - { - leftHistory.add(lNode); - checkRight = true; - lNode = lNode.getAncestor(); - } - boolean checkLeft = false; - if (rNode != null) - { - rightHistory.add(rNode); - checkLeft = true; - rNode = rNode.getAncestor(); - } - if (checkRight) - { - AVMNode check = leftHistory.get(leftHistory.size() - 1); - for (AVMNode node : rightHistory) - { - if (node.equals(check)) - { - return node.getDescriptor("", "", "", -1); - } - } - } - if (checkLeft) - { - AVMNode check = rightHistory.get(rightHistory.size() - 1); - for (AVMNode node : leftHistory) - { - if (node.equals(check)) - { - return node.getDescriptor("", "", "", -1); - } - } - } - } - return null; - } - - /** - * Get the ContentData for a file. - * - * @param version - * The version to look under. - * @param path - * The path to the file. - * @return The ContentData for the file. - */ - public ContentData getContentDataForRead(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - return store.getContentDataForRead(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the ContentData for a file for writing. - * - * @param path - * The path to the file. - * @return The ContentData object. - */ - public ContentData getContentDataForWrite(String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - ContentData result = store.getContentDataForWrite(pathParts[1]); - return result; - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set the ContentData on a file. - * - * @param path - * The path to the file. - * @param data - * The content data to set. - */ - public void setContentData(String path, ContentData data) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setContentData(pathParts[1], data); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the single instance of AVMRepository. - * - * @return The single instance. - */ - public static AVMRepository GetInstance() - { - return fgInstance; - } - - public void setMetaDataFrom(String path, AVMNodeDescriptor from) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - AVMNode fromNode = fAVMNodeDAO.getByID(from.getId()); - if (fromNode == null) - { - throw new AVMNotFoundException("Node not found: " + from.getPath()); - } - fLookupCache.onWrite(pathParts[0]); - store.setMetaDataFrom(pathParts[1], fromNode); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Add an aspect to an AVM Node. - * - * @param path - * The path to the node. - * @param aspectName - * The name of the aspect. - */ - public void addAspect(String path, QName aspectName) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.addAspect(pathParts[1], aspectName); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get all the aspects on an AVM node. - * - * @param version - * The version to look under. - * @param path - * The path to the node. - * @return A List of the QNames of the Aspects. - */ - public Set getAspects(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getAspects(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Remove an aspect and all associated properties from a node. - * - * @param path - * The path to the node. - * @param aspectName - * The name of the aspect. - */ - public void removeAspect(String path, QName aspectName) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.removeAspect(pathParts[1], aspectName); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Does a node have a particular aspect. - * - * @param version - * The version to look under. - * @param path - * The path to the node. - * @param aspectName - * The name of the aspect. - * @return Whether the node has the aspect. - */ - public boolean hasAspect(int version, String path, QName aspectName) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.hasAspect(version, pathParts[1], aspectName); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set the ACL on a node. - * - * @param path - * The path to the node. - * @param acl - * The ACL to set. - */ - public void setACL(String path, Acl acl) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setACL(pathParts[1], acl); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Get the ACL on a node. - * - * @param version - * The version to look under. - * @param path - * The path to the node. - * @return The ACL. - */ - public Acl getACL(int version, String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - return store.getACL(version, pathParts[1]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Link a node into a directory, directly. - * - * @param parentPath - * The path to the parent. - * @param name - * The name to give the node. - * @param toLink - * The node to link. - */ - public void link(String parentPath, String name, AVMNodeDescriptor toLink) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(parentPath); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - store.link(pathParts[1], name, toLink); - fLookupCache.onWrite(pathParts[0]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Update a link, directly. - * - * @param parentPath - * The path to the parent. - * @param name - * The name to give the node. - * @param toLink - * The node to link. - */ - public void updateLink(String parentPath, String name, AVMNodeDescriptor toLink) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(parentPath); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - store.updateLink(pathParts[1], name, toLink); - fLookupCache.onWrite(pathParts[0]); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * This is the danger version of link. It must be called on a copied and unsnapshotted directory. It blithely - * inserts a child without checking if a child exists with a conflicting name. - * - * @param parent - * The parent directory. - * @param name - * The name to give the child. - * @param child - * The child to link in. - */ - public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child) - { - AVMNode node = fAVMNodeDAO.getByID(parent.getId()); - if (!(node instanceof DirectoryNode)) - { - throw new AVMWrongTypeException("Not a Directory."); - } - DirectoryNode dir = (DirectoryNode) node; - if (!dir.getIsNew()) - { - throw new AVMException("Directory has not already been copied."); - } - if (!can(null, dir, PermissionService.ADD_CHILDREN, false)) - { - throw new AccessDeniedException("Not allowed to write: " + parent); - } - dir.link(name, child); - } - - /** - * Remove name without leaving behind a deleted node. Dangerous if used unwisely. - * - * @param path - * The path to the layered directory. - * @param name - * The name of the child. - */ - public void flatten(String path, String name) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onDelete(pathParts[0]); - Lookup lPath = store.lookup(-1, pathParts[1], true, false); - AVMNode node = lPath.getCurrentNode(); - if (node == null) - { - throw new AVMNotFoundException("Path not found."); - } - if (!(node instanceof LayeredDirectoryNode)) - { - throw new AVMWrongTypeException("Not a Layered Directory."); - } - if (!can(store, node, PermissionService.FLATTEN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write in: " + path); - } - LayeredDirectoryNode dir = (LayeredDirectoryNode) node; - dir.flatten(name); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Force a copy on write. - * - * @param path - * The path to force. - */ - public AVMNodeDescriptor forceCopy(String path) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - // Just force a copy if needed by looking up in write mode. - Lookup lPath = store.lookup(-1, pathParts[1], true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path not found."); - } - AVMNode node = lPath.getCurrentNode(); - AVMNodeDescriptor desc = node.getDescriptor(lPath); - return desc; - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Rename a store. - * - * @param sourceName - * The original name. - * @param destName - * The new name. - * @throws AVMNotFoundException - * @throws AVMExistsException - */ - public void renameStore(String sourceName, String destName) - { - AlfrescoTransactionSupport.bindListener(fPurgeStoreTxnListener); - AlfrescoTransactionSupport.bindListener(fCreateStoreTxnListener); - AVMStore store = getAVMStoreByName(sourceName); - if (store == null) - { - throw new AVMNotFoundException("Store Not Found: "+sourceName); - } - if (getAVMStoreByName(destName) != null) - { - throw new AVMExistsException("Store Already Exists: " + destName); - } - if (!FileNameValidator.isValid(destName)) - { - throw new AVMBadArgumentException("Bad store name: " + destName); - } - store.setName(destName); - - AVMDAOs.Instance().fAVMStoreDAO.update(store); - - store.createSnapshot("Rename Store", "Rename Store from " + sourceName + " to " + destName, new HashMap()); - fLookupCache.onDelete(sourceName); - fAVMStoreDAO.invalidateCache(); - fPurgeStoreTxnListener.storePurged(sourceName); - fCreateStoreTxnListener.storeCreated(destName); - } - - /** - * Revert a head path to a given version. This works by cloning the version to revert to, and then linking that new - * version into head. The reverted version will have the previous head version as ancestor. - * - * @param path - * The path to the parent directory. - * @param name - * The name of the node. - * @param toRevertTo - * The descriptor of the version to revert to. - */ - public void revert(String path, String name, AVMNodeDescriptor toRevertTo) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.revert(pathParts[1], name, toRevertTo); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set the GUID on a node. - * - * @param path - * @param guid - */ - public void setGuid(String path, String guid) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store not found:"+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setGuid(pathParts[1], guid); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set the encoding on a node. - * - * @param path - * @param encoding - */ - public void setEncoding(String path, String encoding) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store Not Found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setEncoding(pathParts[1], encoding); - } - finally - { - fLookupCount.set(null); - } - } - - /** - * Set the mime type on a node. - * - * @param path - * @param encoding - */ - public void setMimeType(String path, String mimeType) - { - fLookupCount.set(1); - try - { - String[] pathParts = SplitPath(path); - AVMStore store = getAVMStoreByName(pathParts[0]); - if (store == null) - { - throw new AVMNotFoundException("Store Not Found: "+pathParts[0]); - } - fLookupCache.onWrite(pathParts[0]); - store.setMimeType(pathParts[1], mimeType); - } - finally - { - fLookupCount.set(null); - } - } - - public List getPathsInStoreVersion(AVMNodeDescriptor desc, String store, int version) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not found: " + desc); - } - List paths = new ArrayList(); - List components = new ArrayList(); - recursiveGetStoreVersionPaths(store, node, version, components, paths); - return paths; - } - - /** - * Do the actual work. - * - * @param node - * The current node. - * @param components - * The currently accumulated path components. - * @param paths - * The list to put full paths in. - */ - private void recursiveGetStoreVersionPaths(String storeName, AVMNode node, int version, List components, List paths) - { - if (!can(null, node, PermissionService.READ, false)) - { - return; - } - if (node.getIsRoot()) - { - VersionRoot versionRoot = fVersionRootDAO.getByRoot(node); - if (versionRoot.getAvmStore().getName().equals(storeName) && versionRoot.getVersionID() == version) - { - addPath(components, storeName, paths); - return; - } - return; - } - List entries = fChildEntryDAO.getByChild(node); - for (ChildEntry entry : entries) - { - String name = entry.getKey().getName(); - components.add(name); - AVMNode parent = entry.getKey().getParent(); - recursiveGetStoreVersionPaths(storeName, parent, version, components, paths); - components.remove(components.size() - 1); - } - } - - public Map getNodeProperties(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Node not found: " + desc); - } - if (!can(null, node, PermissionService.READ_PROPERTIES, false)) - { - throw new AccessDeniedException("Not allowed to read properties: " + desc); - } - return node.getProperties(); - } - - public ContentData getContentDataForRead(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Node not found: " + desc); - } - if (!can(null, node, PermissionService.READ_CONTENT, false)) - { - throw new AccessDeniedException("Not allowed to read: " + desc); - } - if (node.getType() == AVMNodeType.PLAIN_FILE) - { - PlainFileNode file = (PlainFileNode) node; - return file.getContentData(); - } - else if (node.getType() == AVMNodeType.LAYERED_FILE) - { - LayeredFileNode file = (LayeredFileNode) node; - return file.getContentData(null); - } - throw new AVMWrongTypeException("Not a file: " + desc); - } - - public Set getAspects(AVMNodeDescriptor desc) - { - AVMNode node = fAVMNodeDAO.getByID(desc.getId()); - if (node == null) - { - throw new AVMNotFoundException("Node not found: " + desc); - } - if (!can(null, node, PermissionService.READ_PROPERTIES, false)) - { - throw new AccessDeniedException("Not allowed to read properties: " + desc); - } - Set aspectQNames = node.getAspects(); - return aspectQNames; - } - - /** - * Evaluate permission on a node. I've got a bad feeling about this... - * - * @param store - * @param node - * @param permission - * @return - */ - public boolean can(AVMStore store, AVMNode node, String permission, boolean isDirectlyContained) - { - Acl acl = node.getAcl(); - - QName type; - if (node.getType() == AVMNodeType.PLAIN_DIRECTORY) - { - type = WCMModel.TYPE_AVM_PLAIN_FOLDER; - } - else if (node.getType() == AVMNodeType.PLAIN_FILE) - { - type = WCMModel.TYPE_AVM_PLAIN_CONTENT; - } - else if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - type = WCMModel.TYPE_AVM_LAYERED_FOLDER; - } - else - { - type = WCMModel.TYPE_AVM_LAYERED_CONTENT; - } - PermissionContext context = new PermissionContext(type); - - context.addDynamicAuthorityAssignment(node.getBasicAttributes().getOwner(), PermissionService.OWNER_AUTHORITY); - - if ((store != null) && isDirectlyContained) - { - String storeOwner = getStoreUserName(store.getName()); - if (storeOwner != null) - { - // Special case: WCM author sandbox (author, author preview, author workflow, author workflow preview) - context.addDynamicAuthorityAssignment(storeOwner, PermissionService.WCM_STORE_OWNER_AUTHORITY); - } - - /* - StoreType storeType = StoreType.getStoreType(store.getName(), store.getDescriptor(), store.getProperties()); - switch (storeType) - { - case AUTHOR: - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case AUTHOR_WORKFLOW_PREVIEW: - String storeName = store.getName(); - int first = -1; - int second = -1; - first = storeName.indexOf("--"); - if (first >= 0) - { - second = storeName.indexOf("--", first + 2); - String storeOwner; - if (second >= 0) - { - storeOwner = storeName.substring(first + 2, second); - } - else - { - storeOwner = storeName.substring(first + 2); - } - context.addDynamicAuthorityAssignment(storeOwner, PermissionService.WCM_STORE_OWNER_AUTHORITY); - } - break; - case STAGING: - case STAGING_PREVIEW: - case UNKNOWN: - case WORKFLOW: - case WORKFLOW_PREVIEW: - default: - } - */ - } - - // Pass in node aspects - Set nodeAspectQNames = node.getAspects(); - Set contextQNames = context.getAspects(); - contextQNames.addAll(nodeAspectQNames); - - /* TODO review - PermissionContext.getProperties() not currently used ? - // Pass in node properties - Map nodeProperties = node.getProperties(); - Map contextProperties = new HashMap(5); - QNameDAO qnameDAO = AVMDAOs.Instance().fQNameDAO; - for (Map.Entry entry : nodeProperties.entrySet()) - { - QName qname = qnameDAO.getQName(entry.getKey()).getSecond(); - PropertyDefinition def = fDictionaryService.getProperty(qname); - if (def == null) - { - contextProperties.put(qname, entry.getValue().getValue(DataTypeDefinition.ANY)); - } - else - { - contextProperties.put(qname, entry.getValue().getValue(def.getDataType().getName())); - } - } - context.getProperties().putAll(contextProperties); - */ - - Long aclId = null; - if (acl != null) - { - aclId = acl.getId(); - } - if (store != null) - { - Acl storeAcl = store.getStoreAcl(); - if (storeAcl != null) - { - Long storeAclID = storeAcl.getId(); - context.setStoreAcl(storeAclID); - } - } - return fPermissionService.hasPermission(aclId, context, permission) == AccessStatus.ALLOWED; - } - - private final static String WCM_STORE_SEPARATOR = "--"; - private final static String WCM_STORE_PREVIEW = "--preview"; - private final static String WCM_STORE_WORKFLOW = "--workflow-"; - - // TODO - merge with WCM 3.x utils - // - // Note: relies on WCM sandbox naming convention - // - // Staging: mystore - // Staging preview: mystore--preview - // Author: mystore--myuserid - // Author preview: mystore--myuserid--preview - // Author workflow: mystore--myuserid--workflow-guid - // Author workflow preview: mystore--myuserid--workflow-guid--preview - // Workflow: mystore--workflow-guid - // Workflow preview: mystore--worklow-guid--preview - // - private static String getStoreUserName(String storeName) - { - String storeOwner = null; - int preview = storeName.indexOf(WCM_STORE_PREVIEW); - if (preview >= 0) - { - // strip off "--preview" - storeName = storeName.substring(0, preview); - } - int workflow = storeName.indexOf(WCM_STORE_WORKFLOW); - if (workflow >= 0) - { - // strip off "--workflow-" - storeName = storeName.substring(0, workflow); - } - int author = storeName.indexOf(WCM_STORE_SEPARATOR); - if (author >= 0) - { - storeOwner = storeName.substring(author + 2); - } - return storeOwner; - } - - public boolean can(String storeName, int version, String path, String permission) - { - Lookup lookup = AVMRepository.GetInstance().lookup(version, path, true); - if (lookup != null) - { - AVMNode node = lookup.getCurrentNode(); - AVMStore store = getAVMStoreByName(storeName); - return can(store, node, permission, lookup.getDirectlyContained()); - } - else - { - // Does not exist => allowed - return true; - } - } - - /** - * Set the acl on a store. - * - * @param storeName - * @param acl - */ - public void setStoreAcl(String storeName, Acl acl) - { - AVMStore store = getAVMStoreByName(storeName); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+storeName); - } - store.setStoreAcl(acl); - - AVMDAOs.Instance().fAVMStoreDAO.update(store); - } - - /** - * Get the ACL on a store. - * - * @param storeName - * @return - */ - public Acl getStoreAcl(String storeName) - { - AVMStore store = getAVMStoreByName(storeName); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+storeName); - } - return store.getStoreAcl(); - } - - /** - * @param name - * @param version - * @return - */ - public List getAVMStoreVersionsTo(String name, int version) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getVersionsTo(version); - } - - /** - * @param name - * @param version - * @return - */ - public List getAVMStoreVersionsFrom(String name, int version) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getVersionsFrom(version); - } - - /** - * @param name - * @param startVersion - * @param endVersion - * @return - */ - public List getAVMStoreVersionsBetween(String name, int startVersion, int endVersion) - { - AVMStore store = getAVMStoreByName(name); - if (store == null) - { - throw new AVMNotFoundException("Store not found: "+name); - } - return store.getVersionsBetween(startVersion, endVersion); - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java deleted file mode 100644 index b796fcece5..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java +++ /dev/null @@ -1,1706 +0,0 @@ -/* - * Copyright (C) 2005-2011 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMCycleException; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.AVMWrongTypeException; -import org.alfresco.service.cmr.avm.LayeringDescriptor; -import org.alfresco.service.cmr.avm.VersionDescriptor; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.FileNameValidator; -import org.alfresco.util.Pair; -import org.alfresco.util.TempFileProvider; -import org.alfresco.wcm.util.WCMUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Implements the AVMService. - * @author britt - */ -public class AVMServiceImpl implements AVMService -{ - /** The i18n'ized messages */ - private static final String MSG_CYCLE_ON_CREATE = "avm.cycle.create"; - - public static final String SYSTEM = "system"; - - private static Log logger = LogFactory.getLog(AVMServiceImpl.class); - - /** - * The AVMRepository for each service thread. - */ - private AVMRepository fAVMRepository; - - /** - * Basic constructor for the service. - */ - public AVMServiceImpl() - { - } - - /** - * Set the repository reference. For Spring. - * @param avmRepository The repository reference. - */ - public void setAvmRepository(AVMRepository avmRepository) - { - fAVMRepository = avmRepository; - } - - /** - * Get an InputStream from a file. - * @param version The version to look under. - * @param path The absolute path. - * @return An InputStream - * @throws AVMNotFoundException When the path is invalid. - */ - public InputStream getFileInputStream(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getInputStream(version, path); - } - - /** - * Get an InputStream from a descriptor. - * @param desc The descriptor. - * @return An InputStream. - * @throws AVMNotFoundException - */ - public InputStream getFileInputStream(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - return fAVMRepository.getInputStream(desc); - } - - /** - * Get an output stream to a file. Triggers versioning. - */ - public OutputStream getFileOutputStream(String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getOutputStream(path); - } - - /** - * Get a content reader from a file node. - * @param version The version of the file. - * @param path The path to the file. - * @return A ContentReader. - */ - public ContentReader getContentReader(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getContentReader(version, path); - } - - /** - * Get a ContentWriter to a file node. - * @param path The path to the file. - * @param update true if the property must be updated atomically when the content write - * stream is closed (attaches a listener to the stream); false if the client code - * will perform the updates itself. - * @return A ContentWriter. - */ - public ContentWriter getContentWriter(String path, boolean update) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.createContentWriter(path, update); - } - - /** - * Get a directory listing. - * @param version The version id to lookup. - * @param path The path to lookup. - */ - public SortedMap getDirectoryListing(int version, String path) - { - return getDirectoryListing(version, path, false); - } - - /** - * Get a listing of a Folder by name, with the option of seeing - * Deleted Nodes. - * @param version The version id to look in. - * @param path The simple absolute path to the file node. - * @param includeDeleted Whether to see Deleted Nodes. - * @return A Map of names to descriptors. - * @throws AVMNotFoundException If path is not found. - * @throws AVMWrongTypeException If path contains a non-terminal - * component that is not a directory, or if path is not pointing - * at a directory. - */ - public SortedMap getDirectoryListing(int version, String path, - boolean includeDeleted) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getListing(version, path, includeDeleted); - } - - /** - * Get a directory listing as an Array of AVMNodeDescriptors. - * @param version The version to look under. - * @param path The path to the directory to be listed. - * @param includeDeleted Whether to include ghosts. - * @return An array of AVMNodeDescriptors. - */ - public AVMNodeDescriptor [] getDirectoryListingArray(int version, String path, - boolean includeDeleted) - { - Map listing = - getDirectoryListing(version, path, includeDeleted); - AVMNodeDescriptor [] result = new AVMNodeDescriptor[listing.size()]; - int off = 0; - for (AVMNodeDescriptor desc : listing.values()) - { - result[off++] = desc; - } - return result; - } - - /** - * Get a directory listing as an Array of node descriptors. - * @param dir The descriptor pointing at the directory to list. - * @param includeDeleted Whether to show ghosts. - * @return An array of AVMNodeDescriptors. - */ - public AVMNodeDescriptor [] getDirectoryListingArray(AVMNodeDescriptor dir, - boolean includeDeleted) - { - Map listing = - getDirectoryListing(dir, includeDeleted); - AVMNodeDescriptor [] result = new AVMNodeDescriptor[listing.size()]; - int off = 0; - for (AVMNodeDescriptor desc : listing.values()) - { - result[off++] = desc; - } - return result; - } - - /** - * Get a listing of all the directly contained children of a directory. - * @param dir The directory descriptor. - * @param includeDeleted Whether to include deleted children. - * @return A Map of Strings to descriptors. - */ - public SortedMap - getDirectoryListingDirect(AVMNodeDescriptor dir, boolean includeDeleted) - { - if (dir == null) - { - throw new AVMBadArgumentException("Illegal null descriptor."); - } - return fAVMRepository.getListingDirect(dir, includeDeleted); - } - - /** - * Get the listing of nodes contained directly in a directory. This is the - * same as getDirectoryListing for PlainDirectories, but returns only those that - * are directly contained in a layered directory. - * @param version The version to look up. - * @param path The full path to get listing for. - * @return A Map of names to descriptors. - * @throws AVMNotFoundException If path does not exist. - * @throws AVMWrongTypeException If path contains any non-directory - * elements. - */ - public SortedMap - getDirectoryListingDirect(int version, String path) - { - return getDirectoryListingDirect(version, path, false); - } - - /** - * Get the listing of nodes contained directly in a directory. This is the - * same as getDirectoryListing for PlainDirectories, but returns only those that - * are directly contained in a layered directory. This has the option of - * seeing Deleted Nodes. - * @param version The version to look up. - * @param path The full path to get listing for. - * @param includeDeleted Whether to see Deleted Nodes. - * @return A Map of names to descriptors. - * @throws AVMNotFoundException If path does not exist. - * @throws AVMWrongTypeException If path contains any non-directory - * elements. - */ - public SortedMap - getDirectoryListingDirect(int version, String path, boolean includeDeleted) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getListingDirect(version, path, includeDeleted); - } - - /** - * Get a directory listing from a node descriptor. - * @param dir The directory node descriptor. - * @return A Map of names to node descriptors. - */ - public SortedMap getDirectoryListing(AVMNodeDescriptor dir) - { - return getDirectoryListing(dir, false); - } - - - public SortedMap getDirectoryListing(AVMNodeDescriptor dir, String childPattern) - { - return getDirectoryListing(dir, childPattern, false); - } - - public SortedMap getDirectoryListing(AVMNodeDescriptor dir, String childNamePattern, boolean includeDeleted) - { - if (dir == null) - { - throw new AVMBadArgumentException("Null descriptor."); - } - return fAVMRepository.getListing(dir, childNamePattern, includeDeleted); - } - - /** - * Get a directory listing from a node descriptor, with the option of - * seeing deleted nodes. - * @param dir The directory node descriptor. - * @param includeDeleted Whether to see Deleted Nodes. - * @return A Map of names to node descriptors. - * @throws AVMNotFoundException If the descriptor is stale. - * @throws AVMWrongTypeException If the descriptor does not point at a directory. - */ - public SortedMap getDirectoryListing(AVMNodeDescriptor dir, - boolean includeDeleted) - { - if (dir == null) - { - throw new AVMBadArgumentException("Null descriptor."); - } - return fAVMRepository.getListing(dir, includeDeleted); - } - - /** - * Get the names of nodes that have been deleted in a directory. - * @param version The version to look under. - * @param path The path of the directory. - * @return A List of names. - * @throws AVMNotFoundException If path does not exist. - * @throws AVMWrongTypeException If path contains any elements - * that are not directories. - */ - public List getDeleted(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getDeleted(version, path); - } - - /** - * Create a new file. The file must not exist. - * @param path The path to the containing directory. - * @param name The name of the file. - * @return An output stream to the file. - */ - public OutputStream createFile(String path, String name) - { - if (path == null || name == null || !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal argument."); - } - return fAVMRepository.createFile(path, name); - } - - /** - * Create a file with content specified by the InputStream. - * Guaranteed to be created atomically. - * @param path The path to the containing directory. - * @param name The name to give the file. - * @param in An InputStream containing data for file. - */ - public void createFile(String path, String name, InputStream in) - { - createFile(path, name, in, null, null); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String, java.io.InputStream, java.util.List, java.util.Map) - */ - public void createFile(String path, String name, InputStream in, List aspects, Map properties) - { - if (path == null || name == null || in == null) - { - throw new AVMBadArgumentException("Illegal argument."); - } - - if(!FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal argument, name:" + name); - } - - // Save the contents to temp space. - File temp; - try - { - temp = TempFileProvider.createTempFile("alf", "tmp"); - OutputStream out = new FileOutputStream(temp); - byte [] buff = new byte[8192]; - int read; - while ((read = in.read(buff)) != -1) - { - out.write(buff, 0, read); - } - out.close(); - in.close(); - } - catch (IOException ie) - { - throw new AVMException("I/O Error."); - } - try - { - fAVMRepository.createFile(path, name, temp, aspects, properties); - } - finally - { - temp.delete(); - } - } - - /** - * Create a directory. The directory must not exist. - * @param path The path to the containing directory. - * @param name The name of the new directory. - */ - public void createDirectory(String path, String name) - { - createDirectory(path, name, null, null); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createDirectory(java.lang.String, java.lang.String, java.util.List, java.util.Map) - */ - public void createDirectory(String path, String name, List aspects, Map properties) - { - if (path == null || name == null || !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal argument."); - } - fAVMRepository.createDirectory(path, name, aspects, properties); - } - - /** - * Create a new layered file. It must not exist. - * @param srcPath The src path. Ie the target for the layering. - * @param parent The path to the parent directory. - * @param name The name to give the new file. - */ - public void createLayeredFile(String srcPath, String parent, String name) - { - if (srcPath == null || parent == null || name == null || - !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal argument."); - } - fAVMRepository.createLayeredFile(srcPath, parent, name); - } - - /** - * Create a new layered directory. It must not exist. - * @param srcPath The src path. Ie the target for layering. - * @param parent The path to the parent directory. - * @param name The name for the new directory. - */ - public void createLayeredDirectory(String srcPath, String parent, String name) - { - if (srcPath == null || parent == null || name == null || - !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal argument."); - } - fAVMRepository.createLayeredDirectory(srcPath, parent, name); - - // check for cycle (note: optimised to skip when creating WCM sandbox layer) - String[] pathParts = AVMUtil.splitPath(parent); - if ((WCMUtil.getWebProject(this, pathParts[0]) == null) || - (! (pathParts[1].equals("/") && name.equals(JNDIConstants.DIR_DEFAULT_WWW)))) - { - long start = System.currentTimeMillis(); - - if (checkForLDCycle(srcPath, AVMUtil.extendAVMPath(parent, name))) - { - throw new AVMCycleException(MSG_CYCLE_ON_CREATE); - } - - if (logger.isDebugEnabled()) - { - logger.debug("createLayeredDirectory: cycle check: "+parent+"/"+name+" -> "+srcPath+" (in "+(System.currentTimeMillis()-start)+" msecs)"); - } - } - } - - private boolean checkForLDCycle(String srcPath, String dstDirPath) - { - boolean found = false; - SortedMap listing = getDirectoryListing(-1, dstDirPath, false); - for (AVMNodeDescriptor node : listing.values()) - { - if (node.isDirectory()) - { - if (node.isLayeredDirectory() && node.isPrimary() && node.getIndirection().equals(srcPath)) - { - return true; - } - if (checkForLDCycle(srcPath, node.getPath())) - { - found = true; - break; - } - } - } - return found; - } - - /** - * Create an AVMStore with the given name (it must not exist). - * @param name The name to give the AVMStore. - */ - public void createStore(String name) - { - if (name == null || !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Bad Name."); - } - fAVMRepository.createAVMStore(name); - } - - /** - * Create an AVMStore with the given name (it must not exist) and set store properties. - * @param name The name to give the AVMStore. - * @param props A Map of the properties to set. - */ - public void createStore(String name, Map props) - { - if (name == null || !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Bad Name."); - } - fAVMRepository.createAVMStore(name, props); - } - - /** - * Create a branch. - * @param version The version to branch from. - * @param srcPath The path to the thing to branch from. - * @param dstPath The path to the destination containing directory. - * @param name The name of the new branch. - */ - public void createBranch(int version, String srcPath, String dstPath, - String name) - { - if (srcPath == null || dstPath == null || name == null || - !FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal argument."); - } - fAVMRepository.createBranch(version, srcPath, dstPath, name); - } - - /** - * Remove a node. Beware, the node can be a directory and - * this acts recursively. - * @param parent The path to the parent. - * @param name The name of the node to remove. - */ - public void removeNode(String parent, String name) - { - if (parent == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.remove(parent, name); - } - - /** - * Remove a node by full path. - * @param path The full path to the node. - */ - public void removeNode(String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - String [] basePath = AVMNodeConverter.SplitBase(path); - if (basePath[0] == null) - { - throw new AVMBadArgumentException("Cannot remove root node: " + path); - } - fAVMRepository.remove(basePath[0], basePath[1]); - } - - /** - * Rename a node. - * @param srcParent The path to the source parent. - * @param srcName The name of the source node. - * @param dstParent The path to the destination parent. - * @param dstName The name to give the renamed node. - */ - public void rename(String srcParent, String srcName, String dstParent, - String dstName) - { - if (srcParent == null || srcName == null || dstParent == null || dstName == null || - !FileNameValidator.isValid(dstName)) - { - throw new AVMBadArgumentException("Illegal argument."); - } - fAVMRepository.rename(srcParent, srcName, dstParent, dstName); - } - - /** - * Uncover a deleted name in a layered directory. - * @param dirPath The path to the layered directory. - * @param name The name to uncover. - */ - public void uncover(String dirPath, String name) - { - if (dirPath == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.uncover(dirPath, name); - } - - /** - * Make name in dirPath transparent to what was underneath it. That is, this - * removes the offending node from its layered directory parent's direct ownership. - * @param dirPath The path to the layered directory. - * @param name The name of the item to flatten. - */ - public void makeTransparent(String dirPath, String name) - { - if (dirPath == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.flatten(dirPath, name); - } - - /** - * Get the Latest Version ID for an AVMStore. - * @param repName The name of the AVMStore. - * @return The Latest Version ID. - */ - public int getNextVersionID(String repName) - { - if (repName == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getLatestVersionID(repName); - } - - /** - * Get the latest snapshot id of a store. - * @param storeName The store name. - * @return The id of the latest extant version of the store. - * @throws AVMNotFoundException If storeName does not exist. - */ - public int getLatestSnapshotID(String storeName) - { - if (storeName == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getLatestSnapshotID(storeName); - } - - /* - * Snapshot an AVMRepository. - * @param store The name of the AVMStore. - * @param tag The short description. - * @param description The thick description. - * @return Map of implicitly and explicitly snapshotted stores. - */ - public Map createSnapshot(String store, String tag, String description) - { - if (store == null) - { - throw new AVMBadArgumentException("Store is null."); - } - return fAVMRepository.createSnapshot(store, tag, description); - } - - /** - * Look up information about a node. - * @param version The version to look up. - * @param path The path to look up. - * @return A Descriptor. - */ - public AVMNodeDescriptor lookup(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Illegal null path."); - } - return lookup(version, path, false); - } - - /** - * Lookup a node by version ids and path, with the option of - * seeing Deleted Nodes. - * @param version The version id to look under. - * @param path The simple absolute path to the parent directory. - * @param includeDeleted Whether to see Deleted Nodes. - * @return An AVMNodeDescriptor. - * @throws AVMNotFoundException If path does not exist or - * if version does not exist. - * @throws AVMWrongTypeException If path contains a non-terminal - * element that is not a directory. - */ - public AVMNodeDescriptor lookup(int version, String path, boolean includeDeleted) - { - if (path == null) - { - throw new AVMBadArgumentException("Path is null."); - } - try - { - Lookup lookup = fAVMRepository.lookup(version, path, includeDeleted); - if (lookup == null) - { - return null; - } - return lookup.getCurrentNode().getDescriptor(lookup); - } - catch (AVMNotFoundException e) - { - return null; - } - } - - /** - * Lookup a node descriptor from a directory node descriptor. - * @param dir The node descriptor of the directory. - * @param name The name to lookup. - * @return The node descriptor of the child. - */ - public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name) - { - if (dir == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return lookup(dir, name, false); - } - - /** - * Lookup a node from a directory node, with the option of seeing - * Deleted Nodes. - * @param dir The descriptor for the directory node. - * @param name The name to lookup. - * @param includeDeleted Whether to see Deleted Nodes. - * @return The descriptor for the child. - * @throws AVMNotFoundException If name does not exist or - * if dir is dangling. - * @throws AVMWrongTypeException If dir does not refer to a directory. - */ - public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, boolean includeDeleted) - { - if (dir == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - try - { - return fAVMRepository.lookup(dir, name, includeDeleted); - } - catch (AVMNotFoundException e) - { - return null; - } - } - - /** - * Get a list of all paths that a given node has. - * @param desc The node descriptor to get paths for. - * @return A List of version, path Pairs. - */ - public List> getPaths(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Descriptor is null."); - } - return fAVMRepository.getPaths(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getAPath(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public Pair getAPath(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Descriptor is null."); - } - return fAVMRepository.getAPath(desc); - } - - /** - * Get all paths that a given node has that are in the head version. - * @param desc The node descriptor to get paths for. - * @return A List of version, path Pairs. - */ - public List> getHeadPaths(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Descriptor is null."); - } - return fAVMRepository.getHeadPaths(desc); - } - - /** - * Get all paths to a node starting at the HEAD version of a store. - * @param desc The node descriptor. - * @param store The store. - * @return A List of all paths meeting the criteria. - */ - public List> getPathsInStoreHead(AVMNodeDescriptor desc, String store) - { - if (desc == null || store == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getPathsInStoreHead(desc, store); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getPathsInStoreVersion(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String, int) - */ - public List getPathsInStoreVersion(AVMNodeDescriptor desc, String store, int version) - { - if (desc == null || store == null || version < 1) - { - throw new AVMBadArgumentException("Illegal null argument or invalid version."); - } - return fAVMRepository.getPathsInStoreVersion(desc, store, version); - } - - /** - * Purge an AVMStore. Permanently delete everything that - * is only referenced in that AVMStore. - * @param name The name of the AVMStore to purge. - */ - public void purgeStore(String name) - { - if (name == null) - { - throw new AVMBadArgumentException("Name is null."); - } - fAVMRepository.purgeAVMStore(name); - } - - /** - * Purge a particular version from a repository. - * @param version The id of the version to purge. - * @param name The name of the repository. - */ - public void purgeVersion(int version, String name) - { - if (name == null) - { - throw new AVMBadArgumentException("Name is null."); - } - fAVMRepository.purgeVersion(name, version); - } - - /** - * Get the indirection path of a layered node. - * @param version The version to lookup. - * @param path The path to lookup. - * @return The indirection path (target) of the layered node. - */ - public String getIndirectionPath(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Path is null."); - } - return fAVMRepository.getIndirectionPath(version, path); - } - - /** - * Get the extant version ids for an AVMStore. - * @param name The name of the AVMStore. - * @return A List of VersionDescriptors. - */ - public List getStoreVersions(String name) - { - if (name == null) - { - throw new AVMBadArgumentException("Name is null."); - } - return fAVMRepository.getAVMStoreVersions(name); - } - - /** - * Get version IDs by creation date. From or to may be null but not - * both. - * @param name The name of the AVMStore to search. - * @param from The earliest versions to return. - * @param to The latest versions to return. - * @return The Set of matching version IDs. - */ - public List getStoreVersions(String name, Date from, Date to) - { - if (name == null || (from == null && to == null)) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getAVMStoreVersions(name, from, to); - } - - /** - * Change what a layered directory points to. - * @param path The path to the layered directory. - */ - public void retargetLayeredDirectory(String path, String target) - { - if (path == null || target == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.retargetLayeredDirectory(path, target); - } - - /** - * Make the indicated directory a primary indirection. - * @param path The absolute path. - */ - public void makePrimary(String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Path is null."); - } - fAVMRepository.makePrimary(path); - } - - /** - * Get a list of all AVMStores. - * @return The AVMStores. - */ - public List getStores() - { - return fAVMRepository.getAVMStores(); - } - - /** - * Get a reposotory. - * @param name The name of the AVMStore to get. - * @return The AVMStore. - */ - public AVMStoreDescriptor getStore(String name) - { - if (name == null) - { - throw new AVMBadArgumentException("Null Store Name."); - } - try - { - return fAVMRepository.getAVMStore(name); - } - catch (AVMNotFoundException e) - { - return null; - } - } - - /** - * Get (and create if necessary) the system store. This store houses things - * like workflow packages. - * @return The descriptor. - */ - public AVMStoreDescriptor getSystemStore() - { - AVMStoreDescriptor store = getStore(SYSTEM); - if (store == null) - { - createStore(SYSTEM); - return getStore(SYSTEM); - } - return store; - } - - /** - * Get a descriptor for the specified AVMStore root. - * @param version The version to get. - * @param name The name of the AVMStore. - * @return The root descriptor. - */ - public AVMNodeDescriptor getStoreRoot(int version, String name) - { - if (name == null) - { - throw new AVMBadArgumentException("Name is null."); - } - return fAVMRepository.getAVMStoreRoot(version, name); - } - - /** - * Get the history of a node. - * @param desc The node to get history from. - * @param count The number of ancestors to fallow back. -1 means all. - * @return A List of ancestors most recent first. - */ - public List getHistory(AVMNodeDescriptor desc, int count) - { - if (desc == null) - { - throw new AVMBadArgumentException("Null descriptor."); - } - return fAVMRepository.getHistory(desc, count); - } - - /** - * Set the opacity of a layered directory. An opaque layer hides what - * its indirection points to. - * @param path The path to the layered directory. - * @param opacity True is opaque false is not. - */ - public void setOpacity(String path, boolean opacity) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - fAVMRepository.setOpacity(path, opacity); - } - - /** - * Get layering information about a path. - * @param version The version to look under. - * @param path The full AVM path. - * @return A LayeringDescriptor. - */ - public LayeringDescriptor getLayeringInfo(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path: " + path); - } - return fAVMRepository.getLayeringInfo(version, path); - } - - /** - * Get the common ancestor of two nodes if one exists. - * @param left The first node. - * @param right The second node. - * @return The common ancestor. There are four possible results. Null means - * that there is no common ancestor. Left returned means that left is strictly - * an ancestor of right. Right returned means that right is strictly an - * ancestor of left. Any other non null return is the common ancestor and - * indicates that left and right are in conflict. - */ - public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, - AVMNodeDescriptor right) - { - if (left == null || right == null) - { - throw new AVMBadArgumentException("Null node descriptor."); - } - return fAVMRepository.getCommonAncestor(left, right); - } - - /** - * Set a property on a node. - * @param path The path to the node to set the property on. - * @param name The QName of the property. - * @param value The property to set. - */ - public void setNodeProperty(String path, QName name, PropertyValue value) - { - if (path == null || name == null || value == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.setNodeProperty(path, name, value); - } - - /** - * Set a collection of properties on a node. - * @param path The path to the node. - * @param properties The Map of properties to set. - */ - public void setNodeProperties(String path, Map properties) - { - if (path == null || properties == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.setNodeProperties(path, properties); - } - - /** - * Get a property of a node by QName. - * @param version The version to look under. - * @param path The path to the node. - * @param name The QName. - * @return The PropertyValue or null if it doesn't exist. - */ - public PropertyValue getNodeProperty(int version, String path, QName name) - { - if (path == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getNodeProperty(version, path, name); - } - - /** - * Get all the properties associated with a node. - * @param version The version to look under. - * @param path The path to the node. - * @return A List of AVMNodeProperties. - */ - public Map getNodeProperties(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getNodeProperties(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public Map getNodeProperties(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Null descriptor."); - } - return fAVMRepository.getNodeProperties(desc); - } - - /** - * Delete a property. - * @param path The path to the node. - * @param name The QName of the property to delete. - */ - public void deleteNodeProperty(String path, QName name) - { - if (path == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.deleteNodeProperty(path, name); - } - - /** - * Delete all the properties attached to an AVM node. - * @param path The path to the node. - */ - public void deleteNodeProperties(String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - fAVMRepository.deleteNodeProperties(path); - } - - /** - * Set a property on a store. If the property exists it will be overwritten. - * @param store The store to set the property on. - * @param name The name of the property. - * @param value The value of the property. - */ - public void setStoreProperty(String store, QName name, PropertyValue value) - { - if (store == null || name == null || value == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.setStoreProperty(store, name, value); - } - - /** - * Set a group of properties on a store. Existing properties will be overwritten. - * @param store The name of the store. - * @param props A Map of the properties to set. - */ - public void setStoreProperties(String store, Map props) - { - if (store == null || props == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.setStoreProperties(store, props); - } - - /** - * Get a property from a store. - * @param store The name of the store. - * @param name The name of the property. - * @return A PropertyValue or null if non-existent. - */ - public PropertyValue getStoreProperty(String store, QName name) - { - if (store == null || name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getStoreProperty(store, name); - } - - /** - * Queries a given store for properties with keys that match a given pattern. - * @param store The name of the store. - * @param keyPattern The sql 'like' pattern, inserted into a QName. - * @return A Map of the matching key value pairs. - */ - public Map queryStorePropertyKey(String store, QName keyPattern) - { - if (store == null || keyPattern == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.queryStorePropertyKey(store, keyPattern); - } - - /** - * Queries all AVM stores for properties with keys that matcha given pattern. - * @param keyPattern The sql 'like' pattern, inserted into a QName. - * @return A List of Pairs of Store name, Map.Entry. - */ - public Map> - queryStoresPropertyKeys(QName keyPattern) - { - if (keyPattern == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.queryStoresPropertyKeys(keyPattern); - } - - /** - * Get all the properties associated with a store. - * @param store The name of the store. - * @return A Map of the stores properties. - */ - public Map getStoreProperties(String store) - { - if (store == null) - { - throw new AVMBadArgumentException("Null store name."); - } - return fAVMRepository.getStoreProperties(store); - } - - /** - * Delete a property on a store by name. - * @param store The name of the store. - * @param name The name of the property to delete. - */ - public void deleteStoreProperty(String store, QName name) - { - if (store == null || name == null) - { - throw new AVMBadArgumentException("Invalid null argument."); - } - fAVMRepository.deleteStoreProperty(store, name); - } - - /** - * Get the ContentData for a node. Only applies to a file. - * @param version The version to look under. - * @param path The path to the node. - * @return The ContentData object. - */ - public ContentData getContentDataForRead(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null Path."); - } - return fAVMRepository.getContentDataForRead(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public ContentData getContentDataForRead(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Null descriptor."); - } - return fAVMRepository.getContentDataForRead(desc); - } - - /** - * Get the Content data for writing. - * @param path The path to the node. - * @return The ContentData object. - */ - public ContentData getContentDataForWrite(String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null Path."); - } - return fAVMRepository.getContentDataForWrite(path); - } - - /** - * Set the content data on a file. - * @param path The path to the file. - * @param data The ContentData to set. - * @throws AVMNotFoundException If path does not exist. - * @throws AVMWrongTypeException If path does not point - * to a file. - */ - public void setContentData(String path, ContentData data) - { - if (path == null || data == null) - { - throw new AVMBadArgumentException("Null Path."); - } - fAVMRepository.setContentData(path, data); - } - - /** - * Set all metadata on a node from another node. Aspects, properties, ACLs. - * @param path The path to the node to set. - * @param from The descriptor for the node to get metadata from. - */ - public void setMetaDataFrom(String path, AVMNodeDescriptor from) - { - if (path == null || from == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - fAVMRepository.setMetaDataFrom(path, from); - } - - /** - * Add an aspect to an AVM node. - * @param path The path to the node. - * @param aspectName The QName of the aspect. - * @throws AVMNotFoundException If path does not exist. - * @throws AVMExistsException If the aspect already exists. - */ - public void addAspect(String path, QName aspectName) - { - if (path == null || aspectName == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.addAspect(path, aspectName); - } - - /** - * Get all the aspects on an AVM node. - * @param version The version to look under. - * @param path The path to the node. - * @return A List of the QNames of the aspects. - */ - public Set getAspects(int version, String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null path."); - } - return fAVMRepository.getAspects(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getAspects(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public Set getAspects(AVMNodeDescriptor desc) - { - if (desc == null) - { - throw new AVMBadArgumentException("Null descriptor: " + desc); - } - return fAVMRepository.getAspects(desc); - } - - /** - * Remove an aspect and its properties from a node. - * @param path The path to the node. - * @param aspectName The name of the aspect. - */ - public void removeAspect(String path, QName aspectName) - { - if (path == null || aspectName == null) - { - throw new AVMBadArgumentException("Null path."); - } - fAVMRepository.removeAspect(path, aspectName); - } - - /** - * Does a node have a particular aspect. - * @param version The version to look under. - * @param path The path to the node. - * @param aspectName The aspect name to check. - * @return Whether the given node has the given aspect. - */ - public boolean hasAspect(int version, String path, QName aspectName) - { - if (path == null || aspectName == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - return fAVMRepository.hasAspect(version, path, aspectName); - } - - /** - * This inserts a node into a parent directly. - * @param parentPath The path to the parent directory. - * @param name The name to give the node. - * @param toLink A descriptor for the node to insert. - */ - public void link(String parentPath, String name, AVMNodeDescriptor toLink) - { - if (parentPath == null || name == null || toLink == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.link(parentPath, name, toLink); - } - - /** - * This replaces a node into a parent directly. - * @param parentPath The path to the parent directory. - * @param name The name to give the node. - * @param toLink A descriptor for the node to insert. - */ - public void updateLink(String parentPath, String name, AVMNodeDescriptor toLink) - { - if (parentPath == null || name == null || toLink == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.updateLink(parentPath, name, toLink); - } - - /** - * Force copy on write of a path. - * @param path The path to force. - */ - public AVMNodeDescriptor forceCopy(String path) - { - if (path == null) - { - throw new AVMBadArgumentException("Null Path."); - } - return fAVMRepository.forceCopy(path); - } - - /** - * Copy (possibly recursively) the source into the destination - * directory. - * @param srcVersion The version of the source. - * @param srcPath The path to the source. - * @param dstPath The destination directory. - * @param name The name to give the copy. - */ - public void copy(int srcVersion, String srcPath, String dstPath, String name) - { - if (srcPath == null || dstPath == null) - { - throw new AVMBadArgumentException("Null Path."); - } - if (srcVersion < 0) - { - String canonicalSrc = - AVMNodeConverter.ToAVMVersionPath( - AVMNodeConverter.ToNodeRef(srcVersion, srcPath)).getSecond(); - String canonicalDst = - AVMNodeConverter.ToAVMVersionPath( - AVMNodeConverter.ToNodeRef(-1, dstPath)).getSecond(); - if (!canonicalSrc.endsWith("/")) - { - canonicalSrc = canonicalSrc + "/"; - } - if (canonicalDst.indexOf(canonicalSrc) == 0) - { - throw new AVMBadArgumentException("Infinite Copy."); - } - } - if (!FileNameValidator.isValid(name)) - { - throw new AVMBadArgumentException("Illegal name."); - } - AVMNodeDescriptor srcDesc = lookup(srcVersion, srcPath); - recursiveCopy(srcVersion, srcDesc, dstPath, name); - } - - - private Acl getAclAsSystem(final int version, final String path) - { - return AuthenticationUtil.runAs(new RunAsWork(){ - - public Acl doWork() throws Exception - { - return fAVMRepository.getACL(version, path); - }}, AuthenticationUtil.getSystemUserName()); - } - - private void setAclAsSystem(final String path, final Acl acl) - { - AuthenticationUtil.runAs(new RunAsWork(){ - - public Object doWork() throws Exception - { - fAVMRepository.setACL(path, acl); - return null; - }}, AuthenticationUtil.getSystemUserName()); - } - - /** - * Do the actual work of copying. - * @param desc The src descriptor. - * @param path The destination parent path. - * @param name The name to give the copy. - */ - private void recursiveCopy(int version, AVMNodeDescriptor desc, String path, String name) - { - String newPath = path + '/' + name; - AVMNodeDescriptor existing = lookup(-1, newPath); - Acl parentAcl = getAclAsSystem(-1, path); - Long parentAclId = null; - if(parentAcl != null) - { - parentAclId = parentAcl.getId(); - } - Acl acl = getAclAsSystem(version, desc.getPath()); - - if (desc.isFile()) - { - InputStream in = getFileInputStream(version, desc.getPath()); - if (existing != null) - { - removeNode(newPath); - } - // Set the acl underneath - createFile(path, name, in); - if (acl != null) - { - setAclAsSystem(newPath, AVMDAOs.Instance().fAclDAO.getAclCopy(acl.getId(), parentAclId, ACLCopyMode.COPY)); - } - ContentData cd = getContentDataForRead(version, desc.getPath()); - setEncoding(newPath, cd.getEncoding()); - setMimeType(newPath, cd.getMimetype()); - } - else // desc is a directory. - { - if (existing != null && !existing.isDirectory()) - { - removeNode(newPath); - existing = null; - } - - Map listing = getDirectoryListing(desc); - - if (existing == null) - { - createDirectory(path, name); - // Set acl before creating children as acls inherit :-) - if (acl != null) - { - setAclAsSystem(newPath, AVMDAOs.Instance().fAclDAO.getAclCopy(acl.getId(), parentAclId, ACLCopyMode.COPY)); - } - } - - for (Map.Entry entry : listing.entrySet()) - { - recursiveCopy(version, entry.getValue(), newPath, entry.getKey()); - } - } - // In either case copy properties, aspects, and acls. - Map props = getNodeProperties(version, desc.getPath()); - setNodeProperties(newPath, props); - Set aspects = getAspects(version, desc.getPath()); - for (QName aspect : aspects) - { - addAspect(newPath, aspect); - } - } - - /** - * Rename a store. - * @param sourceName The original name. - * @param destName The new name. - * @throws AVMNotFoundException - * @throws AVMExistsException - */ - public void renameStore(String sourceName, String destName) - { - if (sourceName == null || destName == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.renameStore(sourceName, destName); - } - - /** - * Revert a head path to a given version. This works by cloning - * the version to revert to, and then linking that new version into head. - * The reverted version will have the previous head version as ancestor. - * @param path The path to the node to revert. - * @param toRevertTo The descriptor of the version to revert to. - * @throws AVMNotFoundException - */ - public void revert(String path, AVMNodeDescriptor toRevertTo) - { - if (path == null || toRevertTo == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - String [] baseName = AVMNodeConverter.SplitBase(path); - if (baseName.length != 2) - { - throw new AVMBadArgumentException("Cannot revert store root: " + path); - } - fAVMRepository.revert(baseName[0], baseName[1], toRevertTo); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setGuid(java.lang.String, java.lang.String) - */ - public void setGuid(String path, String guid) - { - if (path == null || guid == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.setGuid(path, guid); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setEncoding(java.lang.String, java.lang.String) - */ - public void setEncoding(String path, String encoding) - { - if (path == null || encoding == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.setEncoding(path, encoding); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setMimeType(java.lang.String, java.lang.String) - */ - public void setMimeType(String path, String mimeType) - { - if (path == null || mimeType == null) - { - throw new AVMBadArgumentException("Illegal Null Argument."); - } - fAVMRepository.setMimeType(path, mimeType); - } - - public List getStoreVersionsTo(String name, int version) - { - if (name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getAVMStoreVersionsTo(name, version); - } - - public List getStoreVersionsFrom(String name, int version) - { - if (name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getAVMStoreVersionsFrom(name, version); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStoreVersionsBetween(java.lang.String, int, int) - */ - public List getStoreVersionsBetween(String name, int startVersion, int endVersion) - { - if (name == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - return fAVMRepository.getAVMStoreVersionsBetween(name, startVersion, endVersion); - } - - - - -} diff --git a/source/java/org/alfresco/repo/avm/AVMServiceNOOPImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceNOOPImpl.java new file mode 100644 index 0000000000..60f99d948d --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMServiceNOOPImpl.java @@ -0,0 +1,735 @@ +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . */ + +package org.alfresco.repo.avm; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMStoreDescriptor; +import org.alfresco.service.cmr.avm.LayeringDescriptor; +import org.alfresco.service.cmr.avm.VersionDescriptor; +import org.alfresco.service.cmr.repository.ContentData; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; + +// Sparta: disable WCM/AVM - temporary (until WCM/AVM has been fully removed) +public class AVMServiceNOOPImpl implements AVMService +{ + /** + * Basic constructor for the service. + */ + public AVMServiceNOOPImpl() + { + } + + @Override + public InputStream getFileInputStream(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public InputStream getFileInputStream(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public OutputStream getFileOutputStream(String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListing( + int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListingDirect( + int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListing( + AVMNodeDescriptor dir) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListing( + AVMNodeDescriptor dir, String childNamePattern) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getDeleted(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public OutputStream createFile(String path, String name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void createDirectory(String path, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void createLayeredFile(String targetPath, String parent, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void createLayeredDirectory(String targetPath, String parent, + String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void retargetLayeredDirectory(String path, String target) + { + // TODO Auto-generated method stub + + } + + @Override + public void createStore(String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void createStore(String name, Map props) + { + // TODO Auto-generated method stub + + } + + @Override + public void createBranch(int version, String srcPath, String dstPath, + String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void removeNode(String parent, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void rename(String srcParent, String srcName, String dstParent, + String dstName) + { + // TODO Auto-generated method stub + + } + + @Override + public void uncover(String dirPath, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public int getNextVersionID(String storeName) + { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getLatestSnapshotID(String storeName) + { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Map createSnapshot(String store, String tag, + String description) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getStoreVersions(String name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getStoreVersions(String name, Date from, + Date to) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getStores() + { + return Collections.emptyList(); + } + + @Override + public AVMStoreDescriptor getStore(String name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public AVMNodeDescriptor getStoreRoot(int version, String name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public AVMNodeDescriptor lookup(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public AVMNodeDescriptor lookup(int version, String path, + boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, + boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Pair getAPath(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getIndirectionPath(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void purgeStore(String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void purgeVersion(int version, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public void makePrimary(String path) + { + // TODO Auto-generated method stub + + } + + @Override + public List getHistory(AVMNodeDescriptor desc, int count) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setOpacity(String path, boolean opacity) + { + // TODO Auto-generated method stub + + } + + @Override + public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, + AVMNodeDescriptor right) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public LayeringDescriptor getLayeringInfo(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setNodeProperty(String path, QName name, PropertyValue value) + { + // TODO Auto-generated method stub + + } + + @Override + public void setNodeProperties(String path, + Map properties) + { + // TODO Auto-generated method stub + + } + + @Override + public PropertyValue getNodeProperty(int version, String path, QName name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getNodeProperties(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void deleteNodeProperty(String path, QName name) + { + // TODO Auto-generated method stub + + } + + @Override + public void deleteNodeProperties(String path) + { + // TODO Auto-generated method stub + + } + + @Override + public void setStoreProperty(String store, QName name, PropertyValue value) + { + // TODO Auto-generated method stub + + } + + @Override + public void setStoreProperties(String store, Map props) + { + // TODO Auto-generated method stub + + } + + @Override + public PropertyValue getStoreProperty(String store, QName name) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getStoreProperties(String store) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map queryStorePropertyKey(String store, + QName keyPattern) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void deleteStoreProperty(String store, QName name) + { + // TODO Auto-generated method stub + + } + + @Override + public void addAspect(String path, QName aspectName) + { + // TODO Auto-generated method stub + + } + + @Override + public Set getAspects(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void removeAspect(String path, QName aspectName) + { + // TODO Auto-generated method stub + + } + + @Override + public boolean hasAspect(int version, String path, QName aspectName) + { + // TODO Auto-generated method stub + return false; + } + + @Override + public void renameStore(String sourceName, String destName) + { + // TODO Auto-generated method stub + + } + + @Override + public void revert(String path, AVMNodeDescriptor toRevertTo) + { + // TODO Auto-generated method stub + + } + + @Override + public void setGuid(String path, String guid) + { + // TODO Auto-generated method stub + + } + + @Override + public void setMimeType(String path, String mimeType) + { + // TODO Auto-generated method stub + + } + + @Override + public void setEncoding(String path, String encoding) + { + // TODO Auto-generated method stub + + } + + @Override + public Map> queryStoresPropertyKeys( + QName keyPattern) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void createDirectory(String path, String name, List aspects, + Map properties) + { + // TODO Auto-generated method stub + + } + + @Override + public void createFile(String path, String name, InputStream in) + { + // TODO Auto-generated method stub + + } + + @Override + public void createFile(String path, String name, InputStream in, + List aspects, Map properties) + { + // TODO Auto-generated method stub + + } + + @Override + public SortedMap getDirectoryListing( + AVMNodeDescriptor dir, boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + @Override + public AVMNodeDescriptor[] getDirectoryListingArray(AVMNodeDescriptor dir, + boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListingDirect( + int version, String path, boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public AVMNodeDescriptor[] getDirectoryListingArray(int version, + String path, boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListingDirect( + AVMNodeDescriptor dir, boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public SortedMap getDirectoryListing( + int version, String path, boolean includeDeleted) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void removeNode(String path) + { + // TODO Auto-generated method stub + + } + + @Override + public void makeTransparent(String dirPath, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public AVMStoreDescriptor getSystemStore() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setMetaDataFrom(String path, AVMNodeDescriptor from) + { + // TODO Auto-generated method stub + + } + + @Override + public void link(String parentPath, String name, AVMNodeDescriptor toLink) + { + // TODO Auto-generated method stub + + } + + @Override + public void updateLink(String parentPath, String name, + AVMNodeDescriptor toLink) + { + // TODO Auto-generated method stub + + } + + @Override + public AVMNodeDescriptor forceCopy(String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void copy(int srcVersion, String srcPath, String dstPath, String name) + { + // TODO Auto-generated method stub + + } + + @Override + public List> getPaths(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List> getHeadPaths(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List> getPathsInStoreHead( + AVMNodeDescriptor desc, String store) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getPathsInStoreVersion(AVMNodeDescriptor desc, + String store, int version) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getNodeProperties(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Set getAspects(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public ContentReader getContentReader(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public ContentWriter getContentWriter(String path, boolean update) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public ContentData getContentDataForRead(int version, String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public ContentData getContentDataForRead(AVMNodeDescriptor desc) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public ContentData getContentDataForWrite(String path) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setContentData(String path, ContentData data) + { + // TODO Auto-generated method stub + + } + + @Override + public List getStoreVersionsFrom(String name, int version) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getStoreVersionsTo(String name, int version) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getStoreVersionsBetween(String name, + int startVersion, int endVersion) + { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/source/java/org/alfresco/repo/avm/AVMStore.java b/source/java/org/alfresco/repo/avm/AVMStore.java deleted file mode 100644 index 2d9a518276..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMStore.java +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.VersionDescriptor; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.namespace.QName; - -/** - * The store interface. Methods for filesystem like, versioning, - * and layering operations. - * @author britt - */ -public interface AVMStore -{ - /** - * Get the primary key. - */ - public long getId(); - - /** - * This returns the next version in this store that will be snapshotted. - * @return The next version to be snapshotted. - */ - public int getNextVersionID(); - - /** - * This gets the last extant version id. - */ - public int getLastVersionID(); - - /** - * Set a new root for this store. - * @param root The root to set. - */ - public void setNewRoot(DirectoryNode root); - - /** - * Get the Acl associated with this store. - * @return - */ - public Acl getStoreAcl(); - - /** - * Set the acl on this store. - * @param acl - */ - public void setStoreAcl(Acl acl); - - /** - * Snapshots this store. This sets all nodes in the - * the store to the should be copied state, and creates - * a new version root. - * @param tag The short description. - * @param description The long description. - * @param snapShotMap Keeps track of snapshot ids for all stores that - * end up snapshotted, possibly recursively. - * @return The map of all implicitely and explicitely snapshotted stores. - */ - public Map createSnapshot(String tag, String Description, Map snapShotMap); - - /** - * Create a new directory. - * @param path The path to the parent directory. - * @param name The name to give the new directory. - */ - public void createDirectory(String path, String name, List aspects, Map properties); - - /** - * Create a new layered directory. - * @param srcPath The path that the new layered directory will point at. - * @param dstPath The path to the directory to create the new layered directory in. - * @param name The name of the new layered directory. - */ - public void createLayeredDirectory(String srcPath, String dstPath, - String name); - - /** - * Create a new file. The designated file cannot already exist. - * @param path The path to the directory to contain the new file. - * @param name The name to give the new file. - * @return An OutputStream. - */ - public OutputStream createFile(String path, String name); - - /** - * Create a file with the given contents. - * @param path The path to the containing directory. - * @param name The name to give the file. - * @param data The contents of the file. - */ - public void createFile(String path, String name, File data, List aspects, Map properties); - - /** - * Create a new layered file. - * @param srcPath The target path for the new file. - * @param dstPath The path to the directory to make the new file in. - * @param name The name of the new file. - */ - public void createLayeredFile(String srcPath, String dstPath, String name); - - /** - * Get an InputStream from a file. - * @param version The version to look under. - * @param path The path to the file. - * @return An InputStream - */ - public InputStream getInputStream(int version, String path); - - /** - * Get a ContentReader from a file. - * @param version The version to look under. - * @param path The path to the file. - * @return A ContentReader - */ - public ContentReader getContentReader(int version, String path); - - /** - * Get a listing of the designated directory. - * @param version The version to look under. - * @param path The path to the directory. - * @param includeDeleted Whether to see Deleted nodes. - * @return A listing. - */ - public SortedMap getListing(int version, String path, - boolean includeDeleted); - - /** - * Get the list of nodes directly contained in a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @param includeDeleted Whether to see Deleted nodes. - * @return A Map of names to descriptors. - */ - public SortedMap getListingDirect(int version, String path, - boolean includeDeleted); - - /** - * Get the names of the deleted nodes in a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @return A List of names. - */ - public List getDeleted(int version, String path); - - /** - * Get an output stream to a file. - * @param path The path to the file. - * @return An OutputStream - */ - public OutputStream getOutputStream(String path); - - /** - * Get a ContentWriter to a file. - * @param path The path to the file. - * @param update true if the property must be updated atomically when the content write - * stream is closed (attaches a listener to the stream); false if the client code - * will perform the updates itself. - * @return A ContentWriter. - */ - public ContentWriter createContentWriter(String path, boolean update); - - /** - * Remove a node and all of its contents. - * @param path The path to the node's parent directory. - * @param name The name of the node to remove. - */ - public void removeNode(String path, String name); - - /** - * Uncover a whited out node. - * @param dirPath The path to the directory. - * @param name The name to uncover. - */ - public void uncover(String dirPath, String name); - - // TODO This is problematic. As time goes on this returns - // larger and larger data sets. Perhaps what we should do is - // provide methods for getting versions by date range, n most - // recent etc. - /** - * Get all the version for this AVMStore. - * @return A Set of all versions. - */ - public List getVersions(); - - /** - * Get all the versions starting from the last until the version specified - * @param version - the version which which to end - * @return - the versions in descending order - */ - public List getVersionsFrom(int version); - - /** - * Get all the versions after and including the one specified - * @param version - the version to start from - * @return - the versions in ascending order - */ - public List getVersionsTo(int version); - - /** - * Get all versions from an including startVersion up to but NOT including endVersion - * @param startVersion - * @param endVersion - * @return - the versions in ascending order - */ - public List getVersionsBetween(int startVersion, int endVersion); - - /** - * Get the versions from between the given dates. From or to - * may be null but not both. - * @param from The earliest date. - * @param to The latest date. - * @return The Set of matching version IDs. - */ - public List getVersions(Date from, Date to); - - /** - * Get the AVMRepository. - * @return The AVMRepository. - */ - public AVMRepository getAVMRepository(); - - /** - * Lookup a node. - * @param version The version to look under. - * @param path The path to the node. - * @param write Whether this is in a write context. - * @param includeDeleted Whether to see Deleted nodes. - * @return A Lookup object. - */ - public Lookup lookup(int version, String path, boolean write, boolean includeDeleted); - - /** - * Lookup a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @param write Whether this is in a write context. - * @return A Lookup object. - */ - public Lookup lookupDirectory(int version, String path, boolean write); - - /** - * For a layered node, get its indirection. - * @param version The version to look under. - * @param path The path to the node. - * @return The indirection. - */ - public String getIndirectionPath(int version, String path); - - /** - * Make the indicated directory a primary indirection. - * @param path The AVMRepository relative path. - */ - public void makePrimary(String path); - - /** - * Change the target of a layered directory. - * @param path The path to the layered directory. - * @param target The new target path. - */ - public void retargetLayeredDirectory(String path, String target); - - /** - * Get the root directory of this AVMStore. - * @return The root directory. - */ - public DirectoryNode getRoot(); - - /** - * Get the specified root as a descriptor. - * @param version The version to get (-1 for head). - * @return The specified root or null. - */ - public AVMNodeDescriptor getRoot(int version); - - /** - * Get the name of this store. - * @return The name. - */ - public String getName(); - - /** - * Set the name of the store. - * @param name To Set. - */ - public void setName(String name); - - /** - * Purge all the nodes reachable only by the given version. - * @param version - */ - public void purgeVersion(int version); - - /** - * Get the descriptor for this. - * @return The descriptor. - */ - public AVMStoreDescriptor getDescriptor(); - - /** - * Set the opacity of a layered directory. An opaque directory hides - * what is pointed at by its indirection. - * @param path The path to the layered directory. - * @param opacity True is opaque; false is not. - */ - public void setOpacity(String path, boolean opacity); - - /** - * Set a property on a node. - * @param path The path to the node. - * @param name The name of the property. - * @param value The value to set. - */ - public void setNodeProperty(String path, QName name, PropertyValue value); - - /** - * Set a collection of properties on a node. - * @param path The path to the node. - * @param properties The Map of QNames to PropertyValues. - */ - public void setNodeProperties(String path, Map properties); - - /** - * Get a property by name. - * @param version The version to look under. - * @param path The path to the node. - * @param name The name of the property. - * @return A PropertyValue or null if not found. - */ - public PropertyValue getNodeProperty(int version, String path, QName name); - - /** - * Delete a single property from a node. - * @param path The path to the node. - * @param name The name of the property. - */ - public void deleteNodeProperty(String path, QName name); - - /** - * Delete all properties from a node. - * @param path The path to the node. - */ - public void deleteNodeProperties(String path); - - /** - * Get all the properties associated with a node. - * @param version The version to look under. - * @param path The path to the node. - * @return A Map of QNames to PropertyValues. - */ - public Map getNodeProperties(int version, String path); - - /** - * Set a property on this store. Replaces if property already exists. - * @param name The QName of the property. - * @param value The actual PropertyValue. - */ - public void setProperty(QName name, PropertyValue value); - - /** - * Set a group of properties on this store. Replaces any property that exists. - * @param properties A Map of QNames to PropertyValues to set. - */ - public void setProperties(Map properties); - - /** - * Get a property by name. - * @param name The QName of the property to fetch. - * @return The PropertyValue or null if non-existent. - */ - public PropertyValue getProperty(QName name); - - /** - * Get all the properties associated with this node. - * @return A Map of the properties. - */ - public Map getProperties(); - - /** - * Delete a property. - * @param name The name of the property to delete. - */ - public void deleteProperty(QName name); - - /** - * Get the ContentData on a file. - * @param version The version to look under. - * @param path The path to the file. - * @return The ContentData corresponding to the file. - */ - public ContentData getContentDataForRead(int version, String path); - - /** - * Get the ContentData for writing. - * @param path The path to the file. - * @return The ContentData object. - */ - public ContentData getContentDataForWrite(String path); - - /** - * Set the ContentData for a file. - * @param path The path to the file. - * @param data The ContentData to set. - */ - public void setContentData(String path, ContentData data); - - /** - * Set meta data, aspects, properties, acls, from another node. - * @param path The path to the node to set metadata on. - * @param from The node to get the metadata from. - */ - public void setMetaDataFrom(String path, AVMNode from); - - /** - * Add an aspect to a node. - * @param path The path to the node. - * @param aspectName The name of the aspect. - */ - public void addAspect(String path, QName aspectName); - - /** - * Get all aspects on a given node. - * @param version The version to look under. - * @param path The path to the node. - * @return A List of the QNames of the aspects. - */ - public Set getAspects(int version, String path); - - /** - * Remove an aspect and all its properties from a node. - * @param path The path to the node. - * @param aspectName The name of the aspect. - */ - public void removeAspect(String path, QName aspectName); - - /** - * Does a given node have a given aspect. - * @param version The version to look under. - * @param path The path to the node. - * @param aspectName The name of the aspect. - * @return Whether the node has the aspect. - */ - public boolean hasAspect(int version, String path, QName aspectName); - - /** - * Set the ACL on a node. - * @param path The path to the node. - * @param acl The ACL to set. - */ - public void setACL(String path, Acl acl); - - /** - * Get the ACL on a node. - * @param version The version to look under. - * @param path The path to the node. - * @return The ACL. - */ - public Acl getACL(int version, String path); - - /** - * Link a node into a directory, directly. - * @param parentPath The path to the directory. - * @param name The name to give the node. - * @param toLink The node to link. - */ - public void link(String parentPath, String name, AVMNodeDescriptor toLink); - - /** - * Update a link to a node in a directory, directly. - * @param parentPath The path to the directory. - * @param name The name to give the node. - * @param toLink The node to link. - */ - public void updateLink(String parentPath, String name, AVMNodeDescriptor toLink); - - /** - * Revert a head path to a given version. This works by cloning - * the version to revert to, and then linking that new version into head. - * The reverted version will have the previous head version as ancestor. - * @param path The path to the parent directory. - * @param name The name of the node to revert. - * @param toRevertTo The descriptor of the version to revert to. - */ - public void revert(String path, String name, AVMNodeDescriptor toRevertTo); - - /** - * Set the GUID on a node. - * @param path - * @param guid - */ - public void setGuid(String path, String guid); - - /** - * Set the encoding of a file. - * @param path - * @param encoding - */ - public void setEncoding(String path, String encoding); - - /** - * Set the mime type of a file. - * @param path - * @param mimeType - */ - public void setMimeType(String path, String mimeType); -} diff --git a/source/java/org/alfresco/repo/avm/AVMStoreDAO.java b/source/java/org/alfresco/repo/avm/AVMStoreDAO.java deleted file mode 100644 index 664e08470d..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMStoreDAO.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.List; - -/** - * DAO for Repositories. - * @author britt - */ -public interface AVMStoreDAO -{ - /** - * Save an AVMStore, never before saved. - * @param store The AVMStore - */ - public void save(AVMStore store); - - /** - * Delete the given AVMStore. - * @param store The AVMStore. - */ - public void delete(AVMStore store); - - /** - * Get all AVMStores. - * @return A List of all the AVMStores. - */ - public List getAll(); - - /** - * Get an AVMStore by name. - * @param name The name of the AVMStore. - * @return The AVMStore or null if not found. - */ - public AVMStore getByName(String name); - - /** - * Get the AVM Store that has the given root as HEAD. - * @param root The root to query. - * @return The matching store or null. - */ - public AVMStore getByRoot(AVMNode root); - - /** - * Update the given AVMStore record. - * @param rep The dirty AVMStore. - */ - public void update(AVMStore rep); - - /** - * Get A store by primary key. - * @param id The primary key. - * @return The store. - */ - public AVMStore getByID(long id); - - /** - * Invalidate the by name lookup cache. - */ - public void invalidateCache(); -} diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java deleted file mode 100644 index 8f3d25d55b..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ /dev/null @@ -1,2016 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMModel; -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.avm.util.RawServices; -import org.alfresco.repo.avm.util.SimplePath; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.AVMWrongTypeException; -import org.alfresco.service.cmr.avm.VersionDescriptor; -import org.alfresco.service.cmr.dictionary.AspectDefinition; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A Repository contains a current root directory and a list of - * root versions. Each root version corresponds to a separate snapshot - * operation. - * @author britt - */ -public class AVMStoreImpl implements AVMStore -{ - private static Log logger = LogFactory.getLog(AVMStoreImpl.class); - /** - * The primary key. - */ - private long fID; - - /** - * The name of this AVMStore. - */ - private String fName; - - /** - * The current root directory. - */ - private DirectoryNode fRoot; - - /** - * The next version id. - */ - private int fNextVersionID; - - /** - * The version (for concurrency control). - */ - private long fVers; - - /** - * Acl for this store. - */ - private Acl fACL; - - /** - * The AVMRepository. - */ - transient private AVMRepository fAVMRepository; - - /** - * Default constructor. - */ - public AVMStoreImpl() - { - fAVMRepository = AVMRepository.GetInstance(); - } - - /** - * Make a brand new AVMStore. - * @param repo The AVMRepository. - * @param name The name of the AVMStore. - */ - public AVMStoreImpl(AVMRepository repo, String name) - { - // Make ourselves up and save. - fAVMRepository = repo; - - setName(name); - setNextVersionID(0); - setRoot(null); - - AVMDAOs.Instance().fAVMStoreDAO.save(this); - - String creator = RawServices.Instance().getAuthenticationContext().getCurrentUserName(); - if (creator == null) - { - creator = RawServices.Instance().getAuthenticationContext().getSystemUserName(); - } - setProperty(ContentModel.PROP_CREATOR, new PropertyValue(null, creator)); - setProperty(ContentModel.PROP_CREATED, new PropertyValue(null, new Date(System.currentTimeMillis()))); - - // Make up the initial version record and save. - long time = System.currentTimeMillis(); - - PlainDirectoryNode dir = new PlainDirectoryNodeImpl(this); - dir.setIsRoot(true); - AVMDAOs.Instance().fAVMNodeDAO.save(dir); - - setRoot(dir); - - VersionRoot versionRoot = new VersionRootImpl(this, - getRoot(), - getNextVersionID(), - time, - creator, - AVMUtil.INITIAL_SNAPSHOT, - AVMUtil.INITIAL_SNAPSHOT); - setNextVersionID(getNextVersionID()+1); - - AVMDAOs.Instance().fAVMStoreDAO.update(this); - AVMDAOs.Instance().fVersionRootDAO.save(versionRoot); - } - - /** - * Set the primary key - * @param id The primary key. - */ - public void setId(long id) - { - fID = id; - } - - /** - * Get the primary key. - * @return The primary key. - */ - public long getId() - { - return fID; - } - - /** - * Set a new root for this. - * @param root - */ - public void setNewRoot(DirectoryNode root) - { - fRoot = root; - } - - /** - * Snapshot this store. This creates a new version record. - * @return The version id of the new snapshot. - */ - public Map createSnapshot(String tag, String description, Map snapShotMap) - { - long start = System.currentTimeMillis(); - - long rootID = getRoot().getId(); - AVMStoreImpl me = (AVMStoreImpl)AVMDAOs.Instance().fAVMStoreDAO.getByID(getId()); - VersionRoot lastVersion = AVMDAOs.Instance().fVersionRootDAO.getMaxVersion(me); - List layeredEntries = - AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.get(lastVersion); - // Is there no need for a snapshot? - DirectoryNode root = (DirectoryNode)AVMDAOs.Instance().fAVMNodeDAO.getByID(rootID); - if (!root.getIsNew() && layeredEntries.size() == 0) - { - if (logger.isTraceEnabled()) - { - logger.trace("createSnapshot: no snapshot required: "+me.getName()+" ["+me.getId()+"] - lastVersion = "+lastVersion.getVersionID() + "("+tag+", "+description+")"); - } - - // So, we set the tag and description fields of the latest version. - if (tag != null || description != null) - { - lastVersion.setTag(tag); - lastVersion.setDescription(description); - - AVMDAOs.Instance().fVersionRootDAO.update(lastVersion); - } - snapShotMap.put(getName(), lastVersion.getVersionID()); - - if (logger.isTraceEnabled()) - { - logger.trace("createSnapshot: no snapshot required: "+me.getName()+(tag != null ? "("+tag+")" : "")+" [lastVersion = "+lastVersion.getVersionID()+"]"); - } - - return snapShotMap; - } - if (logger.isTraceEnabled()) - { - logger.trace("createSnapshot: snapshot: "+me.getName()+" ["+me.getId()+"] - lastVersion="+lastVersion.getVersionID()+", layeredEntries="+layeredEntries.size()); - } - - snapShotMap.put(getName(), me.getNextVersionID()); - // Force copies on all the layered nodes from last snapshot. - for (VersionLayeredNodeEntry entry : layeredEntries) - { - String[] pathParts = AVMUtil.splitPath(entry.getPath()); - Lookup lookup = me.lookup(-1, pathParts[1], false, false); - if (lookup == null) - { - continue; - } - if (lookup.getCurrentNode().getType() != AVMNodeType.LAYERED_DIRECTORY && - lookup.getCurrentNode().getType() != AVMNodeType.LAYERED_FILE) - { - continue; - } - if (lookup.getCurrentNode().getIsNew()) - { - continue; - } - - if (lookup.getCurrentNode().getType() == AVMNodeType.LAYERED_DIRECTORY) - { - fAVMRepository.forceCopy(entry.getPath()); - me = (AVMStoreImpl)AVMDAOs.Instance().fAVMStoreDAO.getByID(getId()); - } - else if (lookup.getCurrentNode().getType() == AVMNodeType.LAYERED_FILE) - { - String parentName[] = AVMUtil.splitBase(entry.getPath()); - AVMNode child = lookup.getCurrentNode(); - DirectoryNode parent = lookup.getCurrentNodeDirectory(); - - AVMNode newChild = ((LayeredFileNode)child).copyLiterally(lookup); - newChild.setAncestor(child); - parent.putChild(parentName[1], newChild); - } - } - - if (logger.isTraceEnabled()) - { - logger.trace("createSnapshot: force copy: "+me.getName()+(tag != null ? "("+tag+")" : "")+" [lastVersion="+lastVersion.getVersionID()+", layeredEntriesCnt="+layeredEntries.size()+"] in " + (System.currentTimeMillis() - start) + " msecs"); - } - - // Clear out the new nodes. - List allLayeredNodeIDs = AVMDAOs.Instance().fAVMNodeDAO.getNewLayeredInStoreIDs(me); - - AVMDAOs.Instance().fAVMNodeDAO.clearNewInStore(me); - - AVMDAOs.Instance().fAVMNodeDAO.clear(); - List layeredNodeIDs = new ArrayList(); - for (Long layeredID : allLayeredNodeIDs) - { - Layered layered = (Layered)AVMDAOs.Instance().fAVMNodeDAO.getByID(layeredID); - - String indirection = null; - if (layered != null) - { - indirection = layered.getIndirection(); - } - - if (indirection == null) - { - continue; - } - layeredNodeIDs.add(layeredID); - String storeName = AVMUtil.getStoreName(indirection); - if (!snapShotMap.containsKey(storeName)) - { - AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(storeName); - if (store == null) - { - layered.setIndirectionVersion(-1); - } - else - { - store.createSnapshot(null, null, snapShotMap); - layered = (Layered)AVMDAOs.Instance().fAVMNodeDAO.getByID(layeredID); - layered.setIndirectionVersion(snapShotMap.get(storeName)); - } - } - else - { - layered.setIndirectionVersion(snapShotMap.get(storeName)); - } - - AVMDAOs.Instance().fAVMNodeDAO.update(layered); - } - - // Make up a new version record. - String user = RawServices.Instance().getAuthenticationContext().getCurrentUserName(); - if (user == null) - { - user = RawServices.Instance().getAuthenticationContext().getSystemUserName(); - } - - me = (AVMStoreImpl)AVMDAOs.Instance().fAVMStoreDAO.getByID(getId()); - VersionRoot versionRoot = new VersionRootImpl(me, - me.getRoot(), - me.getNextVersionID(), - System.currentTimeMillis(), - user, - tag, - description); - - me.setNextVersionID(me.getNextVersionID()+1); - - AVMDAOs.Instance().fAVMStoreDAO.update(me); - - AVMDAOs.Instance().fVersionRootDAO.save(versionRoot); - - int vlneCnt = 0; - - for (Long nodeID : layeredNodeIDs) - { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(nodeID); - List paths = fAVMRepository.getVersionPaths(versionRoot, node); - for (String path : paths) - { - VersionLayeredNodeEntry entry = - new VersionLayeredNodeEntryImpl(versionRoot, path); - AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.save(entry); - } - - vlneCnt = vlneCnt+paths.size(); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Raw snapshot: "+me.getName()+(tag != null ? "("+tag+")" : "")+" [versionRootId="+versionRoot.getId()+", layeredNodeIDsCnt="+layeredNodeIDs.size()+", versionLayeredNodeEntriesCnt="+vlneCnt+"] in " + (System.currentTimeMillis() - start) + " msecs"); - } - - return snapShotMap; - } - - /** - * Create a new directory. - * @param path The path to the containing directory. - * @param name The name of the new directory. - */ - public void createDirectory(String path, String name, List aspects, Map properties) - { - Lookup lPath = lookupDirectory(-1, path, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(this, dir, PermissionService.ADD_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - Pair temp = dir.lookupChild(lPath, name, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if (child != null && child.getType() != AVMNodeType.DELETED_NODE) - { - throw new AVMExistsException("Child exists: " + name); - } - DirectoryNode newDir = null; - if (lPath.isLayered()) // Creating a directory in a layered context creates - // a LayeredDirectoryNode that gets its indirection from - // its parent. - { - // TODO - collapse save/update - newDir = new LayeredDirectoryNodeImpl((String)null, this, null, null, ACLCopyMode.INHERIT); - ((LayeredDirectoryNodeImpl)newDir).setPrimaryIndirection(false); - ((LayeredDirectoryNodeImpl)newDir).setLayerID(lPath.getTopLayer().getLayerID()); - - newDir.copyACLs(dir, ACLCopyMode.INHERIT); - - AVMDAOs.Instance().fAVMNodeDAO.update(newDir); - } - else - { - newDir = new PlainDirectoryNodeImpl(this); - - newDir.copyACLs(dir, ACLCopyMode.INHERIT); - - AVMDAOs.Instance().fAVMNodeDAO.save(newDir); - } - - // newDir.setVersionID(getNextVersionID()); - if (child != null) - { - newDir.setAncestor(child); - } - //dir.updateModTime(); - dir.putChild(name, newDir); - if (aspects != null) - { - Set aspectQNames = new HashSet(newDir.getAspects()); - aspectQNames.addAll(aspects); - ((DirectoryNodeImpl)newDir).setAspects(aspectQNames); - } - if (properties != null) - { - Map props = new HashMap(newDir.getProperties()); - props.putAll(properties); - ((DirectoryNodeImpl)newDir).setProperties(props); - } - } - - /** - * Create a new layered directory. - * @param srcPath The target indirection for a layered node. - * @param dstPath The containing directory for the new node. - * @param name The name of the new node. - */ - public void createLayeredDirectory(String srcPath, String dstPath, - String name) - { - Lookup lPath = lookupDirectory(-1, dstPath, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + dstPath + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - Pair temp = dir.lookupChild(lPath, name, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if (child != null && child.getType() != AVMNodeType.DELETED_NODE) - { - throw new AVMExistsException("Child exists: " + name); - } - Long parentAcl = dir.getAcl() == null ? null : dir.getAcl().getId(); - - LayeredDirectoryNode newDir = - new LayeredDirectoryNodeImpl(srcPath, this, null, parentAcl, ACLCopyMode.INHERIT); - - if (lPath.isLayered()) - { - // When a layered directory is made inside of a layered context, - // it gets its layer id from the topmost layer in its lookup - // path. - LayeredDirectoryNode top = lPath.getTopLayer(); - newDir.setLayerID(top.getLayerID()); - } - else - { - // Otherwise we issue a brand new layer id. - - // note: re-use generated node id as a layer id - newDir.setLayerID(newDir.getId()); - } - - AVMDAOs.Instance().fAVMNodeDAO.update(newDir); - - if (child != null) - { - newDir.setAncestor(child); - } - - // newDir.setVersionID(getNextVersionID()); - //dir.updateModTime(); - dir.putChild(name, newDir); - } - - /** - * Create a new file. - * @param path The path to the directory to contain the new file. - * @param name The name to give the new file. - * initial content. - */ - public OutputStream createFile(String path, String name) - { - return createFile(path, name, null, null).getContentOutputStream(); - } - - /** - * Create a file with the given contents. - * @param path The path to the containing directory. - * @param name The name to give the new file. - * @param data The contents. - */ - public void createFile(String path, String name, File data, List aspects, Map properties) - { - createFile(path, name, aspects, properties).putContent(data); - } - - private ContentWriter createFile(String path, String name, List aspects, Map properties) - { - Lookup lPath = lookupDirectory(-1, path, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(this, dir, PermissionService.ADD_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - Pair temp = dir.lookupChild(lPath, name, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if (child != null && child.getType() != AVMNodeType.DELETED_NODE) - { - throw new AVMExistsException("Child exists: " + name); - } - - PlainFileNodeImpl file = new PlainFileNodeImpl(this); - - file.setContentData(new ContentData(null, - RawServices.Instance().getMimetypeService().guessMimetype(name), - -1, - "UTF-8")); - - file.copyACLs(dir, ACLCopyMode.INHERIT); - - AVMDAOs.Instance().fAVMNodeDAO.save(file); - - // file.setVersionID(getNextVersionID()); - //dir.updateModTime(); - dir.putChild(name, file); - if (child != null) - { - file.setAncestor(child); - } - - if (aspects != null) - { - Set aspectQNames = new HashSet(aspects.size()); - aspectQNames.addAll(aspects); - file.setAspects(aspectQNames); - } - if (properties != null) - { - Map props = new HashMap(properties.size()); - props.putAll(properties); - file.setProperties(props); - } - - return createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name), true); - } - - /** - * Create a new layered file. - * @param srcPath The target indirection for the layered file. - * @param dstPath The path to the directory to contain the new file. - * @param name The name of the new file. - */ - public void createLayeredFile(String srcPath, String dstPath, String name) - { - Lookup lPath = lookupDirectory(-1, dstPath, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + dstPath + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(this, dir, PermissionService.ADD_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + dstPath); - } - Pair temp = dir.lookupChild(lPath, name, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if (child != null && child.getType() != AVMNodeType.DELETED_NODE) - { - throw new AVMExistsException("Child exists: " + name); - } - // TODO Reexamine decision to not check validity of srcPath. Warning for now. - String[] srcPathParts = srcPath.split(":"); - String[] dstPathParts = dstPath.split(":"); - - Lookup lPathSrc = null; - if (srcPathParts[0].equals(dstPathParts[0])) - { - lPathSrc = lookup(-1, srcPathParts[1], false, false); - } - else - { - AVMStore srcStore = AVMDAOs.Instance().fAVMStoreDAO.getByName(srcPathParts[0]); - if (srcStore != null) - { - lPathSrc = srcStore.lookup(-1, srcPathParts[1], false, false); - } - } - - AVMNode srcNode = null; - if (lPathSrc == null) - { - logger.warn("CreateLayeredFile: srcPath not found: "+srcPath); - } - else - { - srcNode = (AVMNode)lPathSrc.getCurrentNode(); - if (! (srcNode instanceof FileNode)) - { - logger.warn("CreateLayeredFile: srcPath is not a file: "+srcPath); - } - } - - LayeredFileNodeImpl newFile = - new LayeredFileNodeImpl(srcPath, this, null); - - newFile.copyACLs(dir, ACLCopyMode.INHERIT); - - AVMDAOs.Instance().fAVMNodeDAO.save(newFile); - - if (child != null) - { - newFile.setAncestor(child); - } - else - { - if ((srcNode != null) && (srcNode instanceof FileNode)) - { - newFile.setAncestor((FileNode)srcNode); - } - } - - // newFile.setVersionID(getNextVersionID()); - //dir.updateModTime(); - dir.putChild(name, newFile); - } - - /** - * Get an input stream from a file. - * @param version The version id to look under. - * @param path The path to the file. - * @return An InputStream. - */ - public InputStream getInputStream(int version, String path) - { - ContentReader reader = getContentReader(version, path); - if (reader == null) - { - // TODO This is wrong, wrong, wrong. Do something about it - // sooner rather than later. - throw new AVMNotFoundException(path + " has no content."); - } - return reader.getContentInputStream(); - } - - /** - * Get a ContentReader from a file. - * @param version The version to look under. - * @param path The path to the file. - * @return A ContentReader. - */ - public ContentReader getContentReader(int version, String path) - { - try - { - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(version, getName() + ":" + path); - return RawServices.Instance().getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT); - } - catch (InvalidNodeRefException inre) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - } - - /** - * Get a ContentWriter to a file. - * @param path The path to the file. - * @return A ContentWriter. - * @param update true if the property must be updated atomically when the content write - * stream is closed (attaches a listener to the stream); false if the client code - * will perform the updates itself. - */ - public ContentWriter createContentWriter(String path, boolean update) - { - try - { - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, getName() + ":" + path); - ContentWriter writer = - RawServices.Instance().getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, update); - return writer; - } - catch (InvalidNodeRefException inre) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - } - - /** - * Get a listing from a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @return A List of FolderEntries. - */ - public SortedMap getListing(int version, String path, - boolean includeDeleted) - { - Lookup lPath = lookupDirectory(version, path, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(this, dir, PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - Map listing = dir.getListing(lPath, includeDeleted); - return translateListing(listing, lPath); - } - - /** - * Get the list of nodes directly contained in a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @return A Map of names to descriptors. - */ - public SortedMap getListingDirect(int version, String path, - boolean includeDeleted) - { - Lookup lPath = lookupDirectory(version, path, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(this, dir, PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - if (lPath.isLayered() && dir.getType() != AVMNodeType.LAYERED_DIRECTORY) - { - return new TreeMap(); - } - Map listing = dir.getListingDirect(lPath, includeDeleted); - return translateListing(listing, lPath); - } - - /** - * Helper to convert an internal representation of a directory listing - * to an external representation. - * @param listing The internal listing, a Map of names to nodes. - * @param lPath The Lookup for the directory. - * @return A Map of names to descriptors. - */ - private SortedMap - translateListing(Map listing, Lookup lPath) - { - SortedMap results = new TreeMap(String.CASE_INSENSITIVE_ORDER); - for (String name : listing.keySet()) - { - // TODO consider doing this at a lower level. - AVMNode child = listing.get(name); - AVMNodeDescriptor desc = child.getDescriptor(lPath, name); - results.put(name, desc); - } - return results; - } - - /** - * Get the names of the deleted nodes in a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @return A List of names. - */ - public List getDeleted(int version, String path) - { - Lookup lPath = lookupDirectory(version, path, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(this, dir, PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - List deleted = dir.getDeletedNames(); - return deleted; - } - - /** - * Get an output stream to a file. - * @param path The path to the file. - * @return An OutputStream. - */ - public OutputStream getOutputStream(String path) - { - ContentWriter writer = createContentWriter(path, true); - return writer.getContentOutputStream(); - } - - /** - * Remove a node and everything underneath it. - * @param path The path to the containing directory. - * @param name The name of the node to remove. - */ - public void removeNode(String path, String name) - { - Lookup lPath = lookupDirectory(-1, path, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - Pair temp = dir.lookupChild(lPath, name, false); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if (child == null) - { - Lookup lPathToChild = lookup(-1, path+"/"+name, true, false); - if (lPathToChild != null) - { - // ETHREEOH-2297 - child = lPathToChild.getCurrentNode(); - } - if (child == null) - { - throw new AVMNotFoundException("Does not exist: " + name); - } - - dir = lPathToChild.getCurrentNodeDirectory(); - } - - if (!fAVMRepository.can(this, child, PermissionService.DELETE_NODE, false)) - { - throw new AVMNotFoundException("Not allowed to delete in store : " + getName() +" at " + path); - } - - if (dir != null) - { - dir.removeChild(lPath, name); - //dir.updateModTime(); - } - } - - /** - * Allow a name which has been deleted to be visible through that layer. - * @param dirPath The path to the containing directory. - * @param name The name to uncover. - */ - public void uncover(String dirPath, String name) - { - Lookup lPath = lookupDirectory(-1, dirPath, true); - if (lPath == null) - { - throw new AVMNotFoundException("Directory path " + dirPath + " not found."); - } - DirectoryNode node = (DirectoryNode)lPath.getCurrentNode(); - if (node.getType() != AVMNodeType.LAYERED_DIRECTORY) - { - throw new AVMWrongTypeException("Not a layered directory: " + dirPath); - } - Pair temp = node.lookupChild(lPath, name, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if(child == null) - { - throw new AVMNotFoundException("No child to recover at "+dirPath+" called "+name); - } - if (!fAVMRepository.can(this, child, PermissionService.DELETE_NODE, false)) - { - throw new AccessDeniedException("Not allowed to uncover: " + dirPath + " -> "+name); - } - ((LayeredDirectoryNode)node).uncover(lPath, name); - node.updateModTime(); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Get the set of all extant versions for this AVMStore. - * @return A Set of version ids. - */ - public List getVersions() - { - List versions = AVMDAOs.Instance().fVersionRootDAO.getAllInAVMStore(this); - List descs = new ArrayList(); - for (VersionRoot vr : versions) - { - VersionDescriptor desc = - new VersionDescriptor(getName(), - vr.getVersionID(), - vr.getCreator(), - vr.getCreateDate(), - vr.getTag(), - vr.getDescription()); - descs.add(desc); - } - return descs; - } - - /** - * Get the versions between the given dates (inclusive). From or - * to may be null but not both. - * @param from The earliest date. - * @param to The latest date. - * @return The Set of matching version IDs. - */ - public List getVersions(Date from, Date to) - { - List versions = AVMDAOs.Instance().fVersionRootDAO.getByDates(this, from, to); - List descs = new ArrayList(); - for (VersionRoot vr : versions) - { - VersionDescriptor desc = - new VersionDescriptor(getName(), - vr.getVersionID(), - vr.getCreator(), - vr.getCreateDate(), - vr.getTag(), - vr.getDescription()); - descs.add(desc); - } - return descs; - } - - - - public List getVersionsTo(int version) - { - List versions = AVMDAOs.Instance().fVersionRootDAO.getByVersionsTo(this, version); - List descs = new ArrayList(); - for (VersionRoot vr : versions) - { - VersionDescriptor desc = - new VersionDescriptor(getName(), - vr.getVersionID(), - vr.getCreator(), - vr.getCreateDate(), - vr.getTag(), - vr.getDescription()); - descs.add(desc); - } - return descs; - } - - public List getVersionsFrom(int version) - { - List versions = AVMDAOs.Instance().fVersionRootDAO.getByVersionsFrom(this, version); - List descs = new ArrayList(); - for (VersionRoot vr : versions) - { - VersionDescriptor desc = - new VersionDescriptor(getName(), - vr.getVersionID(), - vr.getCreator(), - vr.getCreateDate(), - vr.getTag(), - vr.getDescription()); - descs.add(desc); - } - return descs; - } - - - - - public List getVersionsBetween(int startVersion, int endVersion) - { - List versions = AVMDAOs.Instance().fVersionRootDAO.getByVersionsBetween(this, startVersion, endVersion); - List descs = new ArrayList(); - for (VersionRoot vr : versions) - { - VersionDescriptor desc = - new VersionDescriptor(getName(), - vr.getVersionID(), - vr.getCreator(), - vr.getCreateDate(), - vr.getTag(), - vr.getDescription()); - descs.add(desc); - } - return descs; - } - - /** - * Get the AVMRepository. - * @return The AVMRepository - */ - public AVMRepository getAVMRepository() - { - return fAVMRepository; - } - - /** - * Lookup up a path. - * @param version The version to look in. - * @param path The path to look up. - * @param write Whether this is in the context of a write. - * @return A Lookup object. - */ - public Lookup lookup(int version, String path, boolean write, boolean includeDeleted) - { - SimplePath sPath = new SimplePath(path); - return RawServices.Instance().getLookupCache().lookup(this, version, sPath, write, includeDeleted); - } - - /** - * Get the root node descriptor. - * @param version The version to get. - * @return The descriptor. - */ - public AVMNodeDescriptor getRoot(int version) - { - AVMNode root = null; - if (version < 0) - { - root = getRoot(); - } - else - { - root = AVMDAOs.Instance().fAVMNodeDAO.getAVMStoreRoot(this, version); - } - if (!fAVMRepository.can(this, root, PermissionService.READ_CHILDREN, true)) - { - throw new AccessDeniedException("Not allowed to read: " + getName() + "@" + version); - } - return root.getDescriptor(getName() + ":", "", null, -1); - } - - /** - * Lookup a node and insist that it is a directory. - * @param version The version to look under. - * @param path The path to the directory. - * @param write Whether this is in a write context. - * @return A Lookup object. - */ - public Lookup lookupDirectory(int version, String path, boolean write) - { - // Just do a regular lookup and assert that the last element - // is a directory. - Lookup lPath = lookup(version, path, write, false); - if (lPath == null) - { - return null; - } - if (lPath.getCurrentNode().getType() != AVMNodeType.PLAIN_DIRECTORY && - lPath.getCurrentNode().getType() != AVMNodeType.LAYERED_DIRECTORY) - { - return null; - } - return lPath; - } - - /** - * Get the effective indirection path for a layered node. - * @param version The version to look under. - * @param path The path to the node. - * @return The effective indirection. - */ - public String getIndirectionPath(int version, String path) - { - Lookup lPath = lookup(version, path, false, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - if (!lPath.isLayered()) - { - return null; - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.READ_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - LayeredDirectoryNode dir = (LayeredDirectoryNode)node; - return dir.getUnderlying(lPath); - } - else if (node.getType() == AVMNodeType.LAYERED_FILE) - { - LayeredFileNode file = (LayeredFileNode)node; - return file.getUnderlying(lPath); - } - return lPath.getIndirectionPath(); - } - - /** - * Make the indicated node a primary indirection. - * @param path The path to the node. - */ - public void makePrimary(String path) - { - Lookup lPath = lookupDirectory(-1, path, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!lPath.isLayered()) - { - throw new AVMException("Not in a layered context: " + path); - } - if (!fAVMRepository.can(this, dir, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - dir.turnPrimary(lPath); - dir.updateModTime(); - - AVMDAOs.Instance().fAVMNodeDAO.update(dir); - } - - /** - * Change the indirection of a layered directory. - * @param path The path to the layered directory. - * @param target The target indirection to set. - */ - public void retargetLayeredDirectory(String path, String target) - { - Lookup lPath = lookupDirectory(-1, path, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!lPath.isLayered()) - { - throw new AVMException("Not in a layered context: " + path); - } - if (!fAVMRepository.can(this, dir, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - dir.retarget(lPath, target); - dir.updateModTime(); - - AVMDAOs.Instance().fAVMNodeDAO.update(dir); - } - - /** - * Set the name of this AVMStore. - * @param name - */ - public void setName(String name) - { - fName = name; - } - - /** - * Get the name of this AVMStore. - * @return The name. - */ - public String getName() - { - return fName; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStore#getAcl() - */ - public Acl getStoreAcl() - { - return fACL; - } - - public void setStoreAcl(Acl acl) - { - fACL = acl; - } - - /** - * Set the next version id. - * @param nextVersionID - */ - public void setNextVersionID(int nextVersionID) - { - fNextVersionID = nextVersionID; - } - - /** - * Get the next version id. - * @return The next version id. - */ - public int getNextVersionID() - { - return fNextVersionID; - } - - /** - * This gets the last extant version id. - */ - public int getLastVersionID() - { - Integer lastVersionId = AVMDAOs.Instance().fVersionRootDAO.getMaxVersionID(this); - if (lastVersionId == null) - { - return 0; - } - else - { - return lastVersionId.intValue(); - } - } - - /** - * Set the root directory. - * @param root - */ - public void setRoot(DirectoryNode root) - { - fRoot = root; - } - - /** - * Get the root directory. - * @return The root directory. - */ - public DirectoryNode getRoot() - { - return fRoot; - } - - /** - * Set the version (for concurrency control). - * @param vers The version for optimistic locks. - */ - public void setVers(long vers) - { - fVers = vers; - } - - /** - * Get the version (for concurrency control). - * @return The version for optimistic locks. - */ - public long getVers() - { - return fVers; - } - - /** - * Equals override. - * @param obj - * @return Equality. - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (!(obj instanceof AVMStore)) - { - return false; - } - return getId() == ((AVMStore)obj).getId(); - } - - /** - * Get a hash code. - * @return The hash code. - */ - @Override - public int hashCode() - { - return (int)getId(); - } - - /** - * Purge all nodes reachable only via this version and repository. - * @param version - */ - public void purgeVersion(int version) - { - if (version == 0) - { - throw new AVMBadArgumentException("Cannot purge initial version"); - } - VersionRoot vRoot = AVMDAOs.Instance().fVersionRootDAO.getByVersionID(this, version); - if (vRoot == null) - { - throw new AVMNotFoundException("Version not found."); - } - AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(vRoot); - AVMNode root = vRoot.getRoot(); - if (!fAVMRepository.can(null, root, PermissionService.DELETE_CHILDREN, true)) - { - throw new AccessDeniedException("Not allowed to purge: " + getName() + "@" + version); - } - root.setIsRoot(false); - AVMDAOs.Instance().fAVMNodeDAO.update(root); - AVMDAOs.Instance().fVersionRootDAO.delete(vRoot); - if (root.equals(getRoot())) - { - // We have to set a new current root. - vRoot = AVMDAOs.Instance().fVersionRootDAO.getMaxVersion(this); - setRoot(vRoot.getRoot()); - AVMDAOs.Instance().fAVMStoreDAO.update(this); - } - } - - // TODO permissions? - /** - * Get the descriptor for this. - * @return An AVMStoreDescriptor - */ - public AVMStoreDescriptor getDescriptor() - { - // Get the creator ensuring that nulls are not hit - PropertyValue creatorValue = getProperty(ContentModel.PROP_CREATOR); - String creator = (creatorValue == null ? AuthenticationUtil.SYSTEM_USER_NAME : (String) creatorValue.getValue(DataTypeDefinition.TEXT)); - creator = (creator == null ? AuthenticationUtil.SYSTEM_USER_NAME : creator); - // Get the created date ensuring that nulls are not hit - PropertyValue createdValue = getProperty(ContentModel.PROP_CREATED); - Date created = createdValue == null ? (new Date()) : (Date) createdValue.getValue(DataTypeDefinition.DATE); - created = (created == null) ? (new Date()) : created; - return new AVMStoreDescriptor(getId(), getName(), creator, created.getTime()); - } - - /** - * Set the opacity of a layered directory. An opaque directory hides - * what is pointed at by its indirection. - * @param path The path to the layered directory. - * @param opacity True is opaque; false is not. - */ - public void setOpacity(String path, boolean opacity) - { - Lookup lPath = lookup(-1, path, true, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!(node instanceof LayeredDirectoryNode)) - { - throw new AVMWrongTypeException("Not a LayeredDirectoryNode."); - } - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - ((LayeredDirectoryNode)node).setOpacity(opacity); - node.updateModTime(); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - // TODO Does it make sense to set properties on DeletedNodes? - /** - * Set a property on a node. - * @param path The path to the node. - * @param name The name of the property. - * @param value The value to set. - */ - public void setNodeProperty(String path, QName name, PropertyValue value) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - - node.setProperty(name, value); - - node.setGuid(GUID.generate()); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); // guid and property - } - - /** - * Set a collection of properties on a node. - * @param path The path to the node. - * @param properties The Map of QNames to PropertyValues. - */ - public void setNodeProperties(String path, Map properties) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - if (properties != null) - { - Map props = new HashMap(properties.size()); - props.putAll(properties); - node.addProperties(props); - } - node.setGuid(GUID.generate()); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Get a property by name. - * @param version The version to lookup. - * @param path The path to the node. - * @param name The name of the property. - * @return A PropertyValue or null if not found. - */ - public PropertyValue getNodeProperty(int version, String path, QName name) - { - Lookup lPath = lookup(version, path, false, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.READ_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - - return node.getProperty(name); - } - - /** - * Get all the properties associated with a node. - * @param version The version to lookup. - * @param path The path to the node. - * @return A Map of QNames to PropertyValues. - */ - public Map getNodeProperties(int version, String path) - { - Lookup lPath = lookup(version, path, false, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.READ_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - - return node.getProperties(); - } - - /** - * Delete a single property from a node. - * @param path The path to the node. - * @param name The name of the property. - */ - public void deleteNodeProperty(String path, QName name) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - node.setGuid(GUID.generate()); - - node.deleteProperty(name); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Delete all properties from a node. - * @param path The path to the node. - */ - public void deleteNodeProperties(String path) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - node.setGuid(GUID.generate()); - node.deleteProperties(); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Set a property on this store. Replaces if property already exists. - * @param name The QName of the property. - * @param value The actual PropertyValue. - */ - public void setProperty(QName name, PropertyValue value) - { - AVMStoreProperty prop = new AVMStorePropertyImpl(); - prop.setStore(this); - prop.setQname(name); - prop.setValue(value); - AVMDAOs.Instance().fAVMStorePropertyDAO.save(prop); - } - - /** - * Set a group of properties on this store. Replaces any property that exists. - * @param properties A Map of QNames to PropertyValues to set. - */ - public void setProperties(Map properties) - { - for (QName name : properties.keySet()) - { - setProperty(name, properties.get(name)); - } - } - - /** - * Get a property by name. - * @param name The QName of the property to fetch. - * @return The PropertyValue or null if non-existent. - */ - public PropertyValue getProperty(QName name) - { - return AVMDAOs.Instance().fAVMStorePropertyDAO.get(this, name); - } - - /** - * Get all the properties associated with this store. - * @return A Map of the properties. - */ - public Map getProperties() - { - return AVMDAOs.Instance().fAVMStorePropertyDAO.get(this); - } - - /** - * Delete a property. - * @param name The name of the property to delete. - */ - public void deleteProperty(QName name) - { - AVMDAOs.Instance().fAVMStorePropertyDAO.delete(this, name); - } - - /** - * Get the ContentData on a file. - * @param version The version to look under. - * @param path The path to the file. - * @return The ContentData corresponding to the file. - */ - public ContentData getContentDataForRead(int version, String path) - { - Lookup lPath = lookup(version, path, false, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!(node instanceof FileNode)) - { - throw new AVMWrongTypeException("File Expected."); - } - if (!fAVMRepository.can(this, node, PermissionService.READ_CONTENT, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read: " + path); - } - ContentData content = ((FileNode)node).getContentData(lPath); - // AVMDAOs.Instance().fAVMNodeDAO.evict(node); - return content; - } - - /** - * Get the ContentData on a file for writing. - * @param path The path to the file. - * @return The ContentData corresponding to the file. - */ - public ContentData getContentDataForWrite(String path) - { - Lookup lPath = lookup(-1, path, true, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!(node instanceof FileNode)) - { - throw new AVMWrongTypeException("File Expected."); - } - if (!fAVMRepository.can(this, node, PermissionService.WRITE_CONTENT, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write content: " + path); - } - // TODO Set modifier. - node.updateModTime(); - node.setGuid(GUID.generate()); - - //AVMDAOs.Instance().fAVMNodeDAO.update(node); - // TODO review 'optimisation' - AVMDAOs.Instance().fAVMNodeDAO.updateModTimeAndGuid(node); - - ContentData content = ((FileNode)node).getContentData(lPath); - // AVMDAOs.Instance().fAVMNodeDAO.evict(node); - return content; - } - - // Not doing permission checking because it will already have been done - // at the getContentDataForWrite point. - /** - * Set the ContentData for a file. - * @param path The path to the file. - * @param data The ContentData to set. - */ - public void setContentData(String path, ContentData data) - { - Lookup lPath = lookup(-1, path, true, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!(node instanceof FileNode)) - { - throw new AVMWrongTypeException("File Expected."); - } - ((FileNode)node).setContentData(data); - node.updateModTime(); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Set meta data, aspects, properties, acls, from another node. - * @param path The path to the node to set metadata on. - * @param from The node to get the metadata from. - */ - public void setMetaDataFrom(String path, AVMNode from) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path not found: " + path); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write properties: " + path); - } - node.copyMetaDataFrom(from, node.getAcl() == null ? null : node.getAcl().getInheritsFrom()); - node.setGuid(GUID.generate()); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Add an aspect to a node. - * @param path The path to the node. - * @param aspectName The name of the aspect. - */ - public void addAspect(String path, QName aspectName) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write: " + path); - } - - node.addAspect(aspectName); - node.setGuid(GUID.generate()); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Get all aspects on a given node. - * @param version The version to look under. - * @param path The path to the node. - * @return A List of the QNames of the aspects. - */ - public Set getAspects(int version, String path) - { - Lookup lPath = lookup(version, path, false, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.READ_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read properties: " + path); - } - - return node.getAspects(); - } - - /** - * Remove an aspect and all its properties from a node. - * @param path The path to the node. - * @param aspectName The name of the aspect. - */ - public void removeAspect(String path, QName aspectName) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write properties: " + path); - } - - node.removeAspect(aspectName); - - AspectDefinition def = RawServices.Instance().getDictionaryService().getAspect(aspectName); - Map properties = def.getProperties(); - - for (QName propertyQName : properties.keySet()) - { - node.deleteProperty(propertyQName); - } - - node.setGuid(GUID.generate()); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Does a given node have a given aspect. - * @param version The version to look under. - * @param path The path to the node. - * @param aspectName The name of the aspect. - * @return Whether the node has the aspect. - */ - public boolean hasAspect(int version, String path, QName aspectName) - { - Lookup lPath = lookup(version, path, false, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.READ_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read properties: " + path); - } - - return node.getAspects().contains(aspectName); - } - - /** - * Set the ACL on a node. - * @param path The path to the node. - * @param acl The ACL to set. - */ - public void setACL(String path, Acl acl) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.CHANGE_PERMISSIONS, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to change permissions: " + path); - } - node.setAcl(acl); - node.setGuid(GUID.generate()); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /** - * Get the ACL on a node. - * @param version The version to look under. - * @param path The path to the node. - * @return The ACL. - */ - public Acl getACL(int version, String path) - { - Lookup lPath = lookup(version, path, false, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - if (!fAVMRepository.can(this, lPath.getCurrentNode(), PermissionService.READ_PERMISSIONS, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read permissions: " + path + " in "+getName()); - } - return lPath.getCurrentNode().getAcl(); - } - - /** - * Link a node into a directory, directly. - * @param parentPath The path to the directory. - * @param name The name to give the parent. - * @param toLink The node to link. - */ - public void link(String parentPath, String name, AVMNodeDescriptor toLink) - { - Lookup lPath = lookupDirectory(-1, parentPath, true); - if (lPath == null) - { - String pathParts[] = AVMUtil.splitBase(parentPath); - Lookup lPath2 = lookup(-1, pathParts[0], true, false); - if (lPath2 != null) - { - DirectoryNode parent = (DirectoryNode)lPath2.getCurrentNode(); - Pair temp = parent.lookupChild(lPath2, pathParts[1], false); - if ((temp != null) && (temp.getFirst() != null)) - { - DirectoryNode dir = (DirectoryNode)temp.getFirst(); - - if (logger.isDebugEnabled()) - { - logger.debug("Found: "+dir); - } - - boolean directlyContained = false; - - if (!fAVMRepository.can(null, dir, PermissionService.ADD_CHILDREN, directlyContained)) - { - throw new AccessDeniedException("Not allowed to add children: " + parentPath); - } - - AVMNodeDescriptor desc = fAVMRepository.forceCopy(AVMUtil.buildAVMPath(this.getName(), parentPath)); - fAVMRepository.link(desc, name, toLink); - return; - } - } - - throw new AVMNotFoundException("Path " + parentPath + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - if (!fAVMRepository.can(null, dir, PermissionService.ADD_CHILDREN, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to add children: " + parentPath); - } - dir.link(lPath, name, toLink); - } - - /** - * Update a link to a node in a directory, directly. - * @param parentPath The path to the directory. - * @param name The name to give the parent. - * @param toLink The node to link. - */ - public void updateLink(String parentPath, String name, AVMNodeDescriptor toLink) - { - Lookup lPath = lookupDirectory(-1, parentPath, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + parentPath + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - - Lookup cPath = new Lookup(lPath, AVMDAOs.Instance().fAVMNodeDAO, AVMDAOs.Instance().fAVMStoreDAO); - Pair result = dir.lookupChild(cPath, name, true); - if (result != null) - { - AVMNode child = result.getFirst(); - if (!fAVMRepository.can(null, child, PermissionService.WRITE, cPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to update node: " + parentPath + "/" +name ); - } - dir.removeChild(lPath, name); - } - dir.link(lPath, name, toLink); - } - - /** - * Revert a head path to a given version. This works by cloning - * the version to revert to, and then linking that new version into head. - * The reverted version will have the previous head version as ancestor. - * @param path The path to the parent directory. - * @param name The name of the node to revert. - * @param toRevertTo The descriptor of the version to revert to. - */ - public void revert(String path, String name, AVMNodeDescriptor toRevertTo) - { - Lookup lPath = lookupDirectory(-1, path, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path " + path + " not found."); - } - DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); - - Pair temp = dir.lookupChild(lPath, name, true); - AVMNode child = (temp == null) ? null : temp.getFirst(); - if (child == null) - { - throw new AVMNotFoundException("Node not found: " + name); - } - if (!fAVMRepository.can(null, child, PermissionService.WRITE, false)) - { - throw new AccessDeniedException("Not allowed to revert: " + path); - } - AVMNode revertNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(toRevertTo.getId()); - if (revertNode == null) - { - throw new AVMNotFoundException(toRevertTo.toString()); - } - AVMNode toLink = revertNode.copy(lPath); - dir.putChild(name, toLink); - toLink.changeAncestor(child); - toLink.setVersionID(child.getVersionID() + 1); - - toLink.addAspect(WCMModel.ASPECT_REVERTED); - - PropertyValue value = new PropertyValue(null, toRevertTo.getId()); - toLink.setProperty(WCMModel.PROP_REVERTED_ID, value); - - AVMDAOs.Instance().fAVMNodeDAO.update(toLink); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStore#setGuid(java.lang.String, java.lang.String) - */ - public void setGuid(String path, String guid) - { - Lookup lPath = lookup(-1, path, true, true); - if (lPath == null) - { - throw new AVMNotFoundException("Path not found: " + path); - } - AVMNode node = lPath.getCurrentNode(); - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write properties: " + path); - } - node.setGuid(guid); - - AVMDAOs.Instance().fAVMNodeDAO.update(node); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStore#setEncoding(java.lang.String, java.lang.String) - */ - public void setEncoding(String path, String encoding) - { - Lookup lPath = lookup(-1, path, true, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path not found: " + path); - } - AVMNode node = lPath.getCurrentNode(); - if (node.getType() != AVMNodeType.PLAIN_FILE) - { - throw new AVMWrongTypeException("Not a File: " + path); - } - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write properties: " + path); - } - PlainFileNode file = (PlainFileNode)node; - ContentData contentData = file.getContentData(); - contentData = ContentData.setEncoding(contentData, encoding); - file.setContentData(contentData); - - AVMDAOs.Instance().fAVMNodeDAO.update(file); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStore#setMimeType(java.lang.String, java.lang.String) - */ - public void setMimeType(String path, String mimeType) - { - Lookup lPath = lookup(-1, path, true, false); - if (lPath == null) - { - throw new AVMNotFoundException("Path not found: " + path); - } - AVMNode node = lPath.getCurrentNode(); - if (node.getType() != AVMNodeType.PLAIN_FILE) - { - throw new AVMWrongTypeException("Not a File: " + path); - } - if (!fAVMRepository.can(this, node, PermissionService.WRITE_PROPERTIES, lPath.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to write properties: " + path); - } - PlainFileNode file = (PlainFileNode)node; - ContentData contentData = file.getContentData(); - contentData = ContentData.setMimetype(contentData, mimeType); - file.setContentData(contentData); - - AVMDAOs.Instance().fAVMNodeDAO.update(file); - } - - // for debug - @Override - public String toString() - { - return getName(); - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMStoreProperty.java b/source/java/org/alfresco/repo/avm/AVMStoreProperty.java deleted file mode 100644 index dd168cfc3a..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMStoreProperty.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.service.namespace.QName; - -/** - * Arbitrary properties associated with AVMStores. - * @author britt - */ -public interface AVMStoreProperty -{ - /** - * Set the AVMStore. - * @param store The AVMStore to set. - */ - public void setStore(AVMStore store); - - /** - * Get the AVMStore. - * @return The AVMStore this property belongs to. - */ - public AVMStore getStore(); - - /** - * Set the property type. - * - * @param qname the store property QName - */ - public void setQname(QName qname); - - /** - * Get the property type. - * - * @return returns the store property QName - */ - public QName getQname(); - - /** - * Set the actual property value. - * @param value The PropertyValue to set. - */ - public void setValue(PropertyValue value); - - /** - * Get the actual property value. - * @return The actual PropertyValue. - */ - public PropertyValue getValue(); -} diff --git a/source/java/org/alfresco/repo/avm/AVMStorePropertyDAO.java b/source/java/org/alfresco/repo/avm/AVMStorePropertyDAO.java deleted file mode 100644 index 4841f7d190..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMStorePropertyDAO.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.List; -import java.util.Map; - -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.service.namespace.QName; - -/** - * The DAO interface for AVMStoreProperties. - * @author britt - */ -public interface AVMStorePropertyDAO -{ - /** - * Persist a property. - * @param prop The AVMStoreProperty to persist. - */ - public void save(AVMStoreProperty prop); - - /** - * Get a property by store and name. - * @param store The AVMStore. - * @param name The QName of the property. - * @return The given AVMStoreProperty or null if not found. - */ - public PropertyValue get(AVMStore store, QName name); - - /** - * Get all the properties associated with a store. - * @param store The AVMStore whose properties should be fetched. - * @return A map of properties associated with the store. - */ - public Map get(AVMStore store); - - /** - * Query store properties by key pattern. - * @param store The store. - * @param keyPattern An sql 'like' pattern wrapped up in a QName - * @return A map of matching properties. - */ - public Map queryByKeyPattern(AVMStore store, QName keyPattern); - - /** - * Query all stores' properties by key pattern. - * @param keyPattern The sql 'like' pattern wrapped up in a QName - * @return A list of matching properties. - */ - public Map> queryByKeyPattern(QName keyPattern); - - /** - * Update a modified property. - * @param prop The AVMStoreProperty to update. - */ - public void update(AVMStoreProperty prop); - - /** - * Delete a property from a store by name. - * @param store The AVMStore to delete from. - * @param name The name of the property. - */ - public void delete(AVMStore store, QName name); - - /** - * Delete all properties associated with a store. - * @param store The AVMStore whose properties are to be deleted. - */ - public void delete(AVMStore store); -} diff --git a/source/java/org/alfresco/repo/avm/AVMStorePropertyImpl.java b/source/java/org/alfresco/repo/avm/AVMStorePropertyImpl.java deleted file mode 100644 index 564c72bace..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMStorePropertyImpl.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.Serializable; - -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.service.namespace.QName; - -/** - * Simple bean to hold properties attached to AVMStores. - * @author britt - */ -public class AVMStorePropertyImpl implements AVMStoreProperty, Serializable -{ - private static final long serialVersionUID = -5419606158990318723L; - - /** - * The Primary Key. - */ - private Long fID; - - /** - * The store that owns this property. - */ - private AVMStore fStore; - - /** - * The name of the property. - */ - private QName qname; - - /** - * The actual PropertyValue. - */ - private PropertyValue fValue; - - public AVMStorePropertyImpl() - { - } - - /** - * {@inheritDoc} - */ - public QName getQname() - { - return qname; - } - - /** - * {@inheritDoc} - */ - public void setQname(QName qname) - { - this.qname = qname; - } - - /** - * Get the store this property belongs to. - * @return The AVMStore that owns this. - */ - public AVMStore getStore() - { - return fStore; - } - - /** - * Set the store that this property belongs to. - * @param store The AVMStore. - */ - public void setStore(AVMStore store) - { - fStore = store; - } - - /** - * Get the actual property value. - * @return A PropertyValue object. - */ - public PropertyValue getValue() - { - return fValue; - } - - /** - * Set the actual property value. - * @param value The PropertyValue to set. - */ - public void setValue(PropertyValue value) - { - fValue = value; - } - - /** - * Set the primary key. (For Hibernate) - * @param id The primary key. - */ - protected void setId(Long id) - { - fID = id; - } - - /** - * Get the primary key. (For Hibernate) - * @return The primary key. - */ - protected Long getId() - { - return fID; - } - - @Override - public boolean equals(Object other) - { - if (this == other) - { - return true; - } - if (!(other instanceof AVMStoreProperty)) - { - return false; - } - AVMStoreProperty o = (AVMStoreProperty)other; - return fStore.equals(o.getStore()) && qname.equals(o.getQname()); - } - - @Override - public int hashCode() - { - return fStore.hashCode() + qname.hashCode(); - } -} - diff --git a/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java deleted file mode 100644 index 375c3ae2e9..0000000000 --- a/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java +++ /dev/null @@ -1,1516 +0,0 @@ -/* - * Copyright (C) 2005-2012 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.repo.security.permissions.ACLType; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.service.cmr.avmsync.AVMSyncException; -import org.alfresco.service.cmr.avmsync.AVMSyncService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.AccessPermission; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.NameMatcher; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This implements APIs that allow comparison and synchronization - * of node trees as well as cumulative operations on layers to - * support various content production models. - * @author britt - */ -public class AVMSyncServiceImpl implements AVMSyncService -{ - private static Log logger = LogFactory.getLog(AVMSyncServiceImpl.class); - - /** - * The AVMService. - */ - private AVMService fAVMService; - - /** - * The AVMRepository. - */ - private AVMRepository fAVMRepository; - - /** - * The PermissionService - */ - private PermissionService fPermissionService; - - /** - * Do nothing constructor. - */ - public AVMSyncServiceImpl() - { - } - - /** - * Set the AVM Service. For Spring. - * @param avmService The AVMService reference. - */ - public void setAvmService(AVMService avmService) - { - fAVMService = avmService; - } - - public void setAvmRepository(AVMRepository avmRepository) - { - fAVMRepository = avmRepository; - } - - public void setPermissionService(PermissionService service) - { - fPermissionService = service; - } - - /** - * Get a difference list between two corresponding node trees. - * @param srcVersion The version id for the source tree. - * @param srcPath The avm path to the source tree. - * @param dstVersion The version id for the destination tree. - * @param dstPath The avm path to the destination tree. - * @param excluder A NameMatcher used to exclude files from consideration. - * @return A List of AVMDifference structs which can be used for - * the update operation. - */ - public List compare(int srcVersion, String srcPath, - int dstVersion, String dstPath, - NameMatcher excluder) - { - return compare(srcVersion, srcPath, dstVersion, dstPath, excluder, false); - } - - @Override - public List compare(int srcVersion, String srcPath, int dstVersion, String dstPath, NameMatcher excluder, boolean expandDirs) - { - long start = System.currentTimeMillis(); - - if (logger.isDebugEnabled()) - { - logger.debug(srcPath + " : " + dstPath); - } - if (srcPath == null || dstPath == null) - { - throw new AVMBadArgumentException("Illegal null path."); - } - List result = new ArrayList(); - AVMNodeDescriptor srcDesc = fAVMService.lookup(srcVersion, srcPath, true); - if (srcDesc == null) - { - throw new AVMSyncException("Source not found: " + srcPath); - } - AVMNodeDescriptor dstDesc = fAVMService.lookup(dstVersion, dstPath, true); - if (dstDesc == null) - { - // Special case: no pre-existing version in the destination. - result.add(new AVMDifference(srcVersion, srcPath, dstVersion, dstPath, AVMDifference.NEWER)); - } - else - { - // Invoke the recursive implementation. - compare(srcVersion, srcDesc, dstVersion, dstDesc, result, excluder, true, expandDirs); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Raw compare: [" + srcVersion + "," + srcPath + "][" + dstVersion + "," + dstPath + "][" + result.size() + "] in " + (System.currentTimeMillis() - start) - + " msecs"); - } - - return result; - } - - /** - * Internal recursive implementation of compare. - * @param srcVersion The version of the source tree. - * @param srcDesc The current source descriptor. - * @param dstVersion The version of the destination tree. - * @param dstDesc The current dstDesc - */ - private void compare(int srcVersion, AVMNodeDescriptor srcDesc, - int dstVersion, AVMNodeDescriptor dstDesc, - List result, NameMatcher excluder, boolean firstLevel, boolean expandDirs) - { - String srcPath = srcDesc.getPath(); - String dstPath = dstDesc.getPath(); - - String srcParts[] = AVMUtil.splitBase(srcPath); - String srcChildName = srcParts[1]; - - String dstParts[] = AVMUtil.splitBase(dstPath); - String dstChildName = dstParts[1]; - - if ((dstChildName.equalsIgnoreCase(srcChildName)) && (! dstChildName.equals(srcChildName))) - { - // specific rename 'case' - String dstParentPath = dstParts[0]; - if (dstParentPath == null) - { - dstParentPath = AVMUtil.buildAVMPath(AVMUtil.getStoreName(dstPath), ""); - } - dstPath = AVMUtil.extendAVMPath(dstParentPath, srcChildName); - } - - // Determine how the source and destination nodes differ. - if (excluder != null && (excluder.matches(srcPath) || - excluder.matches(dstPath))) - { - return; - } - int diffCode = compareOne(srcDesc, dstDesc, false); - switch (diffCode) - { - case AVMDifference.SAME : - { - // A big short circuit. - return; - } - // The trivial to handle cases. - case AVMDifference.NEWER : - case AVMDifference.OLDER : - case AVMDifference.CONFLICT : - { - result.add(new AVMDifference(srcVersion, srcPath, - dstVersion, dstPath, - diffCode)); - return; - } - case AVMDifference.DIRECTORY : - { - // First special case: source is a layered directory which points to - // the destinations path, and we are comparing 'head' versions. - if (srcDesc.isLayeredDirectory() && - srcDesc.getIndirection().equalsIgnoreCase(dstPath) && srcVersion < 0 && dstVersion < 0) - { - // skip firstLevel (root) - if (! firstLevel) - { - // compare directory itself - eg. for an ACL change - int dirDiffCode = compareOne(srcDesc, dstDesc, true); - switch (dirDiffCode) - { - case AVMDifference.OLDER : - case AVMDifference.NEWER : - case AVMDifference.CONFLICT : - { - result.add(new AVMDifference(srcVersion, srcPath, - dstVersion, dstPath, - dirDiffCode)); - - // Also add all child items if necessary and any exists - if (expandDirs && srcDesc.isDirectory()) - { - addNewChildrenIfAny(srcVersion, srcDesc, dstVersion, AVMNodeConverter.ExtendAVMPath(dstPath, dstDesc.getName()), result); - } - - return; // short circuit - } - case AVMDifference.SAME : - { - break; - } - default : - { - throw new AVMSyncException("Invalid Difference Code " + dirDiffCode + " - Internal Error."); - } - } - } - - // Get only a direct listing, since that's all that can be different. - Map srcList = - fAVMService.getDirectoryListingDirect(srcDesc, true); - // The biggest shortcut: if the source directory is directly empty - // then we're done. - if (srcList.size() == 0) - { - return; - } - // We grab a complete listing of the destination. - Map dstList = - fAVMService.getDirectoryListing(dstDesc, true); - for (String name : srcList.keySet()) - { - AVMNodeDescriptor srcChild = srcList.get(name); - AVMNodeDescriptor dstChild = dstList.get(name); - - String srcChildPath = srcChild.getPath(); - String dstChildPath = AVMNodeConverter.ExtendAVMPath(dstPath, name); - - if (excluder != null && (excluder.matches(srcChildPath) || - excluder.matches(dstChildPath))) - { - continue; - } - if (dstChild == null) - { - // A missing destination child means the source is NEWER. - result.add(new AVMDifference(srcVersion, srcChildPath, - dstVersion, dstChildPath, - AVMDifference.NEWER)); - - // Also add all child items if necessary and any exists - if (expandDirs && srcChild.isDirectory()) - { - addNewChildrenIfAny(srcVersion, srcChild, dstVersion, dstChildPath, result); - } - - continue; - } - // Otherwise recursively invoke. - compare(srcVersion, srcChild, - dstVersion, dstChild, - result, excluder, false, expandDirs); - } - return; - } - // Second special case. Just as above but reversed. - if (dstDesc.isLayeredDirectory() && - dstDesc.getIndirection().equalsIgnoreCase(srcPath) && srcVersion < 0 && dstVersion < 0) - { - // skip firstLevel (root) - if (! firstLevel) - { - // compare directory itself - eg. for an ACL change - int dirDiffCode = compareOne(srcDesc, dstDesc, true); - switch (dirDiffCode) - { - case AVMDifference.OLDER : - case AVMDifference.NEWER : - case AVMDifference.CONFLICT : - { - result.add(new AVMDifference(srcVersion, srcPath, - dstVersion, dstPath, - dirDiffCode)); - return; // short circuit - } - case AVMDifference.SAME : - { - break; - } - default : - { - throw new AVMSyncException("Invalid Difference Code " + dirDiffCode + " - Internal Error."); - } - } - } - - // Get direct content of destination. - Map dstList = - fAVMService.getDirectoryListingDirect(dstDesc, true); - // Big short circuit. - if (dstList.size() == 0) - { - return; - } - // Get the source listing. - Map srcList = - fAVMService.getDirectoryListing(srcDesc, true); - for (String name : dstList.keySet()) - { - AVMNodeDescriptor dstChild = dstList.get(name); - AVMNodeDescriptor srcChild = srcList.get(name); - - String srcChildPath = AVMNodeConverter.ExtendAVMPath(srcPath, name); - String dstChildPath = dstChild.getPath(); - - if (excluder != null && (excluder.matches(srcChildPath) || - excluder.matches(dstChildPath))) - { - continue; - } - if (srcChild == null) - { - // Missing means the source is older. - result.add(new AVMDifference(srcVersion, srcChildPath, - dstVersion, dstChildPath, - AVMDifference.OLDER)); - continue; - } - // Otherwise, recursively invoke. - compare(srcVersion, srcChild, - dstVersion, dstChild, - result, excluder, false, expandDirs); - } - return; - } - // Neither of the special cases apply, so brute force is the only answer. - Map srcList = - fAVMService.getDirectoryListing(srcDesc, true); - Map dstList = - fAVMService.getDirectoryListing(dstDesc, true); - // Iterate over the source. - for (String name : srcList.keySet()) - { - AVMNodeDescriptor srcChild = srcList.get(name); - AVMNodeDescriptor dstChild = dstList.get(name); - - String srcChildPath = srcChild.getPath(); - String dstChildPath = AVMNodeConverter.ExtendAVMPath(dstPath, name); - - if (excluder != null && (excluder.matches(srcChildPath) || - excluder.matches(dstChildPath))) - { - continue; - } - if (dstChild == null) - { - // Not found in the destination means NEWER. - result.add(new AVMDifference(srcVersion, srcChildPath, - dstVersion, dstChildPath, - AVMDifference.NEWER)); - continue; - } - // Otherwise recursive invocation. - compare(srcVersion, srcChild, - dstVersion, dstChild, - result, excluder, false, expandDirs); - } - // Iterate over the destination. - for (String name : dstList.keySet()) - { - if (srcList.containsKey(name)) - { - continue; - } - - AVMNodeDescriptor dstChild = dstList.get(name); - - String srcChildPath = AVMNodeConverter.ExtendAVMPath(srcPath, name); - String dstChildPath = dstChild.getPath(); - - if (excluder != null && (excluder.matches(srcChildPath) || - excluder.matches(dstChildPath))) - { - continue; - } - // An entry not found in the source is OLDER. - result.add(new AVMDifference(srcVersion, srcChildPath, - dstVersion, dstChildPath, - AVMDifference.OLDER)); - } - break; - } - default : - { - throw new AVMSyncException("Invalid Difference Code " + diffCode + " - Internal Error."); - } - } - } - - private void addNewChildrenIfAny(int srcVersion, AVMNodeDescriptor srcChild, int dstVersion, String dstChildPath, List result) - { - Map srcList = fAVMService.getDirectoryListingDirect(srcChild, true); - - for (String name : srcList.keySet()) - { - srcChild = srcList.get(name); - String srcChildPath = srcChild.getPath(); - - String dstPath = AVMNodeConverter.ExtendAVMPath(dstChildPath, name); - AVMNodeDescriptor dstDesc = fAVMService.lookup(dstVersion, dstChildPath, true); - - int diffCode = AVMDifference.NEWER; - if (null == dstDesc) - { - diffCode = AVMDifference.NEWER; - } - result.add(new AVMDifference(srcVersion, srcChildPath, dstVersion, dstPath, diffCode)); - - if (srcChild.isDirectory()) - { - addNewChildrenIfAny(srcVersion, srcChild, dstVersion, dstPath, result); - } - } - } - - /** - * Updates the destination nodes in the AVMDifferences - * with the source nodes. Normally any conflicts or cases in - * which the source of an AVMDifference is older than the destination - * will cause the transaction to roll back. - * @param diffList A List of AVMDifference structs. - * @param excluder A possibly null name matcher to exclude unwanted updates. - * @param ignoreConflicts If this is true the update will skip those - * AVMDifferences which are in conflict with - * the destination. - * @param ignoreOlder If this is true the update will skip those - * AVMDifferences which have the source older than the destination. - * @param overrideConflicts If this is true the update will override conflicting - * AVMDifferences and replace the destination with the conflicting source. - * @param overrideOlder If this is true the update will override AVMDifferences - * @param tag Short update blurb. - * @param description Full update blurb. - * in which the source is older than the destination and overwrite the destination. - */ - public void update(List diffList, - NameMatcher excluder, boolean ignoreConflicts, boolean ignoreOlder, - boolean overrideConflicts, boolean overrideOlder, String tag, String description) - { - long start = System.currentTimeMillis(); - - Map storeVersions = new HashMap(); - Set destStores = new HashSet(); - - Map diffsToUpdate = new TreeMap(); - - for (AVMDifference diff : diffList) - { - if (excluder != null && (excluder.matches(diff.getSourcePath()) || - excluder.matches(diff.getDestinationPath()))) - { - continue; - } - - if (!diff.isValid()) - { - throw new AVMSyncException("Malformed AVMDifference."); - } - - diffsToUpdate.put(diff.getSourcePath(), diff); - } - - for (AVMDifference diff : diffsToUpdate.values()) - { - if (logger.isDebugEnabled()) - { - logger.debug("update: " + diff); - } - // Snapshot the source if needed. - int version = diff.getSourceVersion(); - if (version < 0) - { - String storeName = AVMUtil.getStoreName(diff.getSourcePath()); - if (storeVersions.containsKey(storeName)) - { - // We've already snapshotted this store. - version = storeVersions.get(storeName); - } - else - { - version = fAVMService.createSnapshot(storeName, "Snapshotted for submit.", null).get(storeName); - storeVersions.put(storeName, version); - } - } - AVMNodeDescriptor srcDesc = fAVMService.lookup(version, - diff.getSourcePath(), true); - String [] dstParts = AVMNodeConverter.SplitBase(diff.getDestinationPath()); - if (dstParts[0] == null || diff.getDestinationVersion() >= 0) - { - // You can't have a root node as a destination. - throw new AVMSyncException("Invalid destination node: " + diff.getDestinationPath()); - } - AVMNodeDescriptor dstDesc = fAVMService.lookup(-1, diff.getDestinationPath(), true); - // The default is that the source is newer in the case where - // the destination doesn't exist. - int diffCode = AVMDifference.NEWER; - if (dstDesc != null) - { - diffCode = compareOne(srcDesc, dstDesc, false); - } - // Keep track of stores updated so that they can all be snapshotted - // at end of update. - String dstPath = diff.getDestinationPath(); - destStores.add(AVMUtil.getStoreName(dstPath)); - - dispatchUpdate(diffCode, dstParts[0], dstParts[1], excluder, srcDesc, dstDesc, - ignoreConflicts, ignoreOlder, overrideConflicts, overrideOlder); - } - - for (String storeName : destStores) - { - fAVMService.createSnapshot(storeName, tag, description); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Raw update: [" + diffList.size() + "] in " + (System.currentTimeMillis() - start) + " msecs"); - } - } - - private void dispatchUpdate(int diffCode, String parentPath, String name, NameMatcher excluder, AVMNodeDescriptor srcDesc, AVMNodeDescriptor dstDesc, - boolean ignoreConflicts, boolean ignoreOlder, boolean overrideConflicts, boolean overrideOlder) - { - // Dispatch. - switch (diffCode) - { - case AVMDifference.SAME : - { - // Nada to do. - return; - } - case AVMDifference.NEWER : - { - // You can't delete what isn't there. - linkIn(parentPath, name, srcDesc, excluder, dstDesc != null && !dstDesc.isDeleted(), dstDesc); - return; - } - case AVMDifference.OLDER : - { - // You can force it. - if (overrideOlder) - { - linkIn(parentPath, name, srcDesc, excluder, !dstDesc.isDeleted(), dstDesc); - return; - } - // You can ignore it. - if (ignoreOlder) - { - return; - } - // Or it's an error. - throw new AVMSyncException("Older version prevents update."); - } - case AVMDifference.CONFLICT : - { - // You can force it. - if (overrideConflicts) - { - linkIn(parentPath, name, srcDesc, excluder, true, dstDesc); - return; - } - // You can ignore it. - if (ignoreConflicts) - { - return; - } - // Or it's an error. - throw new AVMSyncException("Conflict prevents update."); - } - case AVMDifference.DIRECTORY : - { - int dirDiffCode = compareOne(srcDesc, dstDesc, true); - if (dirDiffCode == AVMDifference.DIRECTORY) - { - // error - throw new AVMSyncException("Unexpected diff code: " + dirDiffCode); - } - - dispatchUpdate(dirDiffCode, parentPath, name, excluder, srcDesc, dstDesc, - ignoreConflicts, ignoreOlder, overrideConflicts, overrideOlder); - return; - } - default : - { - throw new AVMSyncException("Invalid Difference Code " + diffCode + " - Internal Error."); - } - } - } - - /** - * Do the actual work of connecting nodes to the destination tree. - * @param parentPath The parent path the node will go in. - * @param name The name it will have. - * @param toLink The node descriptor. - * @param removeFirst Whether to do a removeNode before linking in. - */ - private void linkIn(String parentPath, String name, AVMNodeDescriptor toLink, NameMatcher excluder, boolean removeFirst, AVMNodeDescriptor dstDesc) - { - // This is a delete. - if (toLink == null) - { - try - { - fAVMService.removeNode(parentPath, name); - } - catch (AVMNotFoundException nfe) - { - // ignore - if (logger.isDebugEnabled()) - { - logger.debug("linkIn: Does not exist: "+parentPath+"/"+name); - } - } - return; - } - mkdirs(parentPath, AVMNodeConverter.SplitBase(toLink.getPath())[0]); - - if (toLink.isLayeredDirectory() && !toLink.isPrimary()) - { - // Combining the remove and add into a single update API causes all sorts of potential security issues - if (removeFirst) - { - fAVMService.removeNode(parentPath, name); - } - recursiveCopy(parentPath, name, toLink, excluder); - return; - } - - String newPath = AVMNodeConverter.ExtendAVMPath(parentPath, name); - - if (toLink.isLayeredDirectory() && - toLink.isPrimary() && - dstDesc == null && - toLink.getIndirection().equals(newPath)) - { - recursiveCopy(parentPath, name, toLink, excluder); - return; - } - - if (removeFirst) - { - if (toLink.isDirectory()) - { - // Combining the remove and add into a single update API causes all sorts of potential security issues - fAVMService.removeNode(parentPath, name); - fAVMService.link(parentPath, name, toLink); - } - else - { - // this API only requires write access to the file - fAVMService.updateLink(parentPath, name, toLink); - } - } - else - { - fAVMService.link(parentPath, name, toLink); - } - - setACL(parentPath, toLink.getPath(), newPath); - } - - /* - * Get acl - */ - private Acl getACL(String path) - { - Lookup lookup = AVMRepository.GetInstance().lookup(-1, path, false); - if (lookup != null) - { - AVMNode node = lookup.getCurrentNode(); - return node.getAcl(); - } - else - { - return null; - } - } - - /* - * Set ACL without COW - */ - private void setACL(String parentPath, String toCopyPath, String newPath) - { - Acl parentAcl= getACL(parentPath); - Acl acl = getACL(toCopyPath); - - Lookup lookup = AVMRepository.GetInstance().lookup(-1, newPath, false); - if (lookup != null) - { - AVMNode newNode = lookup.getCurrentNode(); - newNode.copyACLs(acl, parentAcl, ACLCopyMode.COPY); - - AVMDAOs.Instance().fAVMNodeDAO.update(newNode); - } - else - { - return; - } - } - - /** - * Recursively copy a node into the given position. - * @param parentPath The place to put it. - * @param name The name to give it. - * @param toCopy The it to put. - */ - private void recursiveCopy(String parentPath, String name, AVMNodeDescriptor toCopy, NameMatcher excluder) - { - fAVMService.createDirectory(parentPath, name); - String newParentPath = AVMNodeConverter.ExtendAVMPath(parentPath, name); - fAVMService.setMetaDataFrom(newParentPath, toCopy); - AVMNodeDescriptor parentDesc = fAVMService.lookup(-1, newParentPath, true); - Map children = - fAVMService.getDirectoryListing(toCopy, true); - for (Map.Entry entry : children.entrySet()) - { - recursiveCopy(parentDesc, entry.getKey(), entry.getValue(), excluder); - } - } - - /** - * Shortcutting helper that uses an AVMNodeDescriptor parent. - * @param parent The parent we are linking into. - * @param name The name to link in. - * @param toCopy The node to link in. - */ - private void recursiveCopy(AVMNodeDescriptor parent, String name, AVMNodeDescriptor toCopy, NameMatcher excluder) - { - String newPath = AVMNodeConverter.ExtendAVMPath(parent.getPath(), name); - if (excluder != null && (excluder.matches(newPath) || - excluder.matches(toCopy.getPath()))) - { - return; - } - // If it's a file or deleted simply link it in. - if (toCopy.isFile() || toCopy.isDeleted() || toCopy.isPlainDirectory()) - { - fAVMRepository.link(parent, name, toCopy); - - // needs to get the acl from the new location - setACL(parent.getPath(), toCopy.getPath(), newPath); - return; - } - // Otherwise make a directory in the target parent, and recursiveCopy all the source - // children into it. - AVMNodeDescriptor newParentDesc = fAVMRepository.createDirectory(parent, name); - fAVMService.setMetaDataFrom(newParentDesc.getPath(), toCopy); - Map children = - fAVMService.getDirectoryListing(toCopy, true); - for (Map.Entry entry : children.entrySet()) - { - recursiveCopy(newParentDesc, entry.getKey(), entry.getValue(), excluder); - } - } - - /** - * The workhorse of comparison and updating. Determine the versioning relationship - * of two nodes. - * @param srcDesc Descriptor for the source node. - * @param dstDesc Descriptor for the destination node. - * @return One of SAME, OLDER, NEWER, CONFLICT, DIRECTORY - */ - private int compareOne(AVMNodeDescriptor srcDesc, AVMNodeDescriptor dstDesc, boolean compareDir) - { - if (srcDesc == null) - { - return AVMDifference.OLDER; - } - if (srcDesc.getId() == dstDesc.getId()) - { - // Identical - return AVMDifference.SAME; - } - - // Check for mismatched fundamental types. - if ((srcDesc.isDirectory() && dstDesc.isFile()) || - (srcDesc.isFile() && dstDesc.isDirectory())) - { - if (logger.isInfoEnabled()) - { - logger.info("compareOne(1): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - - // A deleted node on either side means uniform handling because - // a deleted node can be the descendent of any other type of node. - if (srcDesc.isDeleted() || dstDesc.isDeleted()) - { - AVMNodeDescriptor common = fAVMService.getCommonAncestor(srcDesc, dstDesc); - if (common == null) - { - if (logger.isInfoEnabled()) - { - logger.info("compareOne(2): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - if (common.getId() == srcDesc.getId()) - { - return AVMDifference.OLDER; - } - if (common.getId() == dstDesc.getId()) - { - return AVMDifference.NEWER; - } - - if (common.isLayeredFile()) - { - Integer diff = compareLayeredCommonAncestor(common, srcDesc, dstDesc); - if (diff != null) - { - return diff; - } - } - - if (srcDesc.isDeleted() && - ((srcDesc.getDeletedType() == AVMNodeType.LAYERED_DIRECTORY) || (srcDesc.getDeletedType() == AVMNodeType.LAYERED_FILE))) - { - Integer diff = compareLayeredCommonAncestor(common, srcDesc, dstDesc); - if (diff != null) - { - return diff; - } - } - else if (dstDesc.isDeleted() && - ((dstDesc.getDeletedType() == AVMNodeType.LAYERED_DIRECTORY) || (dstDesc.getDeletedType() == AVMNodeType.LAYERED_FILE))) - { - Integer diff = compareLayeredCommonAncestor(common, dstDesc, srcDesc); - if (diff != null) - { - return diff; - } - } - - // Must be a conflict. - if (logger.isInfoEnabled()) - { - logger.info("compareOne(3): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - - if (srcDesc.isDirectory() && dstDesc.isDirectory()) - { - // Both source and destination are both some kind of directory. - if (! compareDir) - { - // note: the DIRECTORY difference code never gets returned to external callers of compare. - return AVMDifference.DIRECTORY; - } - else - { - // Matched directories that are not identical should be compared (initially) based on ACLs to see if they're newer, older or in conflict - - if ((srcDesc.isLayeredDirectory() && srcDesc.getIndirection().equals(dstDesc.getPath())) || - (dstDesc.isLayeredDirectory() && dstDesc.getIndirection().equals(srcDesc.getPath()))) - { - // Either: Source is a layered directory and points at the destination plain/layered directory - // Or: Destination is a layered directory and points at the source plain directory - - // Check properties (eg. title/description) - if (compareNodeProps(srcDesc, dstDesc) == AVMDifference.SAME) - { - // Check ACLs - int dirDiffCode = compareACLs(srcDesc, dstDesc); - if (dirDiffCode != AVMDifference.CONFLICT) - { - return dirDiffCode; - } - - if (logger.isInfoEnabled()) - { - logger.info("compareOne(4): conflict ["+srcDesc+","+dstDesc+"]"); - } - } - - // drop through to check common ancestor - } - - // Check common ancestor - AVMNodeDescriptor common = fAVMService.getCommonAncestor(srcDesc, dstDesc); - // Conflict case. - if (common == null) - { - if (logger.isInfoEnabled()) - { - logger.info("compareOne(5): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - if (common.getId() == srcDesc.getId()) - { - return AVMDifference.OLDER; - } - if (common.getId() == dstDesc.getId()) - { - return AVMDifference.NEWER; - } - - if (logger.isInfoEnabled()) - { - logger.info("compareOne(6): conflict ["+srcDesc+","+dstDesc+"]"); - } - // They must, finally, be in conflict. - return AVMDifference.CONFLICT; - } - } - // At this point both source and destination are both some kind of file. - if (srcDesc.isLayeredFile()) - { - // Handle the layered file source case. - if (dstDesc.isPlainFile()) - { - // We consider a layered source file that points at the destination - // file SAME. - if (srcDesc.getIndirection().equals(dstDesc.getPath())) - { - return AVMDifference.SAME; - } - - if (logger.isInfoEnabled()) - { - logger.info("compareOne(7): conflict ["+srcDesc+","+dstDesc+"]"); - } - // We know that they are in conflict since they are of different types. - return AVMDifference.CONFLICT; - } - // Destination is a layered file also. - AVMNodeDescriptor common = fAVMService.getCommonAncestor(srcDesc, dstDesc); - if (common == null) - { - if (logger.isInfoEnabled()) - { - logger.info("compareOne(8): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - if (common.getId() == srcDesc.getId()) - { - return AVMDifference.OLDER; - } - if (common.getId() == dstDesc.getId()) - { - return AVMDifference.NEWER; - } - if (logger.isInfoEnabled()) - { - logger.info("compareOne(9): conflict ["+srcDesc+","+dstDesc+"]"); - } - // Finally we know they are in conflict. - return AVMDifference.CONFLICT; - } - // Source is a plain file. - if (dstDesc.isLayeredFile()) - { - // We consider a source file that is the target of a layered destination file to be - // SAME. - if (dstDesc.getIndirection().equals(srcDesc.getPath())) - { - return AVMDifference.SAME; - } - - AVMNodeDescriptor common = fAVMService.getCommonAncestor(srcDesc, dstDesc); - if (common == null) - { - if (logger.isInfoEnabled()) - { - logger.info("compareOne(10): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - if (common.getId() == srcDesc.getId()) - { - return AVMDifference.OLDER; - } - if (common.getId() == dstDesc.getId()) - { - return AVMDifference.NEWER; - } - - if (common.isLayeredFile()) - { - Integer diff = compareLayeredCommonAncestor(common, srcDesc, dstDesc); - if (diff != null) - { - return diff; - } - } - - if (logger.isInfoEnabled()) - { - logger.info("compareOne(11): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - // Destination is a plain file. - AVMNodeDescriptor common = fAVMService.getCommonAncestor(srcDesc, dstDesc); - - // Conflict case. - if (common == null) - { - if (logger.isInfoEnabled()) - { - logger.info("compareOne(12): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - if (common.getId() == srcDesc.getId()) - { - return AVMDifference.OLDER; - } - if (common.getId() == dstDesc.getId()) - { - return AVMDifference.NEWER; - } - - if (common.isLayeredFile()) - { - Integer diff = compareLayeredCommonAncestor(common, srcDesc, dstDesc); - if (diff != null) - { - return diff; - } - } - - if (logger.isInfoEnabled()) - { - logger.info("compareOne(13): conflict ["+srcDesc+","+dstDesc+"]"); - } - // They must, finally, be in conflict. - return AVMDifference.CONFLICT; - } - - private Integer compareLayeredCommonAncestor(AVMNodeDescriptor common, AVMNodeDescriptor srcDesc, AVMNodeDescriptor dstDesc) - { - Integer diff = null; - - // check dst ancestry - diff = compareLayeredCommonAncestor(common, dstDesc.getId(), AVMDifference.NEWER); - if (diff == null) - { - // check src ancestry - diff = compareLayeredCommonAncestor(common, srcDesc.getId(), AVMDifference.OLDER); - } - - return diff; - } - - private Integer compareLayeredCommonAncestor(AVMNodeDescriptor common, long compareNodeId, int diffType) - { - Integer diff = null; - - AVMNode compareAncNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(compareNodeId).getAncestor(); - if (compareAncNode != null) - { - if (common.getId() == compareAncNode.getId()) - { - diff = diffType; - } - else if (common.isLayeredFile() || (compareAncNode.getType() == AVMNodeType.LAYERED_FILE)) - { - // TODO review (alongside createSnapshot+COW) - diff = compareLayeredCommonAncestor(common, compareAncNode.getId(), diffType); - } - } - - return diff; - } - - // compare node properties - private int compareNodeProps(AVMNodeDescriptor srcDesc, AVMNodeDescriptor dstDesc) - { - Map srcProps = fAVMService.getNodeProperties(srcDesc); - Map dstProps = fAVMService.getNodeProperties(dstDesc); - - if (srcProps.size() == dstProps.size()) - { - for (Map.Entry srcEntry : srcProps.entrySet()) - { - PropertyValue srcValue = srcEntry.getValue(); - PropertyValue dstValue = dstProps.get(srcEntry.getKey()); - if ((srcValue == null) && (dstValue == null)) - { - continue; - } - else if ((srcValue != null) && (dstValue != null) && - (srcValue.equals(dstValue))) - { - continue; - } - else - { - if (logger.isInfoEnabled()) - { - logger.info("compareNodeProps(1): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - } - - return AVMDifference.SAME; - } - - if (logger.isInfoEnabled()) - { - logger.info("compareNodeProps(2): conflict ["+srcDesc+","+dstDesc+"]"); - } - return AVMDifference.CONFLICT; - } - - // compare ACLs - private int compareACLs(AVMNodeDescriptor srcDesc, AVMNodeDescriptor dstDesc) - { - Acl srcAcl = getACL(srcDesc.getPath()); - Acl dstAcl = getACL(dstDesc.getPath()); - - if ((srcAcl == null) && (dstAcl == null)) - { - return AVMDifference.SAME; - } - else if (srcAcl != null) - { - if ((dstAcl != null) && (srcAcl.getAclId() == dstAcl.getAclId())) - { - return AVMDifference.SAME; - } - - if (srcAcl.getAclType().equals(ACLType.LAYERED)) - { - if ((dstAcl == null) || dstAcl.getAclType().equals(ACLType.SHARED) || dstAcl.getAclType().equals(ACLType.LAYERED) || dstAcl.getAclType().equals(ACLType.DEFINING)) - { - return AVMDifference.SAME; - } - else - { - // TODO review - throw new AVMSyncException("srcAcl type: " + srcAcl.getAclType() + ", unexpected dstAcl type: " + dstAcl.getAclType()); - } - } - else if (srcAcl.getAclType().equals(ACLType.DEFINING)) - { - if ((dstAcl == null) || dstAcl.getAclType().equals(ACLType.SHARED) || dstAcl.getAclType().equals(ACLType.LAYERED)) - { - return AVMDifference.NEWER; - } - else if (dstAcl.getAclType().equals(ACLType.DEFINING)) - { - boolean same = compareACEs(srcDesc, dstDesc); - if (same) - { - return AVMDifference.SAME; - } - } - else - { - // TODO review - throw new AVMSyncException("srcAcl type: " + srcAcl.getAclType() + ", unexpected dstAcl type: " + dstAcl.getAclType()); - } - } - else if (srcAcl.getAclType().equals(ACLType.SHARED)) - { - if ((dstAcl == null) || dstAcl.getAclType().equals(ACLType.SHARED)) - { - boolean same = compareACEs(srcDesc, dstDesc); - if (same) - { - return AVMDifference.SAME; - } - } - else - { - // TODO review - throw new AVMSyncException("srcAcl type: " + srcAcl.getAclType() + ", unexpected dstAcl type: " + dstAcl.getAclType()); - } - } - } - else if (srcAcl == null) - { - if (dstAcl != null) - { - return AVMDifference.SAME; - } - } - - if (logger.isInfoEnabled()) - { - logger.info("compareACLs: conflict ["+srcDesc+","+dstDesc+"]"); - } - - return AVMDifference.CONFLICT; - } - - private boolean compareACEs(AVMNodeDescriptor srcDesc, AVMNodeDescriptor dstDesc) - { - boolean same = false; - - NodeRef srcNodeRef = AVMNodeConverter.ToNodeRef(-1, srcDesc.getPath()); - Set srcSet = fPermissionService.getAllSetPermissions(srcNodeRef); - - NodeRef dstNodeRef = AVMNodeConverter.ToNodeRef(-1, dstDesc.getPath()); - Set dstSet = fPermissionService.getAllSetPermissions(dstNodeRef); - - if (srcSet.size() == dstSet.size()) - { - same = true; - for (AccessPermission srcPerm : srcSet) - { - boolean found = false; - for (AccessPermission dstPerm : dstSet) - { - if (compareAccessPermission(srcPerm, dstPerm)) - { - found = true; - break; - } - } - if (! found) - { - same = false; - break; - } - } - } - - return same; - } - - private boolean compareAccessPermission(AccessPermission srcPerm, AccessPermission dstPerm) - { - // TODO: currently ignores position (refer to updated AccessPermissionImpl.equals) - if (srcPerm == dstPerm) - { - return true; - } - if (srcPerm == null) - { - return false; - } - - if (srcPerm.getAccessStatus() == null) - { - if (dstPerm.getAccessStatus() != null) - { - return false; - } - } - else if (! srcPerm.getAccessStatus().equals(dstPerm.getAccessStatus())) - { - return false; - } - - if (srcPerm.getAuthority() == null) - { - if (dstPerm.getAuthority() != null) - { - return false; - } - } - else if (! srcPerm.getAuthority().equals(dstPerm.getAuthority())) - { - return false; - } - - if (srcPerm.getPermission() == null) - { - if (dstPerm.getPermission() != null) - { - return false; - } - } - else if (! srcPerm.getPermission().equals(dstPerm.getPermission())) - { - return false; - } - - return true; - } - - /** - * Flattens a layer so that all all nodes under and including - * layerPath become translucent to any nodes in the - * corresponding location under and including underlyingPath - * that are the same version. - * @param layerPath The overlying layer path. - * @param underlyingPath The underlying path. - */ - public void flatten(String layerPath, String underlyingPath) - { - long start = System.currentTimeMillis(); - - if (layerPath == null || underlyingPath == null) - { - throw new AVMBadArgumentException("Illegal null path."); - } - AVMNodeDescriptor layerNode = fAVMService.lookup(-1, layerPath, true); - if (layerNode == null) - { - throw new AVMNotFoundException("Not found: " + layerPath); - } - AVMNodeDescriptor underlyingNode = fAVMService.lookup(-1, underlyingPath, true); - if (underlyingNode == null) - { - throw new AVMNotFoundException("Not found: " + underlyingPath); - } - - flatten(layerNode, underlyingNode); - - if (logger.isDebugEnabled()) - { - logger.debug("Raw flatten: " + layerNode + " " + underlyingNode + " in " + (System.currentTimeMillis() - start) + " msecs"); - } - } - - /** - * This is the implementation of flatten. - * @param layer The on top node. - * @param underlying The underlying node. - */ - private boolean flatten(AVMNodeDescriptor layer, AVMNodeDescriptor underlying) - { - if (logger.isDebugEnabled()) - { - logger.debug("flatten: " + layer + " " + underlying); - } - if (!layer.isLayeredDirectory()) - { - return false; - } - // layer and underlying must match for flattening to be useful. - if (!layer.getIndirection().equalsIgnoreCase(underlying.getPath())) - { - return false; - } - // The underlying thing must be a directory. - if (!underlying.isDirectory()) - { - return false; - } - - Map layerListing = - fAVMService.getDirectoryListingDirect(-1, layer.getPath(), true); - // If the layer is empty (directly, that is) we're done. - if (layerListing.size() == 0) - { - return true; - } - - // Grab the listing - Map underListing = - fAVMService.getDirectoryListing(underlying, true); - - boolean flattened = true; - for (String name : layerListing.keySet()) - { - AVMNodeDescriptor topNode = layerListing.get(name); - AVMNodeDescriptor bottomNode = underListing.get(name); - - if (logger.isTraceEnabled()) - { - logger.trace("Trying to flatten out: " + name); - } - - if (bottomNode == null) - { - if (logger.isTraceEnabled()) - { - logger.trace("Can't flatten (no bottomNode): " + name); - } - - flattened = false; - continue; - } - // We've found an identity so flatten it. - if (topNode.getId() == bottomNode.getId()) - { - fAVMRepository.flatten(layer.getPath(), name); - - if (logger.isTraceEnabled()) - { - logger.trace("Identity flattened: " + name); - } - } - else - { - if (bottomNode.isLayeredDirectory()) - { - AVMNodeDescriptor lookup = fAVMService.lookup(bottomNode.getIndirectionVersion(), bottomNode.getIndirection()); - if (lookup == null) - { - if (logger.isDebugEnabled()) - { - logger.debug("Can't flatten (no bottomNode indirection): " + name); - } - - flattened = false; - continue; - } - } - - // Otherwise recursively flatten the children. - if (flatten(topNode, bottomNode)) - { - fAVMRepository.flatten(layer.getPath(), name); - - if (logger.isTraceEnabled()) - { - logger.trace("Recursively flattened: " + name); - } - } - else - { - flattened = false; - } - } - } - return flattened; - } - - /** - * Takes a layer, deletes it and recreates it pointing at the same underlying - * node. Any changes in the layer are lost (except to history if the layer has been - * snapshotted.) - * - * NB: fixed to respect permissions and allow reset end preview sandboxes by finding all direct children and flattening - * - * @param layerPath - */ - public void resetLayer(String layerPath) - { - long start = System.currentTimeMillis(); - - AVMNodeDescriptor desc = fAVMService.lookup(-1, layerPath); - if (desc == null) - { - throw new AVMNotFoundException("Not Found: " + layerPath); - } - Map layerListing = - fAVMService.getDirectoryListingDirect(-1, layerPath, true); - for (String name : layerListing.keySet()) - { - fAVMRepository.flatten(layerPath, name); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Raw resetLayer: " + layerPath + " in " + (System.currentTimeMillis() - start) + " msecs"); - } - } - - /** - * Make sure this entire directory path exists. - * @param path - * @param sourcePath - */ - private void mkdirs(String path, String sourcePath) - { - if (fAVMService.lookup(-1, path) != null) - { - return; - } - String [] pathParts = AVMNodeConverter.SplitBase(path); - if (pathParts[0] == null) - { - // This is a root path and as such has to exist. - // Something else is going on. - throw new AVMSyncException("No corresponding destination path: " + path); - } - mkdirs(pathParts[0], AVMNodeConverter.SplitBase(sourcePath)[0]); - fAVMService.createDirectory(pathParts[0], pathParts[1]); - fAVMService.setMetaDataFrom(path, fAVMService.lookup(-1, sourcePath)); - } -} diff --git a/source/java/org/alfresco/repo/avm/AVMSyncServiceNOOPImpl.java b/source/java/org/alfresco/repo/avm/AVMSyncServiceNOOPImpl.java new file mode 100644 index 0000000000..5e224508d5 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMSyncServiceNOOPImpl.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2005-2013 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . */ + +package org.alfresco.repo.avm; + +import java.util.List; + +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.util.NameMatcher; + +//Sparta: disable WCM/AVM - temporary (until WCM/AVM has been fully removed) +public class AVMSyncServiceNOOPImpl implements AVMSyncService +{ + /** + * Basic constructor for the service. + */ + public AVMSyncServiceNOOPImpl() + { + } + + @Override + public List compare(int srcVersion, String srcPath, + int dstVersion, String dstPath, NameMatcher excluder) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public List compare(int srcVersion, String srcPath, + int dstVersion, String dstPath, NameMatcher excluder, + boolean expandDirs) + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void update(List diffList, NameMatcher excluder, + boolean ignoreConflicts, boolean ignoreOlder, + boolean overrideConflicts, boolean overrideOlder, String tag, + String description) + { + // TODO Auto-generated method stub + + } + + @Override + public void flatten(String layerPath, String underlyingPath) + { + // TODO Auto-generated method stub + + } + + @Override + public void resetLayer(String layerPath) + { + // TODO Auto-generated method stub + + } +} diff --git a/source/java/org/alfresco/repo/avm/AvmBootstrap.java b/source/java/org/alfresco/repo/avm/AvmBootstrap.java deleted file mode 100644 index 23e7095951..0000000000 --- a/source/java/org/alfresco/repo/avm/AvmBootstrap.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - -import java.util.List; - -import org.alfresco.service.cmr.security.PermissionService; -import org.springframework.extensions.surf.util.AbstractLifecycleBean; -import org.springframework.context.ApplicationEvent; - -/** - * This component ensures that the AVM system is properly bootstrapped - * and that this is done in the correct order relative to other - * bootstrap components. - * - * @see #setIssuers(List) - * @see org.alfresco.repo.avm.Issuer - * - * @author Derek Hulley - */ -public class AvmBootstrap extends AbstractLifecycleBean -{ - private AVMLockingAwareService avmLockingAwareService; - - private AVMRepository avmRepository; - - private PermissionService permissionService; - - private AVMSyncServiceImpl avmSyncService; - - - public AvmBootstrap() - { - } - - public void setAvmLockingAwareService(AVMLockingAwareService service) - { - avmLockingAwareService = service; - } - - public void setAvmRepository(AVMRepository repository) - { - avmRepository = repository; - } - - public void setPermissionService(PermissionService service) - { - permissionService = service; - } - - public void setAvmSyncService(AVMSyncServiceImpl service) - { - avmSyncService = service; - } - - /** - * Initialize the issuers. - */ - @Override - protected void onBootstrap(ApplicationEvent event) - { - avmLockingAwareService.init(); - avmRepository.setPermissionService(permissionService); - avmSyncService.setPermissionService(permissionService); - } - - /** NO-OP */ - @Override - protected void onShutdown(ApplicationEvent event) - { - // Nothing - } -} diff --git a/source/java/org/alfresco/repo/avm/ChildEntry.java b/source/java/org/alfresco/repo/avm/ChildEntry.java deleted file mode 100644 index f6d2365ba8..0000000000 --- a/source/java/org/alfresco/repo/avm/ChildEntry.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -/** - * This interface represents an entry in a directory. - * @author britt - */ -public interface ChildEntry -{ - /** - * Set the key for this ChildEntry. - * @param key The ChildKey. - */ - public void setKey(ChildKey key); - - /** - * Get the ChildKey for this ChildEntry. - * @return - */ - public ChildKey getKey(); - - /** - * Set the child in this entry. - * @param child - */ - public void setChild(AVMNode child); - - /** - * Get the child in this entry. - * @return The child. - */ - public AVMNode getChild(); -} diff --git a/source/java/org/alfresco/repo/avm/ChildEntryDAO.java b/source/java/org/alfresco/repo/avm/ChildEntryDAO.java deleted file mode 100644 index 7d0de0aef7..0000000000 --- a/source/java/org/alfresco/repo/avm/ChildEntryDAO.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.List; - -/** - * DAO for ChildEntries. - * @author britt - */ -public interface ChildEntryDAO -{ - /** - * Save an unsaved ChildEntry. - * @param entry The entry to save. - */ - public void save(ChildEntry entry); - - /** - * Get an entry by name and parent. - * @param name The name of the child to find. - * @param parent The parent to look in. - * @return The ChildEntry or null if not foun. - */ - public ChildEntry get(ChildKey key); - - /** - * Get all the children of a given parent. - * @param parent The parent. - * @param childNamePattern - achild name pattern to match - null is supported for match all - * @return A List of ChildEntries. - */ - public List getByParent(DirectoryNode parent, String childNamePattern); - - /** - * Does the entry exist for a given child in a given parent. - * @param parent The parent. - * @param child The child. - * @return True if it exists - */ - public boolean existsParentChild(DirectoryNode parent, AVMNode child); - - /** - * Get all the ChildEntries corresponding to the given child. - * @param child The child for which to look up entries. - * @return The matching entries. - */ - public List getByChild(AVMNode child); - - /** - * Rename a child entry (specific rename 'case' only) - * @param child The one to rename. - */ - public void rename(ChildKey key, String newName); - - /** - * Delete one. - * @param child The one to delete. - */ - public void delete(ChildEntry child); - - /** - * Delete all children of the given parent. - * @param parent The parent. - */ - public void deleteByParent(AVMNode parent); - - /** - * Evict a child entry. - * @param entry - * - * @deprecated - */ - public void evict(ChildEntry entry); -} diff --git a/source/java/org/alfresco/repo/avm/ChildEntryImpl.java b/source/java/org/alfresco/repo/avm/ChildEntryImpl.java deleted file mode 100644 index d445631d3a..0000000000 --- a/source/java/org/alfresco/repo/avm/ChildEntryImpl.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - - -/** - * An entry in a directory. Contains a name, parent, and child. - * @author britt - */ -public class ChildEntryImpl implements ChildEntry -{ - /** - * The key. - */ - private ChildKey fKey; - - /** - * The child. - */ - private AVMNode fChild; - - /** - * Default constructor for Hibernate. - */ - public ChildEntryImpl() - { - } - - /** - * Make up a brand new entry. - * @param key The ChildKey. - * @param child The child. - */ - public ChildEntryImpl(ChildKey key, - AVMNode child) - { - fKey = key; - fChild = child; - } - - /** - * Set the key for this ChildEntry. - * @param key The ChildKey. - */ - public void setKey(ChildKey key) - { - fKey = key; - } - - /** - * Get the ChildKey for this ChildEntry. - * @return - */ - public ChildKey getKey() - { - return fKey; - } - - /** - * Set the child in this entry. - * @param child - */ - public void setChild(AVMNode child) - { - fChild = child; - } - - /** - * Get the child in this entry. - * @return The child. - */ - public AVMNode getChild() - { - return fChild; - } - - /** - * Equals override. - * @param obj - * @return Equality. - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (!(obj instanceof ChildEntry)) - { - return false; - } - ChildEntry other = (ChildEntry)obj; - return fKey.equals(other.getKey()); - } - - /** - * Get the hash code. - * @return The hash code. - */ - @Override - public int hashCode() - { - return fKey.hashCode(); - } -} diff --git a/source/java/org/alfresco/repo/avm/ChildKey.java b/source/java/org/alfresco/repo/avm/ChildKey.java deleted file mode 100644 index 76e0f6fabe..0000000000 --- a/source/java/org/alfresco/repo/avm/ChildKey.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import java.io.Serializable; - -/** - * The key to a ChildEntry, a Parent and a name. - * @author britt - */ -public class ChildKey implements Serializable -{ - private static final long serialVersionUID = 2033634095972856432L; - - /** - * The Parent. - */ - private DirectoryNode fParent; - - /** - * The child's name. - */ - private String fName; - - /** - * Construct one with parameters. - * @param parent The parent directory. - * @param name The name of the child. - */ - public ChildKey(DirectoryNode parent, String name) - { - fParent = parent; - fName = name; - } - - /** - * A Default Constructor. - */ - public ChildKey() - { - } - - /** - * Set the parent. - */ - public void setParent(DirectoryNode parent) - { - fParent = parent; - } - - /** - * Get the parent. - * @return A DirectoryNode. - */ - public DirectoryNode getParent() - { - return fParent; - } - - /** - * Set the name. - */ - public void setName(String name) - { - fName = name; - } - - /** - * Get the name. - */ - public String getName() - { - return fName; - } - - /** - * Override of equals. - */ - @Override - public boolean equals(Object other) - { - if (this == other) - { - return true; - } - if (!(other instanceof ChildKey)) - { - return false; - } - ChildKey o = (ChildKey)other; - return fParent.equals(o.getParent()) && - fName.equalsIgnoreCase(o.getName()); - } - - /** - * Override of hashCode. - */ - public int hashCode() - { - return fParent.hashCode() + fName.toLowerCase().hashCode(); - } -} diff --git a/source/java/org/alfresco/repo/avm/DeletedNode.java b/source/java/org/alfresco/repo/avm/DeletedNode.java deleted file mode 100644 index 890a3d289d..0000000000 --- a/source/java/org/alfresco/repo/avm/DeletedNode.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -/** - * Represents a node that has been deleted. - * @author britt - */ -public interface DeletedNode extends AVMNode -{ - /** - * Get the type of node that this is a deleted placeholder for - * @return The type of node that was deleted. - */ - public int getDeletedType(); -} diff --git a/source/java/org/alfresco/repo/avm/DeletedNodeImpl.java b/source/java/org/alfresco/repo/avm/DeletedNodeImpl.java deleted file mode 100644 index 9a08ee9b5b..0000000000 --- a/source/java/org/alfresco/repo/avm/DeletedNodeImpl.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; - -/** - * Place holder for a deleted node. - * @author britt - */ -public class DeletedNodeImpl extends AVMNodeImpl implements DeletedNode -{ - private static final long serialVersionUID = 7283526790174482993L; - - /** - * The type of node that this is a deleted node for. - */ - private int fDeletedType; - - /** - * Default constructor. - */ - public DeletedNodeImpl() - { - } - - /** - * Create a new one from scratch. - * @param store The store it's being created in. - */ - public DeletedNodeImpl(AVMStore store, Acl acl) - { - super(store); - this.setAcl(acl); - } - - public DeletedNodeImpl(DeletedNode other, - AVMStore store, Long parentAcl, ACLCopyMode mode) - { - super(store); - - setDeletedType(other.getDeletedType()); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - } - - /** - * Setter. - */ - public void setDeletedType(int type) - { - fDeletedType = type; - } - - /** - * Getter. - */ - public int getDeletedType() - { - return fDeletedType; - } - - // TODO What happens when this is called? Does it muck anything up. - /** - * This is only called rarely. - */ - public AVMNode copy(Lookup lPath) - { - DirectoryNode dir = lPath.getCurrentNodeDirectory(); - Long parentAclId = null; - if((dir != null) && (dir.getAcl() != null)) - { - parentAclId = dir.getAcl().getId(); - } - AVMNode newMe = new DeletedNodeImpl(this, lPath.getAVMStore(), parentAclId, ACLCopyMode.COPY); - newMe.setAncestor(this); - return newMe; - } - - /** - * Get a descriptor. - * @param lPath The Lookup to this node's parent. - * @param name The name of this node. - * @return An AVMNodeDescriptor - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath, String name) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - if (path.endsWith("/")) - { - path = path + name; - } - else - { - path = path + "/" + name; - } - return new AVMNodeDescriptor(path, - name, - AVMNodeType.DELETED_NODE, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - -1, - getDeletedType()); - } - - /** - * Get a descriptor. - * @param lPath The full Lookup to this. - * @return An AVMNodeDescriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - return new AVMNodeDescriptor(path, - path.substring(path.lastIndexOf("/") + 1), - AVMNodeType.DELETED_NODE, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - -1, - getDeletedType()); - } - - /** - * Get a descriptor. - * @param parentPath - * @param name - * @param parentIndirection Ignored. - * @return An AVMNodeDescriptor. - */ - public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion) - { - BasicAttributes attrs = getBasicAttributes(); - String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name; - return new AVMNodeDescriptor(path, - name, - AVMNodeType.DELETED_NODE, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - -1, - getDeletedType()); - } - - /** - * Get the type of this node. - * @return The AVMNodeType of this. - */ - public int getType() - { - return AVMNodeType.DELETED_NODE; - } - - /** - * Get a descriptive string representation. - * @param lPath The lookup we've been found through. - * @return A String representation. - */ - public String toString(Lookup lPath) - { - return "[DN:" + getId() + "]"; - } -} diff --git a/source/java/org/alfresco/repo/avm/DirectoryNode.java b/source/java/org/alfresco/repo/avm/DirectoryNode.java deleted file mode 100644 index 2d51d7be3d..0000000000 --- a/source/java/org/alfresco/repo/avm/DirectoryNode.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import java.util.List; -import java.util.Map; -import java.util.SortedMap; - -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.util.Pair; - -/** - * The interface for Directory Nodes. - * @author britt - */ -public interface DirectoryNode extends AVMNode -{ - /** - * Does this directory directly contain the specified node. - * @param node The node to check. - * @return Whether it does. - */ - public boolean directlyContains(AVMNode node); - - /** - * Put child into this directory directly. No copy on write. - * @param name The name to give it. - * @param node The child. - */ - public void putChild(String name, AVMNode node); - - /** - * Lookup a child node. - * @param lPath The Lookup so far. - * @param name The name of the child to lookup. - * @param includeDeleted Include deleted nodes or not. - */ - public Pair lookupChild(Lookup lPath, String name, boolean includeDeleted); - - /** - * Lookup a child entry. - * @param lPath The Lookup so far. - * @param name The name of the child to lookup. - * @param includeDeleted Include deleted nodes or not. - */ - public Pair lookupChildEntry(Lookup lPath, String name, boolean includeDeleted); - - /** - * Lookup a child node using an AVMNodeDescriptor as context. - * @param mine The node descriptor for this. - * @param name The name of the child to lookup. - * @return The descriptor for the looked up child. - */ - public AVMNodeDescriptor lookupChild(AVMNodeDescriptor mine, String name, boolean includeDeleted); - - /** - * Remove a child directly. No copy is possible. - * @param lPath The lookup through which this node was reached. - * @param name The name of the child to remove. - */ - public void removeChild(Lookup lPath, String name); - - /** - * Get a directory listing. - * @param lPath The lookup context. - * @return A SortedMap of names to DirectoryEntries. - */ - public Map getListing(Lookup lPath, boolean includeDeleted); - - /** - * Get a directory listing. - * @param lPath The lookup context. - * @return A SortedMap of names to DirectoryEntries. - */ - public Map getListing(Lookup lPath, String childNamePattern, boolean includeDeleted); - - /** - * Get a listing of the nodes directly contained by a directory. - * @param lPath The Lookup to this directory. - * @return A Map of names to nodes. - */ - public Map getListingDirect(Lookup lPath, boolean includeDeleted); - - /** - * Get a listing of nodes directly contained by a directory. - * @param dir The descriptor for the directory. - * @param includeDeleted Whether to include deleted nodes. - * @return A Map of Strings to descriptors. - */ - public SortedMap getListingDirect(AVMNodeDescriptor dir, - boolean includeDeleted); - - /** - * Get a listing from a directory specified by an AVMNodeDescriptor. - * @param dir The directory to list. - * @return A Map of names to node descriptors - */ - public SortedMap getListing(AVMNodeDescriptor dir, - boolean includeDeleted); - - /** - * Get a listing from a directory specified by an AVMNodeDescriptor. - * @param dir The directory to list. - * @param childNamePattern - child name pattern to match - * @param includeDeleted = include deleted children - * @return A Map of names to node descriptors - */ - public SortedMap getListing(AVMNodeDescriptor dir, - String childNamePattern, - boolean includeDeleted); - - /** - * Get the names of nodes deleted in this directory. - * @return A List of names. - */ - public List getDeletedNames(); - - /** - * Set the directory, which must be in a layer, into a primary - * indirection taking its indirection from the Lookup. - * @param lPath The Lookup. - */ - public void turnPrimary(Lookup lPath); - - /** - * Retarget a layered directory. - * @param lPath The Lookup. - * @param target The target path. - */ - public void retarget(Lookup lPath, String target); - - /** - * Set whether this node is a root node. - * @param isRoot - */ - public void setIsRoot(boolean isRoot); - - /** - * Link a node with the given id into this directory. - * @param lPath The Lookup for this node. - * @param name The name to give the node. - * @param toLink The node to link in. - */ - public void link(Lookup lPath, String name, AVMNodeDescriptor toLink); - - /** - * Dangerous version of link that assumes that a child node of - * the given name does not already exist. - * @param name The name to give the child. - * @param toLink The child to link in. - */ - public void link(String name, AVMNodeDescriptor toLink); -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java deleted file mode 100644 index 0ae6127a1f..0000000000 --- a/source/java/org/alfresco/repo/avm/DirectoryNodeImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.util.Pair; - -/** - * Base class for Directories. - * @author britt - */ -public abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode -{ - /** - * Default constructor. - */ - protected DirectoryNodeImpl() - { - } - - /** - * A pass through constructor. Called when a new concrete subclass - * instance is created. - * @param repo - */ - protected DirectoryNodeImpl(AVMStore repo) - { - super(repo); - } - - /** - * Dangerous version of link. - * @param name The name to give the child. - * @param toLink The child to link in. - */ - public void link(String name, AVMNodeDescriptor toLink) - { - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(toLink.getId()); - if (node == null) - { - throw new AVMNotFoundException("Child node not found."); - } - if (node.getType() == AVMNodeType.LAYERED_DIRECTORY && - !((LayeredDirectoryNode)node).getPrimaryIndirection()) - { - throw new AVMBadArgumentException("Non primary layered directories cannot be linked."); - } - // Make the new ChildEntry and save. - ChildKey key = new ChildKey(this, name); - ChildEntry newChild = new ChildEntryImpl(key, node); - AVMDAOs.Instance().fChildEntryDAO.save(newChild); - } - - /** - * Does this node directly contain the indicated node. - * - * @param node - * The node we are checking. - * @return Whether node is directly contained. - */ - public boolean directlyContains(AVMNode node) - { - return AVMDAOs.Instance().fChildEntryDAO.existsParentChild(this, node); - } - - /** - * Lookup a child node by name. - * @param lPath The lookup path so far. - * @param name The name to lookup. - * @param includeDeleted Whether to lookup deleted nodes. - * @return The child node or null. - */ - public Pair lookupChild(Lookup lPath, String name, boolean includeDeleted) - { - Pair result = lookupChildEntry(lPath, name, includeDeleted); - if (result == null) - { - return null; - } - return new Pair(result.getFirst().getChild(), result.getSecond()); - } -} diff --git a/source/java/org/alfresco/repo/avm/FileNode.java b/source/java/org/alfresco/repo/avm/FileNode.java deleted file mode 100644 index 9c15e1bbaf..0000000000 --- a/source/java/org/alfresco/repo/avm/FileNode.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import org.alfresco.service.cmr.repository.ContentData; - -/** - * Interface for the generic idea of a file. - * @author britt - */ -public interface FileNode extends AVMNode -{ - /** - * Set the ContentData for this file. - * @param contentData The value to set. - */ - public void setContentData(ContentData contentData); - - /** - * Get the ContentData for this file. - * @param lPath The Lookup used to get here. - * @return The ContentData object for this file. - */ - public ContentData getContentData(Lookup lPath); -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/FileNodeImpl.java b/source/java/org/alfresco/repo/avm/FileNodeImpl.java deleted file mode 100644 index 7907fa8e6f..0000000000 --- a/source/java/org/alfresco/repo/avm/FileNodeImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - - -/** - * Base class for file objects. - * @author britt - */ -abstract class FileNodeImpl extends AVMNodeImpl implements FileNode -{ - /** - * Default constructor. - */ - protected FileNodeImpl() - { - } - - /** - * Pass through constructor. - * @param store The AVMStore we belong to. - */ - public FileNodeImpl(AVMStore store) - { - super(store); - } -} diff --git a/source/java/org/alfresco/repo/avm/Layered.java b/source/java/org/alfresco/repo/avm/Layered.java deleted file mode 100644 index 74d8a79eca..0000000000 --- a/source/java/org/alfresco/repo/avm/Layered.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -/** - * Layered nodes share these methods. - * @author britt - */ -public interface Layered extends AVMNode -{ - /** - * Get the indirection, or underlying path that this - * node points to. - * @param lookup The lookup path. Needed for most nodes to determine - * underlying path. - * @return The underlying indirection. - */ - public String getUnderlying(Lookup lookup); - - /** - * Get the indirection version. - * @param lookup The lookup path. - * @return The underlying indirection version. - */ - public int getUnderlyingVersion(Lookup lookup); - - /** - * Get the raw indirection of a layered node. - * @return The raw indirection, which will be null for - * LayeredDirectoryNodes that are not primary indirections. - */ - public String getIndirection(); - - /** - * Set the indirection version for this layered node. - * @param version The indirection version to set. - */ - public void setIndirectionVersion(Integer version); -} diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java deleted file mode 100644 index 99354222fd..0000000000 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - -import org.alfresco.repo.domain.permissions.Acl; - -/** - * Interface for Layered Directories. - * @author britt - */ -public interface LayeredDirectoryNode extends DirectoryNode, Layered -{ - /** - * Does this node have a primary indirection. - * @return Whether this is a primary indirection. - */ - public boolean getPrimaryIndirection(); - - /** - * Set whether this has a primary indirection. - * @param has Whether this has a primary indirection. - */ - public void setPrimaryIndirection(boolean has); - - /** - * Get the layer id for this node. - * @return The layer id. - */ - public long getLayerID(); - - /** - * Set the layer id for this node. - * @param id The id to set. - */ - public void setLayerID(long id); - - /** - * Set this to be a primary indirection from the path - * passed in. - * @param path The indirection path. - */ - public void rawSetPrimary(Lookup lPath, String path); - - /** - * Turn this node into a primary indirection node with the indirection - * taken from the Lookup passed in. - * Performs a copy on write. - * @param lPath - */ - public void turnPrimary(Lookup lPath); - - /** - * Retarget this directory. - * @param lPath The Lookup. - * @param target The new target path. - */ - public void retarget(Lookup lPath, String target); - - /** - * Make visible a node deleted in a layer. - * @param lPath The Lookup. - * @param name The name to make visible. - */ - public void uncover(Lookup lPath, String name); - - /** - * Remove name without leaving behind a deleted node. - * @param name The name of the child to flatten. - */ - public void flatten(String name); - - /** - * Set the indirection. - * @param indirection - */ - public void setIndirection(String indirection); - - /** - * Get the indirection version. - * @return The indirection version. - */ - public Integer getIndirectionVersion(); - - /** - * Set the opacity of this. - * @param opacity Whether this should be opaque, i.e. not see the things it - * in its indirection. - */ - public void setOpacity(boolean opacity); - - /** - * Get the opacity of this. - * @return The opacity. - */ - public boolean getOpacity(); - - public void setAclAndInherit(LayeredDirectoryNode layeredDirectory, Acl acl, String name); -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java deleted file mode 100644 index 4f62cc45dc..0000000000 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java +++ /dev/null @@ -1,1275 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.repo.security.permissions.ACLType; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.util.Pair; - -/** - * A layered directory node. A layered directory node points at an underlying directory, which may or may not exist. The - * visible contents of a layered directory node is the contents of the underlying node pointed at plus those nodes added - * to or modified in the layered directory node minus those nodes which have been deleted in the layered directory node. - * - * @author britt - */ -public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirectoryNode -{ - static final long serialVersionUID = 4623043057918181724L; - - /** - * The layer id. - */ - private long fLayerID; - - /** - * The pointer to the underlying directory. - */ - private String fIndirection; - - /** - * Whether this is a primary indirection node. - */ - private boolean fPrimaryIndirection; - - /** - * Whether this is opaque. - */ - private boolean fOpacity; - - /** - * The indirection version. - */ - private int fIndirectionVersion; - - /** - * Default constructor. - */ - public LayeredDirectoryNodeImpl() - { - } - - /** - * Make a new one from a specified indirection path. - * - * @param indirection - * The indirection path to set. - * @param store - * The store that owns this node. - */ - public LayeredDirectoryNodeImpl(String indirection, AVMStore store, AVMNode toCopy, Long parentAcl, ACLCopyMode mode) - { - super(store); - - setLayerID(-1); - setIndirection(indirection); - setIndirectionVersion(-1); - setPrimaryIndirection(true); - setOpacity(false); - - if (toCopy != null) - { - setVersionID(toCopy.getVersionID() + 1); - - copyACLs(toCopy, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(toCopy); - } - else - { - setVersionID(1); - - if (indirection != null) - { - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, indirection); - if (lookup != null) - { - DirectoryNode dir = (DirectoryNode) lookup.getCurrentNode(); - if (dir.getAcl() != null) - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(dir.getAcl().getId())); - } - else - { - // TODO: Will not pick up changes if we start with no permission on the target node - may need - // to add - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(null)); - } - } - else - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(null)); - } - } - else - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(null)); - } - } - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - if (toCopy != null) - { - copyProperties(toCopy); - copyAspects(toCopy); - } - } - - /** - * Kind of copy constructor, sort of. - * - * @param other - * The LayeredDirectoryNode we are copied from. - * @param repos - * The AVMStore object we use. - */ - public LayeredDirectoryNodeImpl(LayeredDirectoryNode other, AVMStore repos, Lookup lookup, boolean copyAll, Long parentAcl, ACLCopyMode mode) - { - super(repos); - - setLayerID(-1); - setIndirection(other.getIndirection()); - setIndirectionVersion(-1); - setPrimaryIndirection(other.getPrimaryIndirection()); - setOpacity(other.getOpacity()); - - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - - Map children = null; - if (copyAll) - { - children = other.getListing(lookup, true); - } - else - { - children = other.getListingDirect(lookup, true); - } - for (Map.Entry child : children.entrySet()) - { - ChildKey key = new ChildKey(this, child.getKey()); - ChildEntry entry = new ChildEntryImpl(key, child.getValue()); - AVMDAOs.Instance().fChildEntryDAO.save(entry); - } - } - - /** - * Construct one from a PlainDirectoryNode. Called when a COW is performed in a layered context. - * - * @param other - * The PlainDirectoryNode. - * @param store - * The AVMStore we should belong to. - * @param lPath - * The Lookup object. - */ - public LayeredDirectoryNodeImpl(PlainDirectoryNode other, AVMStore store, Lookup lPath, boolean copyContents, Long parentAcl, ACLCopyMode mode) - { - super(store); - - setLayerID(-1); - setIndirection(null); - setIndirectionVersion(-1); - setPrimaryIndirection(false); - setOpacity(false); - - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - - if (copyContents) - { - for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other, null)) - { - ChildKey key = new ChildKey(this, child.getKey().getName()); - ChildEntryImpl newChild = new ChildEntryImpl(key, child.getChild()); - AVMDAOs.Instance().fChildEntryDAO.save(newChild); - } - } - } - - /** - * Create a new layered directory based on a directory we are being named from that is in not in the layer of the - * source lookup. - * - * @param dir - * The directory - * @param store - * The store - * @param srcLookup - * The source lookup. - * @param name - * The name of the target. - */ - public LayeredDirectoryNodeImpl(DirectoryNode dir, AVMStore store, Lookup srcLookup, String name, Long inheritedAcl, ACLCopyMode mode) - { - super(store); - - setLayerID(-1); - setIndirection(srcLookup.getIndirectionPath() + "/" + name); - setIndirectionVersion(-1); - setPrimaryIndirection(true); - setOpacity(false); - - setVersionID(dir.getVersionID() + 1); - - copyACLs(dir, inheritedAcl, mode); - copyCreationAndOwnerBasicAttributes(dir); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(dir); - copyAspects(dir); - - Map children = dir.getListing(srcLookup, true); - for (Map.Entry child : children.entrySet()) - { - ChildKey key = new ChildKey(this, child.getKey()); - ChildEntry entry = new ChildEntryImpl(key, child.getValue()); - AVMDAOs.Instance().fChildEntryDAO.save(entry); - } - } - - /** - * Is this a primary indirection node. - * - * @return Whether this is a primary indirection. - */ - public boolean getPrimaryIndirection() - { - return fPrimaryIndirection; - } - - /** - * Set the primary indirection state of this. - * - * @param has - * Whether this is a primary indirection node. - */ - public void setPrimaryIndirection(boolean has) - { - fPrimaryIndirection = has; - } - - /** - * Get the indirection path. - * - * @return The indirection path. - */ - public String getIndirection() - { - return fIndirection; - } - - /** - * Get the underlying path in the Lookup's context. - * - * @param lPath - * The Lookup. - * @return The underlying path. - */ - public String getUnderlying(Lookup lPath) - { - if (getPrimaryIndirection()) - { - return getIndirection(); - } - return lPath.getCurrentIndirection(); - } - - /** - * Get the underlying version in the lookup path context. - * - * @param lPath - * The Lookup. - * @return The effective underlying version. - */ - public int getUnderlyingVersion(Lookup lPath) - { - if (lPath.getVersion() == -1) - { - return -1; - } - if (getPrimaryIndirection()) - { - return getIndirectionVersion(); - } - return lPath.getCurrentIndirectionVersion(); - } - - /** - * Get the layer id. - * - * @return The layer id. - */ - public long getLayerID() - { - return fLayerID; - } - - /** - * Set the layer id. - * - * @param id - * The id to set. - */ - public void setLayerID(long id) - { - fLayerID = id; - } - - /** - * Copy on write logic. - * - * @param lPath - * @return The copy or null. - */ - public AVMNode copy(Lookup lPath) - { - DirectoryNode dir = lPath.getCurrentNodeDirectory(); - Long parentAclId = null; - if ((dir != null) && (dir.getAcl() != null)) - { - parentAclId = dir.getAcl().getId(); - } - // Capture the store. - AVMStore store = lPath.getAVMStore(); - LayeredDirectoryNodeImpl newMe = null; - if (!lPath.isInThisLayer()) - { - // This means that this is being seen indirectly through the topmost - // layer. The following creates a node that will inherit its - // indirection from its parent. - newMe = new LayeredDirectoryNodeImpl((String) null, store, this, parentAclId, ACLCopyMode.COW); - newMe.setPrimaryIndirection(false); - newMe.setLayerID(lPath.getTopLayer().getLayerID()); - } - else - { - // A simple copy is made. - newMe = new LayeredDirectoryNodeImpl(this, store, lPath, false, parentAclId, ACLCopyMode.COW); - newMe.setLayerID(getLayerID()); - } - newMe.setAncestor(this); - - AVMDAOs.Instance().fAVMNodeDAO.update(newMe); - - return newMe; - } - - /** - * Insert a child node without COW. - * - * @param name - * The name to give the child. - */ - public void putChild(String name, AVMNode node) - { - if (DEBUG) - { - checkReadOnly(); - } - ChildKey key = new ChildKey(this, name); - ChildEntry existing = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (existing != null) - { - AVMDAOs.Instance().fChildEntryDAO.delete(existing); - } - ChildEntry entry = new ChildEntryImpl(key, node); - AVMDAOs.Instance().fChildEntryDAO.save(entry); - } - - /** - * Get a listing of the virtual contents of this directory. - * - * @param lPath - * The Lookup. - * @return A Map from names to nodes. This is a sorted Map. - */ - public Map getListing(Lookup lPath, boolean includeDeleted) - { - return getListing(lPath, null, includeDeleted); - } - - /** - * Get a listing of the virtual contents of this directory. - * - * @param lPath - * The Lookup. - * @return A Map from names to nodes. This is a sorted Map. - */ - public Map getListing(Lookup lPath, String childNamePattern, boolean includeDeleted) - { - Map listing = new HashMap(); - Map baseLowerKeyName = new HashMap(); - - if (!getOpacity()) - { - // If we are not opaque, get the underlying base listing (from the thing we indirect to) - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(getUnderlyingVersion(lPath), getUnderlying(lPath)); - if (lookup != null) - { - DirectoryNode dir = (DirectoryNode) lookup.getCurrentNode(); - Map underListing = dir.getListing(lookup, childNamePattern, includeDeleted); - for (Map.Entry entry : underListing.entrySet()) - { - if (entry.getValue().getType() == AVMNodeType.LAYERED_DIRECTORY || - entry.getValue().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(lookup.getAVMStore(), entry.getValue(), PermissionService.READ_CHILDREN, false)) - { - continue; - } - } - listing.put(entry.getKey(), entry.getValue()); - baseLowerKeyName.put(entry.getKey().toLowerCase(), entry.getKey()); - } - } - } - for (ChildEntry entry : AVMDAOs.Instance().fChildEntryDAO.getByParent(this, childNamePattern)) - { - if (entry.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || - entry.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(lPath.getAVMStore(), entry.getChild(), PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) - { - continue; - } - } - if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - listing.remove(entry.getKey().getName()); - } - else - { - String keyName = baseLowerKeyName.get(entry.getKey().getName().toLowerCase()); - if (keyName != null) - { - // specific rename 'case' only - listing.remove(keyName); - } - - listing.put(entry.getKey().getName(), entry.getChild()); - } - } - return listing; - } - - /** - * Get a listing of the nodes directly contained by a directory. - * - * @param lPath - * The Lookup to this directory. - * @return A Map of names to nodes. - */ - public Map getListingDirect(Lookup lPath, boolean includeDeleted) - { - Map listing = new HashMap(); - for (ChildEntry entry : AVMDAOs.Instance().fChildEntryDAO.getByParent(this, null)) - { - if (entry.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || - entry.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(lPath != null ? lPath.getAVMStore() : null, - entry.getChild(), PermissionService.READ_CHILDREN, - lPath != null ? lPath.getDirectlyContained() : false)) - { - continue; - } - } - if (includeDeleted || entry.getChild().getType() != AVMNodeType.DELETED_NODE) - { - listing.put(entry.getKey().getName(), entry.getChild()); - } - } - return listing; - } - - /** - * Get the direct contents of this directory. - * - * @param dir - * The descriptor that describes us. - * @param includeDeleted - * Whether to inlude deleted nodes. - * @return A Map of Strings to descriptors. - */ - public SortedMap getListingDirect(AVMNodeDescriptor dir, boolean includeDeleted) - { - List children = AVMDAOs.Instance().fChildEntryDAO.getByParent(this, null); - SortedMap listing = new TreeMap(String.CASE_INSENSITIVE_ORDER); - for (ChildEntry child : children) - { - AVMNode childNode = child.getChild(); - if (childNode.getType() == AVMNodeType.LAYERED_DIRECTORY || - childNode.getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(null, childNode, PermissionService.READ_CHILDREN, false)) - { - continue; - } - } - if (!includeDeleted && childNode.getType() == AVMNodeType.DELETED_NODE) - { - continue; - } - AVMNodeDescriptor childDesc = childNode.getDescriptor(dir.getPath(), child.getKey().getName(), dir.getIndirection(), dir.getIndirectionVersion()); - listing.put(child.getKey().getName(), childDesc); - } - return listing; - } - - /** - * Get a listing from a directory node descriptor. - * - * @param dir - * The directory node descriptor. - * @param includeDeleted - * Should DeletedNodes be shown. - * @return A Map of names to node descriptors. - */ - public SortedMap getListing(AVMNodeDescriptor dir, boolean includeDeleted) - { - return getListing(dir, null, includeDeleted); - } - - /** - * Get a listing from a directory node descriptor. - * - * @param dir - * The directory node descriptor. - * @param childNamePattern - * Pattern to match for child names - may be null - * @param includeDeleted - * Should DeletedNodes be shown. - * @return A Map of names to node descriptors. - */ - public SortedMap getListing(AVMNodeDescriptor dir, String childNamePattern, boolean includeDeleted) - { - if (dir.getPath() == null || dir.getIndirection() == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - SortedMap listing = new TreeMap(String.CASE_INSENSITIVE_ORDER); - Map baseLowerKeyName = new HashMap(); - - if (!getOpacity()) - { - // If we are not opaque, get the underlying base listing (from the thing we indirect to) - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(dir.getIndirectionVersion(), dir.getIndirection()); - if (lookup != null) - { - DirectoryNode dirNode = (DirectoryNode) lookup.getCurrentNode(); - Map underListing = dirNode.getListing(lookup, childNamePattern, includeDeleted); - for (Map.Entry entry : underListing.entrySet()) - { - if (entry.getValue().getType() == AVMNodeType.LAYERED_DIRECTORY || - entry.getValue().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(null, entry.getValue(), PermissionService.READ_CHILDREN, false)) - { - continue; - } - } - listing.put(entry.getKey(), - entry.getValue().getDescriptor(dir.getPath(), entry.getKey(), - lookup.getCurrentIndirection(), - lookup.getCurrentIndirectionVersion())); - - baseLowerKeyName.put(entry.getKey().toLowerCase(), entry.getKey()); - } - } - } - for (ChildEntry entry : AVMDAOs.Instance().fChildEntryDAO.getByParent(this, childNamePattern)) - { - if (entry.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || - entry.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(null, entry.getChild(), PermissionService.READ_CHILDREN, false)) - { - continue; - } - } - if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - listing.remove(entry.getKey().getName()); - } - else - { - String keyName = baseLowerKeyName.get(entry.getKey().getName().toLowerCase()); - if (keyName != null) - { - // specific rename 'case' only - listing.remove(keyName); - } - - listing.put(entry.getKey().getName(), entry.getChild() - .getDescriptor(dir.getPath(), entry.getKey().getName(), dir.getIndirection(), dir.getIndirectionVersion())); - } - } - return listing; - } - - /** - * Get the names of nodes deleted in this directory. - * - * @return A List of names. - */ - public List getDeletedNames() - { - List children = AVMDAOs.Instance().fChildEntryDAO.getByParent(this, null); - List listing = new ArrayList(); - for (ChildEntry entry : children) - { - if (entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - listing.add(entry.getKey().getName()); - } - } - return listing; - } - - /** - * Lookup a child entry by name. - * - * @param lPath - * The Lookup. - * @param name - * The name we are looking. - * @param version - * The version in which we are looking. - * @param write - * Whether this lookup is occurring in a write context. - * @return The child entry or null if not found. - */ - public Pair lookupChildEntry(Lookup lPath, String name, boolean includeDeleted) - { - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry != null) - { - if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - return null; - } - Pair result = new Pair(entry, true); - return result; - } - // Don't check our underlying directory if we are opaque. - if (getOpacity()) - { - return null; - } - // Not here so check our indirection. - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(getUnderlyingVersion(lPath), getUnderlying(lPath)); - if (lookup != null) - { - DirectoryNode dir = (DirectoryNode) lookup.getCurrentNode(); - Pair retVal = dir.lookupChildEntry(lookup, name, includeDeleted); - if (retVal != null) - { - retVal.setSecond(false); - } - lPath.setFinalStore(lookup.getFinalStore()); - return retVal; - } - else - { - return null; - } - } - - /** - * Lookup a child using a node descriptor as context. - * - * @param mine - * The node descriptor for this, - * @param name - * The name to lookup, - * @return The node descriptor. - */ - public AVMNodeDescriptor lookupChild(AVMNodeDescriptor mine, String name, boolean includeDeleted) - { - if (mine.getPath() == null || mine.getIndirection() == null) - { - throw new AVMBadArgumentException("Illegal null argument."); - } - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry != null) - { - if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - return null; - } - AVMNodeDescriptor desc = entry.getChild().getDescriptor(mine.getPath(), name, mine.getIndirection(), mine.getIndirectionVersion()); - return desc; - } - // Don't check our underlying directory if we are opaque. - if (getOpacity()) - { - return null; - } - // Not here so check our indirection. - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(mine.getIndirectionVersion(), mine.getIndirection()); - if (lookup != null) - { - DirectoryNode dir = (DirectoryNode) lookup.getCurrentNode(); - Pair child = dir.lookupChild(lookup, name, includeDeleted); - if (child == null) - { - return null; - } - AVMNodeDescriptor desc = child.getFirst().getDescriptor(lookup); - return desc; - } - else - { - return null; - } - } - - /** - * Directly remove a child. Do not COW. Do not pass go etc. - * - * @param lPath - * The lookup that arrived at this. - * @param name - * The name of the child to remove. - */ - public void removeChild(Lookup lPath, String name) - { - if (DEBUG) - { - checkReadOnly(); - } - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - AVMNode child = null; - boolean indirect = false; - if (entry != null) - { - child = entry.getChild(); - if (child.getType() == AVMNodeType.DELETED_NODE) - { - return; - } - AVMDAOs.Instance().fChildEntryDAO.delete(entry); - - Lookup lookup = AVMRepository.GetInstance().lookup(-1, AVMUtil.extendAVMPath(lPath.getRepresentedPath(), name), true); - - if (((AVMNodeType.PLAIN_FILE == child.getType()) || - (AVMNodeType.LAYERED_DIRECTORY == child.getType()) || - (AVMNodeType.PLAIN_DIRECTORY == child.getType())) && - ((lookup == null) || (lookup.getIndirectionPath() == null)) && (lookupChild(lPath, name, true) == null)) - { - return; - } - } - else - { - Pair temp = lookupChild(lPath, name, false); - if (temp == null) - { - child = null; - } - else - { - child = temp.getFirst(); - } - indirect = true; - } - if (child != null && (indirect || child.getStoreNew() == null || child.getAncestor() != null)) - { - DeletedNodeImpl ghost = new DeletedNodeImpl(lPath.getAVMStore(), child.getAcl()); - AVMDAOs.Instance().fAVMNodeDAO.save(ghost); - - ghost.setAncestor(child); - ghost.setDeletedType(child.getType()); - ghost.copyCreationAndOwnerBasicAttributes(child); - ghost.copyAspects(child); - ghost.copyProperties(child); - - AVMDAOs.Instance().fAVMNodeDAO.update(ghost); - - this.putChild(name, ghost); - } - } - - /** - * Get the type of this node. - * - * @return The type of this node. - */ - public int getType() - { - return AVMNodeType.LAYERED_DIRECTORY; - } - - /** - * For diagnostics. Get a String representation. - * - * @param lPath - * The Lookup. - * @return A String representation. - */ - public String toString(Lookup lPath) - { - return "[LD:" + getId() + (lPath != null ? ":" + getUnderlying(lPath) : "") + "]"; - } - - /** - * Set the primary indirection. No COW. Cascade resetting of acls also does not COW - * - * @param path - * The indirection path. - */ - public void rawSetPrimary(Lookup lPath, String path) - { - if (DEBUG) - { - checkReadOnly(); - } - - setIndirection(path); - setPrimaryIndirection(true); - - // Need to change the permission we point to .... - if (getIndirection() != null) - { - if ((getAcl() == null) || (getAcl().getAclType() == ACLType.LAYERED)) - { - Acl acl = null; - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getIndirection()); - if (lookup != null) - { - DirectoryNode dir = (DirectoryNode) lookup.getCurrentNode(); - if (dir.getAcl() != null) - { - if (getAcl() == null) - { - acl = AVMDAOs.Instance().fAclDAO.createLayeredAcl(dir.getAcl().getId()); - } - else - { - - acl = AVMDAOs.Instance().fAclDAO.getAclCopy(getAcl().getId(), dir.getAcl().getId(), ACLCopyMode.REDIRECT); - } - } - else - { - if (getAcl() == null) - { - acl = AVMDAOs.Instance().fAclDAO.createLayeredAcl(null); - } - else - { - acl = AVMDAOs.Instance().fAclDAO.getAclCopy(getAcl().getId(), null, ACLCopyMode.REDIRECT); - } - } - } - setAclAndInherit(this, acl, null); - } - } - else - { - if (getAcl().getAclType() == ACLType.LAYERED) - { - Acl acl = null; - if (getAcl() == null) - { - acl = AVMDAOs.Instance().fAclDAO.createLayeredAcl(null); - } - else - { - acl = AVMDAOs.Instance().fAclDAO.getAclCopy(getAcl().getId(), null, ACLCopyMode.REDIRECT); - } - setAclAndInherit(this, acl, null); - } - } - } - - public void setAclAndInherit(LayeredDirectoryNode layeredDirectory, Acl acl, String name) - { - // Note ACLS may COW on next ACL change - layeredDirectory.setAcl(acl); - - AVMDAOs.Instance().fAVMNodeDAO.update(layeredDirectory); - - Map directChildren = layeredDirectory.getListingDirect((Lookup) null, true); - for (String key : directChildren.keySet()) - { - AVMNode node = directChildren.get(key); - - if (node instanceof LayeredDirectoryNode) - { - LayeredDirectoryNode childNode = (LayeredDirectoryNode) node; - Acl currentAcl = node.getAcl(); - if (currentAcl == null) - { - if (acl == null) - { - childNode.setAclAndInherit(childNode, null, key); - } - else - { - childNode.setAclAndInherit(childNode, AVMDAOs.Instance().fAclDAO.getAclCopy(acl.getId(), acl.getId(), ACLCopyMode.REDIRECT), key); - } - } - else - { - if (acl == null) - { - childNode.setAclAndInherit(childNode, currentAcl, key); - } - else - { - childNode.setAclAndInherit(childNode, AVMDAOs.Instance().fAclDAO.getAclCopy(currentAcl.getId(), acl.getId(), ACLCopyMode.REDIRECT), key); - } - } - } - else if (node instanceof PlainFileNode) - { - PlainFileNode childNode = (PlainFileNode) node; - Acl currentAcl = node.getAcl(); - if (currentAcl == null) - { - if (acl == null) - { - childNode.setAcl(null); - } - else - { - childNode.setAcl(AVMDAOs.Instance().fAclDAO.getAclCopy(acl.getId(), acl.getId(), ACLCopyMode.REDIRECT)); - } - } - else - { - if (acl == null) - { - childNode.setAcl(currentAcl); - } - else - { - childNode.setAcl(AVMDAOs.Instance().fAclDAO.getAclCopy(currentAcl.getId(), acl.getId(), ACLCopyMode.REDIRECT)); - } - } - - AVMDAOs.Instance().fAVMNodeDAO.update(childNode); - } - } - } - - /** - * Make this node become a primary indirection. COW. - * - * @param lPath - * The Lookup. - */ - public void turnPrimary(Lookup lPath) - { - if (DEBUG) - { - checkReadOnly(); - } - String path = lPath.getCurrentIndirection(); - rawSetPrimary(lPath, path); - } - - /** - * Make this point at a new target. - * - * @param lPath - * The Lookup. - */ - public void retarget(Lookup lPath, String target) - { - if (DEBUG) - { - checkReadOnly(); - } - rawSetPrimary(lPath, target); - } - - /** - * Let anything behind name in this become visible. - * - * @param lPath - * The Lookup. - * @param name - * The name to uncover. - */ - public void uncover(Lookup lPath, String name) - { - if (DEBUG) - { - checkReadOnly(); - } - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry.getChild().getType() != AVMNodeType.DELETED_NODE) - { - throw new AVMException("One can only uncover deleted nodes."); - } - if (entry != null) - { - AVMDAOs.Instance().fChildEntryDAO.delete(entry); - } - } - - /** - * Get the descriptor for this node. - * - * @param lPath - * The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath, String name) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - path = AVMNodeConverter.ExtendAVMPath(path, name); - - int indirectionVersion = getUnderlyingVersion(lPath); - String indirect = null; - if (getPrimaryIndirection()) - { - indirect = getIndirection(); - } - else - { - indirect = AVMNodeConverter.ExtendAVMPath(lPath.getCurrentIndirection(), name); - } - - return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_DIRECTORY, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), attrs - .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), indirect, indirectionVersion, getPrimaryIndirection(), getLayerID(), getOpacity(), -1, -1); - } - - /** - * Get the descriptor for this node. - * - * @param lPath - * The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - String name = path.substring(path.lastIndexOf("/") + 1); - return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_DIRECTORY, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), attrs - .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), getUnderlying(lPath), getUnderlyingVersion(lPath), getPrimaryIndirection(), getLayerID(), - getOpacity(), -1, -1); - } - - /** - * Get a descriptor for this. - * - * @param parentPath - * The parent path. - * @param name - * The name this was looked up with. - * @param parentIndirection - * The indirection of the parent. - * @return The descriptor. - */ - public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion) - { - BasicAttributes attrs = getBasicAttributes(); - String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name; - String indirection = null; - int indirectionVersion = -1; - if (getPrimaryIndirection()) - { - indirection = getIndirection(); - indirectionVersion = getIndirectionVersion(); - } - else - { - indirection = parentIndirection.endsWith("/") ? parentIndirection + name : parentIndirection + "/" + name; - indirectionVersion = parentIndirectionVersion; - } - return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_DIRECTORY, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), attrs - .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), indirection, indirectionVersion, getPrimaryIndirection(), getLayerID(), getOpacity(), -1, -1); - } - - /** - * Set the indirection. - * - * @param indirection - */ - public void setIndirection(String indirection) - { - fIndirection = indirection; - } - - /** - * Does nothing because LayeredDirectoryNodes can't be roots. - * - * @param isRoot - */ - public void setIsRoot(boolean isRoot) - { - } - - /** - * Get the opacity of this. - * - * @return The opacity. - */ - public boolean getOpacity() - { - return fOpacity; - } - - /** - * Set the opacity of this, ie, whether it blocks things normally seen through its indirection. - * - * @param opacity - */ - public void setOpacity(boolean opacity) - { - fOpacity = opacity; - } - - /** - * Link a node with the given id into this directory. - * - * @param lPath - * The Lookup for this. - * @param name - * The name to give the node. - * @param toLink - * The node to link in. - */ - public void link(Lookup lPath, String name, AVMNodeDescriptor toLink) - { - if (DEBUG) - { - checkReadOnly(); - } - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(toLink.getId()); - if (node == null) - { - throw new AVMNotFoundException("Not Found: " + toLink.getId()); - } - if (node.getType() == AVMNodeType.LAYERED_DIRECTORY && !((LayeredDirectoryNode) node).getPrimaryIndirection()) - { - throw new AVMBadArgumentException("Non primary layered directories cannot be linked."); - } - // Look for an existing child of that name. - Pair temp = lookupChild(lPath, name, true); - AVMNode existing = (temp == null) ? null : temp.getFirst(); - ChildKey key = new ChildKey(this, name); - if (existing != null) - { - if (existing.getType() != AVMNodeType.DELETED_NODE) - { - // If the existing child is not a DELETED_NODE it's an error. - throw new AVMExistsException(name + " exists."); - } - // Only if the existing DELETED_NODE child exists directly in this - // directory do we delete it. - if (directlyContains(existing)) - { - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - AVMDAOs.Instance().fChildEntryDAO.delete(entry); - } - } - // Make the new ChildEntry and save. - ChildEntry newChild = new ChildEntryImpl(key, node); - AVMDAOs.Instance().fChildEntryDAO.save(newChild); - } - - /** - * Remove name without leaving behind a deleted node. - * - * @param name - * The name of the child to flatten. - */ - public void flatten(String name) - { - if (DEBUG) - { - checkReadOnly(); - } - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry != null) - { - AVMDAOs.Instance().fChildEntryDAO.delete(entry); - } - } - - /* - * (non-Javadoc) - * - * @see org.alfresco.repo.avm.LayeredDirectoryNode#setIndirectionVersion(int) - */ - public void setIndirectionVersion(Integer version) - { - if (version == null) - { - fIndirectionVersion = -1; - } - else - { - fIndirectionVersion = version; - } - } - - /** - * Get the indirection version. - * - * @return The indirection version. - */ - public Integer getIndirectionVersion() - { - return fIndirectionVersion; - } - -} diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNode.java b/source/java/org/alfresco/repo/avm/LayeredFileNode.java deleted file mode 100644 index dd8c17ed8f..0000000000 --- a/source/java/org/alfresco/repo/avm/LayeredFileNode.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -/** - * Interface for a layered file node. - * @author britt - */ -public interface LayeredFileNode extends FileNode, Layered -{ - /** - * Get the indirection version. - * @return The indirection version. - */ - public Integer getIndirectionVersion(); - - /** - * Make a copy of this node that is a LayeredFileNode. - * @param lookup The context. - * @return The copy. - */ - public LayeredFileNode copyLiterally(Lookup lookup); -} diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java deleted file mode 100644 index 3db5cd8dea..0000000000 --- a/source/java/org/alfresco/repo/avm/LayeredFileNodeImpl.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.repository.ContentData; - -/** - * A LayeredFileNode behaves like a copy on write symlink. - * - * @author britt - */ -public class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode -{ - static final long serialVersionUID = 9208423010479156363L; - - /** - * The indirection. - */ - private String fIndirection; - - /** - * The indirection version. - */ - private int fIndirectionVersion; - - /** - * Default constructor. - */ - public LayeredFileNodeImpl() - { - } - - /** - * Basically a copy constructor. Used when a branch is created from a layered file. - * - * @param other - * The file to make a copy of. - * @param store - * The store that contains us. - */ - public LayeredFileNodeImpl(LayeredFileNode other, AVMStore store, Long parentAcl, ACLCopyMode mode) - { - super(store); - setIndirection(other.getIndirection()); - setIndirectionVersion(-1); - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - } - - /** - * Make a brand new layered file node. - * - * @param indirection - * The thing we point to. - * @param store - * The store we belong to. - */ - public LayeredFileNodeImpl(String indirection, AVMStore store, Acl acl) - { - super(store); - setIndirection(indirection); - setIndirectionVersion(-1); - setVersionID(1); - - if (acl != null) - { - setAcl(acl); - } - else - { - if (indirection != null) - { - Lookup lookup = AVMRepository.GetInstance().lookup(-1, indirection, false); - if (lookup != null) - { - AVMNode node = lookup.getCurrentNode(); - if (node.getAcl() != null) - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(node.getAcl().getId())); - } - else - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(null)); - } - } - else - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(null)); - } - } - else - { - setAcl(AVMDAOs.Instance().fAclDAO.createLayeredAcl(null)); - } - } - } - - /** - * Copy on write logic. - * - * @param lPath - * The path by which this was found. - */ - public AVMNode copy(Lookup lPath) - { - // LayeredFileNodes are always copied. - Lookup lookup = AVMRepository.GetInstance().lookup(-1, getIndirection(), false); - if (lookup == null) - { - throw new AVMException("Unbacked layered file node."); - } - AVMNode indirect = lookup.getCurrentNode(); - if (indirect.getType() != AVMNodeType.LAYERED_FILE && indirect.getType() != AVMNodeType.PLAIN_FILE) - { - throw new AVMException("Unbacked layered file node."); - } - DirectoryNode dir = lPath.getCurrentNodeDirectory(); - Acl parentAcl = null; - if ((dir != null) && (dir.getAcl() != null)) - { - parentAcl = dir.getAcl(); - } - // TODO This doesn't look quite right. - PlainFileNodeImpl newMe = new PlainFileNodeImpl(lPath.getAVMStore(), getBasicAttributes(), getContentData(lPath), indirect.getProperties(), indirect.getAspects(), indirect - .getAcl(), getVersionID(), parentAcl, ACLCopyMode.COPY); - newMe.setAncestor(this); - return newMe; - } - - /** - * Get the type of this node. - * - * @return The type. - */ - public int getType() - { - return AVMNodeType.LAYERED_FILE; - } - - /** - * Get the underlying path. - * - * @param lookup - * The Lookup. (Unused here.) - * @return The underlying path. - */ - public String getUnderlying(Lookup lookup) - { - return getIndirection(); - } - - /** - * Get a diagnostic String representation. - * - * @param lPath - * The Lookup. - * @return A diagnostic String representation. - */ - public String toString(Lookup lPath) - { - return "[LF:" + getId() + ":" + getIndirection() + "]"; - } - - /** - * Get the descriptor for this node. - * - * @param lPath - * The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath, String name) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - if (path.endsWith("/")) - { - path = path + name; - } - else - { - path = path + "/" + name; - } - return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_FILE, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), - attrs.getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), getUnderlying(lPath), getUnderlyingVersion(lPath), false, -1, false, 0, -1); - } - - /** - * Get the descriptor for this node. - * - * @param lPath - * The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - return new AVMNodeDescriptor(path, path.substring(path.lastIndexOf("/") + 1), AVMNodeType.LAYERED_FILE, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), - attrs.getCreateDate(), attrs.getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), getUnderlying(lPath), getUnderlyingVersion(lPath), false, -1, - false, 0, -1); - } - - /** - * Get the descriptor for this node. - * - * @param parentPath - * The parent path. - * @param name - * The name this was looked up with. - * @param parentIndirection - * The parent indirection. - * @return The descriptor. - */ - public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion) - { - BasicAttributes attrs = getBasicAttributes(); - String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name; - return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_FILE, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), - attrs.getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), getIndirection(), getIndirectionVersion(), false, -1, false, 0, -1); - } - - /** - * Get the indirection. - * - * @return The indirection. - */ - public String getIndirection() - { - return fIndirection; - } - - /** - * Set the indirection. - * - * @param indirection - */ - public void setIndirection(String indirection) - { - fIndirection = indirection; - } - - /** - * Set the ContentData for this file. - * - * @param contentData - * The value to set. - */ - public void setContentData(ContentData contentData) - { - throw new AVMException("Should not be called."); - } - - // TODO The lPath argument is unnecessary. - /** - * Get the ContentData for this file. - * - * @return The ContentData object for this file. - */ - public ContentData getContentData(Lookup lPath) - { - Lookup lookup = null; - if (lPath != null) - { - lookup = lPath.getAVMStore().getAVMRepository().lookup(getUnderlyingVersion(lPath), getIndirection(), false); - } - else - { - lookup = AVMRepository.GetInstance().lookup(getUnderlyingVersion(null), getIndirection(), false); - } - - if (lookup == null) - { - throw new AVMException("Invalid target."); - } - AVMNode node = lookup.getCurrentNode(); - if (!(node instanceof FileNode)) - { - throw new AVMException("Invalid target."); - } - FileNode file = (FileNode) node; - return file.getContentData(lookup); - } - - /* - * (non-Javadoc) - * - * @see org.alfresco.repo.avm.Layered#getUnderlyingVersion(org.alfresco.repo.avm.Lookup) - */ - public int getUnderlyingVersion(Lookup lookup) - { - if ((lookup != null) && (lookup.getVersion() == -1)) - { - return -1; - } - return getIndirectionVersion(); - } - - /* - * (non-Javadoc) - * - * @see org.alfresco.repo.avm.LayeredFileNode#getIndirectionVersion() - */ - public Integer getIndirectionVersion() - { - return fIndirectionVersion; - } - - /* - * (non-Javadoc) - * - * @see org.alfresco.repo.avm.LayeredFileNode#setIndirectionVersion(int) - */ - public void setIndirectionVersion(Integer version) - { - if (version == null) - { - fIndirectionVersion = -1; - } - else - { - fIndirectionVersion = version; - } - } - - /* - * (non-Javadoc) - * - * @see org.alfresco.repo.avm.LayeredFileNode#copyLiterally(org.alfresco.repo.avm.Lookup) - */ - public LayeredFileNode copyLiterally(Lookup lookup) - { - DirectoryNode dir = lookup.getCurrentNodeDirectory(); - Long parentAclId = null; - if ((dir != null) && (dir.getAcl() != null)) - { - parentAclId = dir.getAcl().getId(); - } - return new LayeredFileNodeImpl(this, lookup.getAVMStore(), parentAclId, ACLCopyMode.COPY); - } -} diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java deleted file mode 100644 index 67190dd546..0000000000 --- a/source/java/org/alfresco/repo/avm/Lookup.java +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This holds all the information necessary to perform operations - * on AVMNodes, and is structured internally as a list of path components - * from the root directory of a repository. - * @author britt - */ -class Lookup implements Serializable -{ - private static final long serialVersionUID = -2844833688622561L; - - private static Log logger = LogFactory.getLog(Lookup.class); - - /** - * Is this lookup valid? - */ - private boolean fValid; - - /** - * The AVMStore. - */ - private AVMStore fAVMStore; - - /** - * The name of the AVMStore. - */ - private String fStoreName; - - /** - * The components that make up this path. - */ - private List fComponents; - - /** - * The final store in resolving layers. - */ - private AVMStore fFinalStore; - - /** - * Whether, at this point, a layered node has been hit. - * Used while building a Lookup. - */ - private boolean fLayeredYet; - - /** - * Whether we are directly contained at this point. - */ - private boolean fDirectlyContained; - - /** - * The first LayeredDirectoryNode in the path. - */ - private LayeredDirectoryNode fTopLayer; - - /** - * The path index of the top LayeredDirectoryNode in the path. - */ - private int fTopLayerIndex; - - /** - * The lowest layered directory node's index seen so far. - */ - private int fLowestLayerIndex; - - /** - * The current component being looked at by this lookup. - */ - private int fPosition; - - /** - * Whether a needs-to-be-copied component has been seen. - */ - private boolean fNeedsCopying; - - /** - * The version that is being looked up. - */ - private int fVersion; - - public Lookup(Lookup other, AVMNodeDAO nodeDAO, AVMStoreDAO storeDAO) - { - fValid = true; - fAVMStore = storeDAO.getByID(other.fAVMStore.getId()); - fVersion = other.fVersion; - if (fAVMStore == null) - { - fValid = false; - return; - } - fStoreName = fAVMStore.getName(); - fComponents = new ArrayList(); - fLayeredYet = other.fLayeredYet; - if (other.fTopLayer != null) - { - fTopLayer = (LayeredDirectoryNode)nodeDAO.getByID(other.fTopLayer.getId()); - if (fTopLayer == null) - { - fValid = false; - return; - } - } - fPosition = other.fPosition; - fTopLayerIndex = other.fTopLayerIndex; - fLowestLayerIndex = other.fLowestLayerIndex; - fNeedsCopying = other.fNeedsCopying; - fDirectlyContained = other.fDirectlyContained; - if (fLayeredYet) - { - for (LookupComponent comp : other.fComponents) - { - LookupComponent newComp = new LookupComponent(); - newComp.setName(comp.getName()); - newComp.setIndirection(comp.getIndirection()); - newComp.setIndirectionVersion(comp.getIndirectionVersion()); - newComp.setNode(nodeDAO.getByID(comp.getNode().getId())); - if (newComp.getNode() == null) - { - fValid = false; - return; - } - fComponents.add(newComp); - } - } - else - { - // If this is not a layered lookup then we do not - // need to reload any of the actual nodes except for - // the last. - int i = 0; - for (; i < fPosition; ++i) - { - LookupComponent comp = other.fComponents.get(i); - LookupComponent newComp = new LookupComponent(); - newComp.setName(comp.getName()); - fComponents.add(newComp); - } - LookupComponent comp = other.fComponents.get(i); - LookupComponent newComp = new LookupComponent(); - newComp.setName(comp.getName()); - newComp.setNode(nodeDAO.getByID(comp.getNode().getId())); - if (newComp.getNode() == null) - { - fValid = false; - return; - } - fComponents.add(newComp); - } - fFinalStore = storeDAO.getByID(other.fFinalStore.getId()); - if (fFinalStore == null) - { - fValid = false; - } - } - - /** - * Create a new one. - * @param store The AVMStore that's being looked in. - * @param storeName The name of that AVMStore. - */ - public Lookup(AVMStore store, String storeName, int version) - { - fValid = true; - fAVMStore = store; - fStoreName = storeName; - fVersion = version; - fComponents = new ArrayList(); - fLayeredYet = false; - fTopLayer = null; - fPosition = -1; - fTopLayerIndex = -1; - fLowestLayerIndex = -1; - fNeedsCopying = false; - fDirectlyContained = true; - fFinalStore = store; - } - - /** - * Is this a valid lookup? - */ - public boolean isValid() - { - return fValid; - } - - // TODO This is badly in need of cleanup. - /** - * Add a new node to the lookup. - * @param node The node to add. - * @param name The name of the node in the path. - * @param write Whether this is in the context of - * a write operation. - */ - public void add(AVMNode node, String name, boolean directlyContained, boolean write) - { - LookupComponent comp = new LookupComponent(); - comp.setName(name); - comp.setNode(node); - if (fPosition >= 0 && fDirectlyContained && - getCurrentNode().getType() == AVMNodeType.LAYERED_DIRECTORY) - { -// if (directlyContained != ((DirectoryNode)fComponents.get(fPosition).getNode()).directlyContains(node)) -// { -// System.err.println("Bloody Murder!"); -// } - fDirectlyContained = directlyContained; - - if (logger.isTraceEnabled()) - { - logger.trace("add: fDirectlyContained = "+directlyContained); - } - } - if (!write) - { - if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - LayeredDirectoryNode oNode = (LayeredDirectoryNode)node; - if (oNode.getPrimaryIndirection()) - { - comp.setIndirection(oNode.getIndirection()); - comp.setIndirectionVersion(oNode.getIndirectionVersion()); - } - else - { - Pair ind = computeIndirection(name); - comp.setIndirection(ind.getFirst()); - comp.setIndirectionVersion(ind.getSecond()); - } - fLayeredYet = true; - // Record the first layer seen. - if (fTopLayer == null) - { - fTopLayer = oNode; - fTopLayerIndex = fPosition + 1; - } - fLowestLayerIndex = fPosition + 1; - } - fComponents.add(comp); - fPosition++; - return; - } - if (!node.getIsNew()) - { - fNeedsCopying = true; - - if (logger.isTraceEnabled()) - { - logger.trace("add-cow: "+this+" ("+fPosition+") (not new)"); - } - } - else - { - if (fPosition >= 0 && !fDirectlyContained) - { - fNeedsCopying = true; - - if (logger.isTraceEnabled()) - { - logger.trace("add: COW: "+this+" ("+fPosition+") (new, not directly contained)"); - } - } - } - // Record various things if this is layered. - if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - LayeredDirectoryNode oNode = (LayeredDirectoryNode)node; - // Record the indirection path that should be used. - if (oNode.getPrimaryIndirection()) - { - comp.setIndirection(oNode.getIndirection()); - comp.setIndirectionVersion(-1); - } - else - { - Pair ind = computeIndirection(name); - comp.setIndirection(ind.getFirst()); - comp.setIndirectionVersion(-1); - } - fLayeredYet = true; - // Record the first layer seen. - if (fTopLayer == null) - { - fTopLayer = oNode; - fTopLayerIndex = fPosition + 1; - } - fLowestLayerIndex = fPosition + 1; - } - // In a write context a plain directory contained in a layer will - // be copied so we will need to compute an indirection path. - else if (fLayeredYet) - { - Pair ind = computeIndirection(name); - comp.setIndirection(ind.getFirst()); - comp.setIndirectionVersion(-1); - } - fComponents.add(comp); - fPosition++; - // If we are in a write context do copy on write. - if (fNeedsCopying) - { - node = node.copy(this); - getCurrentLookupComponent().setNode(node); - if (fPosition == 0) - { - // Inform the store of a new root. - fAVMStore.setNewRoot((DirectoryNode)node); - - ((DirectoryNode)node).setIsRoot(true); - AVMDAOs.Instance().fAVMNodeDAO.update(((DirectoryNode)node)); - AVMDAOs.Instance().fAVMStoreDAO.update(fAVMStore); - return; - } - // Not the root. Check if we are the top layer and insert this into it's parent. - if (fPosition == fTopLayerIndex) - { - fTopLayer = (LayeredDirectoryNode)node; - } - ((DirectoryNode)fComponents.get(fPosition - 1).getNode()).putChild(name, node); - } - } - - /** - * A helper for keeping track of indirection. - * @param name The name of the being added node. - * @return The indirection for the being added node. - */ - private Pair computeIndirection(String name) - { - String parentIndirection = getCurrentIndirection(); - int parentIndirectionVersion = getCurrentIndirectionVersion(); - if (parentIndirection.endsWith("/")) - { - return new Pair(parentIndirection + name, parentIndirectionVersion); - } - else - { - return new Pair(parentIndirection + "/" + name, parentIndirectionVersion); - } - } - - /** - * Return the parent node of the current node in the look up context or null if there is not one yet - * @return - */ - public DirectoryNode getCurrentNodeDirectory() - { - int position = fPosition -1; - if( (position >= 0) && (position < fComponents.size())) - { - return ((DirectoryNode)fComponents.get(fPosition - 1).getNode()); - } - else - { - return null; - } - } - - private LookupComponent getCurrentLookupComponent() - { - return fComponents.get(fPosition); - } - - /** - * Get the current node we're looking at. - * @return The current node. - */ - public AVMNode getCurrentNode() - { - return getCurrentLookupComponent().getNode(); - } - - /** - * Is the current path layered. - * @return Whether the current position in the path is layered. - */ - public boolean isLayered() - { - return fLayeredYet; - } - - /** - * Determine if a node is directly in this layer. - * @return Whether this node is directly in this layer. - */ - public boolean isInThisLayer() - { - return fLayeredYet && fDirectlyContained; - } - - /** - * Get the number of nodes. - * @return The number of nodes. - */ - public int size() - { - return fComponents.size(); - } - - /** - * Calculate the indirection path at this node. - * @return The indirection path all the way down to the current node. - */ - public String getIndirectionPath() - { - // The path is the underlying path of the lowest layer (in the path sense) - // that is directly contained by the top layer and is a primary indirection node. - int pos = fLowestLayerIndex; - AVMNode node = fComponents.get(pos).getNode(); - LayeredDirectoryNode oNode = null; - while (pos >= fTopLayerIndex && (node.getType() != AVMNodeType.LAYERED_DIRECTORY || - (oNode = (LayeredDirectoryNode)node).getLayerID() != fTopLayer.getLayerID() || - !oNode.getPrimaryIndirection())) - { - pos--; - node = fComponents.get(pos).getNode(); - } - oNode = (LayeredDirectoryNode)node; - // We've found it. - StringBuilder builder = new StringBuilder(); - builder.append(oNode.getIndirection()); - for (int i = pos + 1; i <= fPosition; i++) - { - builder.append("/"); - builder.append(fComponents.get(i).getName()); - } - return builder.toString(); - } - - /** - * Get the computed indirection for the current node. - * @return The indirection. - */ - public String getCurrentIndirection() - { - return getCurrentLookupComponent().getIndirection(); - } - - /** - * Get the computed indirection version for the current node. - * @return The indirection version. - */ - public int getCurrentIndirectionVersion() - { - return getCurrentLookupComponent().getIndirectionVersion(); - } - - /** - * Get the topmost Layered directory node. Topmost in the - * path lookup sense. - * @return The topmost layered directory node. - */ - public LayeredDirectoryNode getTopLayer() - { - return fTopLayer; - } - - /** - * Get the store that this path is in. - * @return The store. - */ - public AVMStore getAVMStore() - { - return fAVMStore; - } - - /** - * Get the path represented by this lookup. - * @return The canonical path for this lookup. - */ - public String getRepresentedPath() - { - if (fComponents.size() == 1) - { - return AVMUtil.buildAVMPath(fStoreName, AVMUtil.AVM_PATH_SEPARATOR); // root; - } - StringBuilder builder = new StringBuilder(); - builder.append(fStoreName); - builder.append(AVMUtil.AVM_STORE_SEPARATOR_CHAR); - int count = fComponents.size(); - for (int i = 1; i < count; i++) - { - builder.append(AVMUtil.AVM_PATH_SEPARATOR_CHAR); - builder.append(fComponents.get(i).getName()); - } - return builder.toString(); - } - - /** - * Gets the final name in the lookup. - * @return The final name in the lookup. - */ - public String getBaseName() - { - return getCurrentLookupComponent().getName(); - } - - /** - * Set the final store the lookup occurred in. - * @param store The store to set. - */ - public void setFinalStore(AVMStore store) - { - fFinalStore = store; - } - - /** - * Get the final store traversed during lookup. - * @return The final store traversed. - */ - public AVMStore getFinalStore() - { - return fFinalStore; - } - - /** - * Get whether the node looked up is directly contained from the - * original root. - * @return Whether the node looked up is directly contained. - */ - public boolean getDirectlyContained() - { - return fDirectlyContained; - } - - /** - * Get the version id that this is a lookup for. - * @return The version id. - */ - public int getVersion() - { - return fVersion; - } - - // for debug - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - - builder.append(getRepresentedPath()); - builder.append(" ["); - - for (int i = 0; i < fComponents.size(); i++) - { - builder.append(AVMUtil.AVM_PATH_SEPARATOR_CHAR); - builder.append(fComponents.get(i).toString()); - } - - builder.append("]"); - - return builder.toString(); - } -} diff --git a/source/java/org/alfresco/repo/avm/LookupCache.java b/source/java/org/alfresco/repo/avm/LookupCache.java deleted file mode 100644 index 302ff4d73f..0000000000 --- a/source/java/org/alfresco/repo/avm/LookupCache.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - -import org.alfresco.repo.avm.util.SimplePath; - -/** - * All lookup traffic goes through here. - */ -public interface LookupCache -{ - - public Lookup lookup(AVMStore store, int version, SimplePath path, boolean write, boolean includeDeleted); - - // Following are the cache invalidation calls. - - /** - * Called when a simple write operation occurs. This - * invalidates all read lookups and all layered lookups. - */ - public void onWrite(String storeName); - - /** - * Called when a delete has occurred in a store. This invalidates both - * reads and write lookups in that store. - */ - public void onDelete(String storeName); - - /** - * Called when a snapshot occurs in a store. This invalidates write - * lookups. Read lookups stay untouched. - */ - public void onSnapshot(String storeName); - - /** - * Full reset of cache. - */ - public void reset(); - -} diff --git a/source/java/org/alfresco/repo/avm/LookupComponent.java b/source/java/org/alfresco/repo/avm/LookupComponent.java deleted file mode 100644 index 2181dd45cd..0000000000 --- a/source/java/org/alfresco/repo/avm/LookupComponent.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -/** - * Represents a path component in a lookup. - * @author britt - */ -class LookupComponent -{ - /** - * The name of this component. - */ - private String fName; - - /** - * The node of this component. - */ - private AVMNode fNode; - - /** - * The indirection path (if any) for this node. - */ - private String fIndirection; - - /** - * The indirection version for this node (if any). - */ - private int fIndirectionVersion; - - /** - * Create a new empty lookup component. - */ - public LookupComponent() - { - } - - /** - * Get the indirection. - * @return the indirection - */ - public String getIndirection() - { - return fIndirection; - } - - /** - * Get the indirection version for this component. - * @return The indirection version. - */ - public int getIndirectionVersion() - { - return fIndirectionVersion; - } - - /** - * Set the indirection. - * @param indirection the indirection to set - */ - public void setIndirection(String indirection) - { - fIndirection = indirection; - } - - /** - * Set the indirection version for this component. - * @param version The version to set. - */ - public void setIndirectionVersion(int version) - { - fIndirectionVersion = version; - } - - /** - * Get the path component name. - * @return the name - */ - public String getName() - { - return fName; - } - - /** - * Set the path component name. - * @param name the name to set - */ - public void setName(String name) - { - fName = name; - } - - /** - * Get the looked up node for this component. - * @return the node - */ - public AVMNode getNode() - { - return fNode; - } - - /** - * Set the node for this component. - * @param node the node to set - */ - public void setNode(AVMNode node) - { - fNode = node; - } - - // for debug - public String toString() - { - return (fNode != null ? fNode.toString(null) : ""); - } -} diff --git a/source/java/org/alfresco/repo/avm/NOOPLookupCache.java b/source/java/org/alfresco/repo/avm/NOOPLookupCache.java deleted file mode 100644 index 1326ff2375..0000000000 --- a/source/java/org/alfresco/repo/avm/NOOPLookupCache.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - -import org.alfresco.repo.avm.util.SimplePath; -import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.util.Pair; - -/** - * A NO-OP implementation of AVM path lookup cache - */ -public class NOOPLookupCache implements LookupCache -{ - /** - * Make one up. - */ - public NOOPLookupCache() - { - } - - /** - * Lookup a path. - * - * @param store The AVMStore. - * @param version The versions. - * @param path The path we are looking up. - * @param write Whether this is a write lookup. - * @param includeDeleted - * @return - */ - public Lookup lookup(AVMStore store, int version, SimplePath path, - boolean write, boolean includeDeleted) - { - // Make up a Lookup to hold the results. - if (path.size() == 0) - { - return null; - } - Lookup result = new Lookup(store, store.getName(), version); - // Grab the root node to start the lookup. - DirectoryNode dir = null; - // Versions less than 0 mean get current. - if (version < 0) - { - dir = store.getRoot(); - } - else - { - VersionRoot vRoot = AVMDAOs.Instance().fVersionRootDAO.getByVersionID(store, version); - if (vRoot != null) - { - dir = vRoot.getRoot(); - } -// dir = fAVMNodeDAO.getAVMStoreRoot(store, version); - } - if (dir == null) - { - return null; - } - // Add an entry for the root. - result.add(dir, "", true, write); - dir = (DirectoryNode)result.getCurrentNode(); - if (path.size() == 1 && path.get(0).equals("")) - { - return result; - } - // Now look up each path element in sequence up to one - // before the end. - DirectoryNode prevDir = null; - for (int i = 0; i < path.size() - 1; i++) - { - if (!AVMRepository.GetInstance().can(null, dir, PermissionService.READ_CHILDREN, result.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read children: " + path.get(i) + " ("+store.getName()+")"); - } - Pair childEntryResult = dir.lookupChildEntry(result, path.get(i), includeDeleted); - if (childEntryResult == null) - { - return null; - } - AVMNode child = childEntryResult.getFirst().getChild(); - // Every element that is not the last needs to be a directory. - if (child.getType() != AVMNodeType.PLAIN_DIRECTORY && - child.getType() != AVMNodeType.LAYERED_DIRECTORY) - { - return null; - } - - prevDir = (DirectoryNode)child; - String lookupPathElementName = childEntryResult.getFirst().getKey().getName(); - result.add(child, lookupPathElementName, childEntryResult.getSecond(), write); - dir = (DirectoryNode)result.getCurrentNode(); - } - // Now look up the last element. - if (!AVMRepository.GetInstance().can(null, dir, PermissionService.READ_CHILDREN, result.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read children: " + path.get(path.size() - 1) + " ("+store.getName()+")"); - } - Pair childEntryResult = dir.lookupChildEntry(result, path.get(path.size() - 1), includeDeleted); - if (childEntryResult == null) - { - if (write && (dir.getType() == AVMNodeType.LAYERED_DIRECTORY)) - { - // stale ? - ChildKey key = new ChildKey(prevDir, path.get(path.size() - 1)); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry != null) - { - if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - return null; - } - childEntryResult = new Pair(entry, true); - } - else - { - return null; - } - } - else - { - return null; - } - } - AVMNode child = childEntryResult.getFirst().getChild(); - String lookupPathElementName = childEntryResult.getFirst().getKey().getName(); - result.add(child, lookupPathElementName, childEntryResult.getSecond(), write); - return result; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.LookupCache#onWrite(java.lang.String) - */ - public void onWrite(String storeName) - { - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.LookupCache#onDelete(java.lang.String) - */ - public void onDelete(String storeName) - { - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.LookupCache#onSnapshot(java.lang.String) - */ - public void onSnapshot(String storeName) - { - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.LookupCache#reset() - */ - public void reset() - { - } - -} diff --git a/source/java/org/alfresco/repo/avm/OrphanReaper.java b/source/java/org/alfresco/repo/avm/OrphanReaper.java deleted file mode 100644 index 725754c46a..0000000000 --- a/source/java/org/alfresco/repo/avm/OrphanReaper.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.alfresco.repo.domain.avm.AVMHistoryLinkEntity; -import org.alfresco.repo.domain.avm.AVMMergeLinkEntity; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.lock.JobLockService; -import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback; -import org.alfresco.repo.lock.LockAcquisitionException; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This is the background thread for reaping no longer referenced nodes in the AVM repository. These orphans arise from - * purge operations. - * - * @author britt - */ -public class OrphanReaper -{ - public void execute() - { - synchronized (this) - { - if (fRunning.get()) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("OrphanReaper is already running - just return"); - } - - return; - } - - fRunning.set(true); - - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("Start running OrphanReaper ..."); - } - } - try - { - do - { - doBatch(); - if (fDone.get()) - { - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("OrphanReaper is done - just return"); - } - return; - } - try - { - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("OrphanReaper is not done - sleep for "+fActiveBaseSleep+" ms"); - } - Thread.sleep(fActiveBaseSleep); - } - catch (InterruptedException e) - { - fgLogger.warn("OrphanReaper was interrupted - do nothing: "+e); - // Do nothing. - } - } - while (fActive.get()); - } - finally - { - synchronized (this) - { - fRunning.set(false); - - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("... finish running OrphanReaper"); - } - } - } - } - - private Log fgLogger = LogFactory.getLog(OrphanReaper.class); - - private static final QName LOCK = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "OrphanReaper"); - private JobLockService jobLockService; - - /** - * The Transaction Service - */ - private TransactionService fTransactionService; - - /** - * How many ms before refreshing the lock? - */ - private long lockRefreshTime = 60000; - - /** - * How long in ms to keep the lock in total before giving up, just in case there is a dead lock. - */ - private long lockTimeOut = 3600000; - - /** - * Active base sleep interval. - */ - private long fActiveBaseSleep = 1000; - - /** - * Batch size. - */ - private int fBatchSize = 50; - - /** - * Whether we are currently active, ie have work queued up. - * Using Atomics so that the memory model is synchronized between threads. - */ - private AtomicBoolean fActive = new AtomicBoolean(false); - private AtomicBoolean fDone = new AtomicBoolean(false); - private AtomicBoolean fRunning = new AtomicBoolean(false); - - /** - * Create one with default parameters. - */ - public OrphanReaper() - { - } - - // Setters for configuration. - - /** - * Set the active base sleep interval. - * - * @param interval - * The interval to set in ms. - */ - public void setActiveBaseSleep(long interval) - { - fActiveBaseSleep = interval; - } - - /** - * Set the batch size. - * - * @param size - * The batch size to set. - */ - public void setBatchSize(int size) - { - fBatchSize = size; - } - - /** - * Set the transaction service. - * - * @param transactionService - * The service. - */ - public void setTransactionService(TransactionService transactionService) - { - fTransactionService = transactionService; - } - - /** - * @param jobLockService service used to ensure that reaper runs are not duplicated - */ - public void setJobLockService(JobLockService jobLockService) - { - this.jobLockService = jobLockService; - } - - public void setLockRefreshTime(long lockRefreshTime) - { - this.lockRefreshTime = lockRefreshTime; - } - - public long getLockRefreshTime() - { - return lockRefreshTime; - } - - public long getTimeToLive() - { - return getLockRefreshTime() * 2; - } - - public void setLockTimeOut(long lockTimeOut) - { - this.lockTimeOut = lockTimeOut; - } - - public long getLockTimeOut() - { - return lockTimeOut; - } - - /** - * Shutdown the reaper. This needs to be called when the application shuts down. - */ - public void shutDown() - { - fDone.set(true); - } - - /** - * Attempts to get the lock. If the lock couldn't be taken, then null is returned. - * - * @return Returns the lock token or null - */ - private String getLock() - { - try - { - return jobLockService.getLock(LOCK, getTimeToLive()); - } - catch (LockAcquisitionException e) - { - return null; - } - } - - /** - * Creates a callback to refresh the lock if we are still doing work. - * @param lockToken to refresh - * @param lockHeld flag to indicate if the lock is needed/held. - * @param start when processing started. - */ - private void createLockRefreshCallback(final String lockToken, final AtomicBoolean lockHeld, final long start) - { - if (lockToken == null) - { - throw new IllegalArgumentException("Must provide existing lockToken"); - } - - JobLockRefreshCallback callback = new JobLockRefreshCallback() - { - @Override - public boolean isActive() - { - boolean active = lockHeld.get(); - if (active) - { - // Check for deadlock - if (System.currentTimeMillis() >= start + getLockTimeOut()) - { - active = false; - lockHeld.set(false); // if not deadlocked this stop processing in the main thread - fgLogger.error("Lock held too long. Do we have a deadlock? Restart process."); - } - } - return active; - } - - @Override - public void lockReleased() - { - lockHeld.set(false); - } - }; - - jobLockService.refreshLock(lockToken, LOCK, getTimeToLive(), callback); - } - - /** - * This is really for debugging and testing. Allows another thread to mark the orphan reaper busy so that it can - * monitor for it's being done. - */ - public void activate() - { - fActive.set(true); - } - - /** - * See if the reaper is actively reaping. - * - * @return Whether this is actively reaping. - */ - public boolean isActive() - { - return fActive.get(); - } - - /** - * Do a batch of cleanup work. - */ - public void doBatch() - { - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - final long start = System.currentTimeMillis(); - int reapCnt = 0; - - String lockToken = getLock(); - if (lockToken == null) - { - fgLogger.info("Can't get lock. Assume multiple reapers ..."); - fActive.set(false); - return null; - } - - AtomicBoolean lockHeld = new AtomicBoolean(true); - try - { - // Creates a callback that refreshes the lock as long the code in this try block is - // still running. If the JVM crashes, the lock will time out. Just in case the lock - // still times out, we check at several points in processing and have an overall - // timeout in case of deadlock. - createLockRefreshCallback(lockToken, lockHeld, start); - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("Orphan reaper doBatch: batchSize="+fBatchSize+", fActiveBaseSleep="+fActiveBaseSleep); - } - - List nodes = AVMDAOs.Instance().fAVMNodeDAO.getOrphans(fBatchSize); - if (nodes.size() == 0) - { - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("Nothing to purge (set fActive = false)"); - } - - fActive.set(false); - return null; - } - - if (!lockHeld.get()) - { - throw new LockAcquisitionException("Lock lost. Finding orphans to reap."); - } - LinkedList fPurgeQueue = new LinkedList(); - for (AVMNode node : nodes) - { - fPurgeQueue.add(node.getId()); - } - - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Queue was empty so got more orphans from DB. Orphan queue size = "+fPurgeQueue.size()); - } - - fActive.set(true); - - for (int i = 0; i < fBatchSize; i++) - { - if (fPurgeQueue.size() == 0) - { - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("Purge queue is empty (fpurgeQueue size = " - + fPurgeQueue.size() + ")"); - } - - fPurgeQueue = null; - break; - } - - if (!lockHeld.get()) - { - throw new LockAcquisitionException("Lock lost. Orphan reap loop: "+i); - } - Long nodeId = fPurgeQueue.removeFirst(); - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(nodeId); - - // Save away the ancestor and merged from fields from - // this node. - - AVMNode ancestor = null; - AVMHistoryLinkEntity hlEntity = AVMDAOs.Instance().newAVMNodeLinksDAO - .getHistoryLinkByDescendent(node.getId()); - if (hlEntity != null) - { - ancestor = AVMDAOs.Instance().fAVMNodeDAO.getByID(hlEntity - .getAncestorNodeId()); - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteHistoryLink( - hlEntity.getAncestorNodeId(), hlEntity.getDescendentNodeId()); - } - - AVMNode mergedFrom = null; - AVMMergeLinkEntity mlEntity = AVMDAOs.Instance().newAVMNodeLinksDAO - .getMergeLinkByTo(node.getId()); - if (mlEntity != null) - { - mergedFrom = AVMDAOs.Instance().fAVMNodeDAO.getByID(mlEntity - .getMergeFromNodeId()); - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteMergeLink( - mlEntity.getMergeFromNodeId(), mlEntity.getMergeToNodeId()); - } - - // Get all the nodes that have this node as ancestor. - List hlEntities = AVMDAOs.Instance().newAVMNodeLinksDAO - .getHistoryLinksByAncestor(node.getId()); - for (AVMHistoryLinkEntity link : hlEntities) - { - AVMNode desc = AVMDAOs.Instance().fAVMNodeDAO.getByID(link - .getDescendentNodeId()); - if (desc != null) - { - desc.setAncestor(ancestor); - if (desc.getMergedFrom() == null) - { - desc.setMergedFrom(mergedFrom); - } - } - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteHistoryLink( - link.getAncestorNodeId(), link.getDescendentNodeId()); - } - // Get all the nodes that have this node as mergedFrom - List mlEntities = AVMDAOs.Instance().newAVMNodeLinksDAO - .getMergeLinksByFrom(node.getId()); - for (AVMMergeLinkEntity link : mlEntities) - { - AVMNode mto = AVMDAOs.Instance().fAVMNodeDAO.getByID(link - .getMergeToNodeId()); - if (mto != null) - { - mto.setMergedFrom(ancestor); - } - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteMergeLink( - link.getMergeFromNodeId(), link.getMergeToNodeId()); - } - - // Get rid of all properties belonging to this node. - AVMDAOs.Instance().fAVMNodeDAO.deleteProperties(node.getId()); - - // Get rid of all aspects belonging to this node. - AVMDAOs.Instance().fAVMNodeDAO.deleteAspects(node.getId()); - - // Get rid of ACL. - @SuppressWarnings("unused") - Acl acl = node.getAcl(); - node.setAcl(null); - // Unused acls will be garbage collected - // Many acls will be shared - // Extra work for directories. - if (node.getType() == AVMNodeType.PLAIN_DIRECTORY - || node.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - // First get rid of all child entries for the node. - AVMDAOs.Instance().fChildEntryDAO.deleteByParent(node); - } - else if (node.getType() == AVMNodeType.PLAIN_FILE) - { - PlainFileNode file = (PlainFileNode) node; - if (file.isLegacyContentData()) - { - // We quickly convert the old ContentData to the - // new storage - ContentData contentData = file.getContentData(); - file.setContentData(contentData); - } - Long contentDataId = file.getContentDataId(); - if (contentDataId != null) - { - // The ContentDataDAO will take care of - // dereferencing and cleanup - AVMDAOs.Instance().contentDataDAO.deleteContentData(contentDataId); - } - } - - // Finally, delete it - AVMDAOs.Instance().fAVMNodeDAO.delete(node); - - if (fgLogger.isTraceEnabled()) - { - fgLogger.trace("Deleted Node [" + node.getId() + "]"); - } - - reapCnt++; - } - // Check we still have the lock at the end - if (!lockHeld.get()) - { - throw new LockAcquisitionException("Lock lost at the end of processing"); - } - } - finally - { - lockHeld.set(false); - jobLockService.releaseLock(lockToken, LOCK); - - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Reaped "+reapCnt+" nodes in "+(System.currentTimeMillis()-start)+" ms"); - } - } - - return null; - } - } - try - { - if (!fTransactionService.isReadOnly()) - { - fTransactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - } - } - catch (Exception e) - { - fgLogger.warn("Garbage collector error. Restarting process", e); - } - } -} diff --git a/source/java/org/alfresco/repo/avm/OrphanReaperJob.java b/source/java/org/alfresco/repo/avm/OrphanReaperJob.java deleted file mode 100644 index 20eb6324cd..0000000000 --- a/source/java/org/alfresco/repo/avm/OrphanReaperJob.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.avm; - -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -/** - * Quartz wrapper for OrphanReaper. - * @author britt - */ -public class OrphanReaperJob implements Job -{ - /* (non-Javadoc) - * @see org.quartz.Job#execute(org.quartz.JobExecutionContext) - */ - public void execute(JobExecutionContext context) throws JobExecutionException - { - OrphanReaper reaper = (OrphanReaper)context.getJobDetail().getJobDataMap().get("orphanReaper"); - reaper.execute(); - } -} diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java deleted file mode 100644 index cf9b06e424..0000000000 --- a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - - -/** - * Interface for PlainDirectoryNodes. - * @author britt - */ -public interface PlainDirectoryNode extends DirectoryNode -{ -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java deleted file mode 100644 index d9079cceb4..0000000000 --- a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.util.Pair; - -/** - * A plain directory. No monkey tricks except for possiblyCopy. - * @author britt - */ -public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectoryNode -{ - static final long serialVersionUID = 9423813734583003L; - - /** - * Make up a new directory with nothing in it. - * @param store - */ - public PlainDirectoryNodeImpl(AVMStore store) - { - super(store); - setVersionID(1); - } - - /** - * Default constructor. - */ - public PlainDirectoryNodeImpl() - { - } - - /** - * Copy like constructor. - * @param other The other directory. - * @param repos The AVMStore Object that will own us. - */ - public PlainDirectoryNodeImpl(PlainDirectoryNode other, - AVMStore store, Long parentAcl, ACLCopyMode mode) - { - super(store); - - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other, null)) - { - ChildKey key = new ChildKey(this, child.getKey().getName()); - ChildEntry newChild = new ChildEntryImpl(key, - child.getChild()); - AVMDAOs.Instance().fChildEntryDAO.save(newChild); - } - - copyProperties(other); - copyAspects(other); - } - - /** - * Get a directory listing. - * @param lPath The lookup path. - * @return The listing. - */ - public Map getListing(Lookup lPath, boolean includeDeleted) - { - return getListing(lPath, null, includeDeleted); - } - - /** - * Get a directory listing. - * @param lPath The lookup path. - * @param childNamePattern A child name pattern. - * @param includeDeleted Include deleted nodes. - * @return The listing. - */ - public Map getListing(Lookup lPath, String childNamePattern, boolean includeDeleted) - { - Map result = new HashMap(); - List children = AVMDAOs.Instance().fChildEntryDAO.getByParent(this, childNamePattern); - for (ChildEntry child : children) - { - if (child.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || - child.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(lPath.getAVMStore(), child.getChild(), PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) - { - continue; - } - } - if (!includeDeleted && child.getChild().getType() == AVMNodeType.DELETED_NODE) - { - continue; - } - result.put(child.getKey().getName(), child.getChild()); - } - return result; - } - - /** - * Get a listing of the nodes directly contained by a directory. - * @param lPath The Lookup to this directory. - * @return A Map of names to nodes. - */ - public Map getListingDirect(Lookup lPath, boolean includeDeleted) - { - return getListing(lPath, includeDeleted); - } - - /** - * Get a listing of the nodes directly contained by a directory. - * @param dir The node's descriptor. - * @param includeDeleted Whether to include deleted nodes. - * @return A Map of Strings to descriptors. - */ - public SortedMap getListingDirect(AVMNodeDescriptor dir, - boolean includeDeleted) - { - return getListing(dir, includeDeleted); - } - - /** - * Get a listing of from a directory node descriptor. - * @param dir The directory node descriptor. - * @return A Map of names to node descriptors. - */ - public SortedMap getListing(AVMNodeDescriptor dir, boolean includeDeleted) - { - return getListing(dir, null, includeDeleted); - } - - /** - * Get a listing of from a directory node descriptor. - * @param dir The directory node descriptor. - * @param childNamePattern - pattern to match for child names - may be null - * @return A Map of names to node descriptors. - */ - public SortedMap getListing(AVMNodeDescriptor dir, String childNamePattern, boolean includeDeleted) - { - if (dir.getPath() == null) - { - throw new AVMBadArgumentException("Path is null."); - } - SortedMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER); - List children = AVMDAOs.Instance().fChildEntryDAO.getByParent(this, childNamePattern); - for (ChildEntry child : children) - { - if (child.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || - child.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) - { - if (!AVMRepository.GetInstance().can(null, child.getChild(), PermissionService.READ_CHILDREN, false)) - { - continue; - } - } - if (!includeDeleted && child.getChild().getType() == AVMNodeType.DELETED_NODE) - { - continue; - } - result.put(child.getKey().getName(), - child.getChild().getDescriptor(dir.getPath(), - child.getKey().getName(), - dir.getIndirection(), - dir.getIndirectionVersion())); - } - return result; - } - - /** - * Get the names of nodes deleted in this directory. - * @return A List of names. - */ - public List getDeletedNames() - { - return new ArrayList(); - } - - /** - * Lookup a child entry by name. - * @param lPath The lookup path so far. - * @param name The name to lookup. - * @param includeDeleted Whether to lookup deleted nodes. - * @return The child entry or null. - */ - public Pair lookupChildEntry(Lookup lPath, String name, boolean includeDeleted) - { - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry == null) - { - return null; - } - if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE) - { - return null; - } - Pair result = new Pair(entry, true); - return result; - } - - /** - * Lookup a child using a node descriptor as context. - * @param mine The node descriptor for this. - * @param name The name of the child to lookup. - * @return A node descriptor for the child. - */ - public AVMNodeDescriptor lookupChild(AVMNodeDescriptor mine, String name, boolean includeDeleted) - { - if (mine.getPath() == null) - { - throw new AVMBadArgumentException("Path is null."); - } - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry == null || - (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE)) - { - return null; - } - AVMNodeDescriptor desc = entry.getChild().getDescriptor(mine.getPath(), name, (String)null, -1); - return desc; - } - - /** - * Remove a child, no copying. - * @param lPath The path by which this was found. - * @param name The name of the child to remove. - */ - public void removeChild(Lookup lPath, String name) - { - if (DEBUG) - { - checkReadOnly(); - } - ChildKey key = new ChildKey(this, name); - ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (entry != null) - { - AVMNode child = entry.getChild(); - if (child.getType() == AVMNodeType.DELETED_NODE) - { - return; - } - AVMDAOs.Instance().fChildEntryDAO.delete(entry); - if (child.getStoreNew() == null || child.getAncestor() != null) - { - DeletedNodeImpl ghost = new DeletedNodeImpl(lPath.getAVMStore(), child.getAcl()); - AVMDAOs.Instance().fAVMNodeDAO.save(ghost); - - ghost.setAncestor(child); - ghost.setDeletedType(child.getType()); - ghost.copyCreationAndOwnerBasicAttributes(child); - ghost.copyAspects(child); - ghost.copyProperties(child); - - AVMDAOs.Instance().fAVMNodeDAO.update(ghost); - - putChild(name, ghost); - } - } - } - - /** - * Put a new child node into this directory. No copy. - * @param name The name of the child. - * @param node The node to add. - */ - public void putChild(String name, AVMNode node) - { - if (DEBUG) - { - checkReadOnly(); - } - ChildKey key = new ChildKey(this, name); - ChildEntry existing = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (existing != null) - { - AVMDAOs.Instance().fChildEntryDAO.delete(existing); - } - ChildEntry entry = new ChildEntryImpl(key, node); - AVMDAOs.Instance().fChildEntryDAO.save(entry); - } - - /** - * Copy on write logic. - * @param lPath The lookup path. - * @return A brand new copied version. - */ - public AVMNode copy(Lookup lPath) - { - DirectoryNode newMe = null; - - DirectoryNode dir = lPath.getCurrentNodeDirectory(); - Long parentAclId = null; - if((dir != null) && (dir.getAcl() != null)) - { - parentAclId = dir.getAcl().getId(); - } - // In a layered context a copy on write creates a new - // layered directory. - if (lPath.isLayered()) - { - // Subtlety warning: This distinguishes the case of a - // Directory that was branched into the layer and one - // that is indirectly seen in this layer. - newMe = new LayeredDirectoryNodeImpl(this, lPath.getAVMStore(), lPath, - lPath.isInThisLayer(), parentAclId, ACLCopyMode.COPY); - ((LayeredDirectoryNodeImpl)newMe).setLayerID(lPath.getTopLayer().getLayerID()); - - AVMDAOs.Instance().fAVMNodeDAO.update(newMe); - } - else - { - newMe = new PlainDirectoryNodeImpl(this, lPath.getAVMStore(), parentAclId, ACLCopyMode.COW); - } - newMe.setAncestor(this); - return newMe; - } - - /** - * Get the type of this node. - * @return The type of this node. - */ - public int getType() - { - return AVMNodeType.PLAIN_DIRECTORY; - } - - /** - * Get a diagnostic String representation. - * @param lPath The Lookup. - * @return A diagnostic String representation. - */ - public String toString(Lookup lPath) - { - return "[PD:" + getId() + "]"; - } - - /** - * Turn this into a primary indirection. This must be in a - * layered context. - * @param lPath The Lookup. - */ - public void turnPrimary(Lookup lPath) - { - assert false : "Should never happen."; - } - - /** - * Retarget this directory. lPath must be in a layered context. - * @param lPath The Lookup. - * @param target The target path. - */ - public void retarget(Lookup lPath, String target) - { - assert false : "Should never happen."; - } - - /** - * Get the descriptor for this node. - * @param lPath The Lookup. - * @param name The name of this node in this context. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath, String name) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - if (path.endsWith("/")) - { - path = path + name; - } - else - { - path = path + "/" + name; - } - return new AVMNodeDescriptor(path, - name, - AVMNodeType.PLAIN_DIRECTORY, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - -1, - -1); - } - - /** - * Get the descriptor for this node. - * @param lPath The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - return new AVMNodeDescriptor(path, - path.substring(path.lastIndexOf("/") + 1), - AVMNodeType.PLAIN_DIRECTORY, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - -1, - -1); - } - - /** - * Get this node's descriptor. - * @param parentPath The parent path. - * @param name The name that we were looked up under. - * @param parentIndirection The parent indirection. - * @return This node's node descriptor - */ - public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion) - { - BasicAttributes attrs = getBasicAttributes(); - String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name; - return new AVMNodeDescriptor(path, - name, - AVMNodeType.PLAIN_DIRECTORY, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - -1, - -1); - } - - /** - * Link a node with the given id into this directory. - * @param lPath The Lookup for this directory. - * @param name The name to give the node. - * @param toLink The node to link in. - */ - public void link(Lookup lPath, String name, AVMNodeDescriptor toLink) - { - if (DEBUG) - { - checkReadOnly(); - } - // Assure that the incoming node exists. - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(toLink.getId()); - if (node == null) - { - throw new AVMNotFoundException("Node not found: " + toLink.getId()); - } - if (node.getType() == AVMNodeType.LAYERED_DIRECTORY && - !((LayeredDirectoryNode)node).getPrimaryIndirection()) - { - throw new AVMBadArgumentException("Non primary layered directories cannot be linked."); - } - // Check for an existing child by the given name. - ChildKey key = new ChildKey(this, name); - ChildEntry child = AVMDAOs.Instance().fChildEntryDAO.get(key); - if (child != null) - { - if (child.getChild().getType() != AVMNodeType.DELETED_NODE) - { - // It's an error if there is a non DELETED_NODE child. - throw new AVMExistsException(name + " exists."); - } - // Get rid of the DELETED_NODE child. - AVMDAOs.Instance().fChildEntryDAO.delete(child); - } - // Make the new entry and save. - ChildEntry newChild = new ChildEntryImpl(key, node); - AVMDAOs.Instance().fChildEntryDAO.save(newChild); - } -} - diff --git a/source/java/org/alfresco/repo/avm/PlainFileNode.java b/source/java/org/alfresco/repo/avm/PlainFileNode.java deleted file mode 100644 index 8e3de01cd4..0000000000 --- a/source/java/org/alfresco/repo/avm/PlainFileNode.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - -import org.alfresco.service.cmr.repository.ContentData; - -/** - * Interface for Plain file nodes. - * @author britt - */ -public interface PlainFileNode extends FileNode -{ - public ContentData getContentData(); - public void setContentData(ContentData contentData); - - public boolean isLegacyContentData(); - public Long getContentDataId(); - - /** - * DAO accessor only. DO NOT USE in code. - */ - public String getContentURL(); - /** - * DAO accessor only. DO NOT USE in code. - */ - public String getMimeType(); - /** - * DAO accessor only. DO NOT USE in code. - */ - public String getEncoding(); - /** - * DAO accessor only. DO NOT USE in code. - */ - public long getLength(); -} diff --git a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java deleted file mode 100644 index 7dc91b6b4e..0000000000 --- a/source/java/org/alfresco/repo/avm/PlainFileNodeImpl.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.contentdata.ContentDataDAO; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.repo.security.permissions.ACLCopyMode; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.namespace.QName; - -/** - * A plain old file. Contains a Content object. - * @author britt - */ -public class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode -{ - static final long serialVersionUID = 8720376837929735294L; - - private static final String PREFIX_CONTENT_DATA_ID = "id:"; - private static final String SUFFIX_CONTENT_DATA_NULL = "null"; - - /** - * The content URL OR the ID of the ContentData entity - */ - private String contentURL; - - /** - * The Mime type. - */ - private String mimeType; - - /** - * The character encoding. - */ - private String encoding; - - /** - * The length of the file. - */ - private long length; - - /** - * Default constructor. - */ - public PlainFileNodeImpl() - { - } - - /** - * Make one from just an AVMStore. - * This is the constructor used when a brand new plain file is being made. - * @param store An AVMStore. - */ - public PlainFileNodeImpl(AVMStore store) - { - super(store); - setVersionID(1); - } - - /** - * Copy on write constructor. - * @param other The node we are being copied from. - * @param store The AVMStore. - */ - public PlainFileNodeImpl(PlainFileNode other, - AVMStore store, Long parentAcl, ACLCopyMode mode) - { - super(store); - // The null is OK because the Lookup argument is only use by - // layered files. - setContentData(other.getContentData(null)); - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - } - - // TODO Is there a reason for passing all these parameters instead - // of just the LayeredFileNode? - /** - * Construct a new one. This is called when a LayeredFileNode - * is copied. - * @param store - * @param attrs - * @param content - */ - public PlainFileNodeImpl(AVMStore store, - BasicAttributes attrs, - ContentData content, - Map props, - Set aspects, - Acl acl, - int versionID, - Acl parentAcl, - ACLCopyMode mode) - { - super(store); - setContentData(content); - setBasicAttributes(attrs); - setVersionID(versionID + 1); - - copyACLs(acl, parentAcl, mode); - - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - addProperties(props); - setAspects(new HashSet(aspects)); - } - - /** - * Copy on write logic. - * @param lPath The lookup path. - */ - public AVMNode copy(Lookup lPath) - { - DirectoryNode dir = lPath.getCurrentNodeDirectory(); - Long parentAclId = null; - if((dir != null) && (dir.getAcl() != null)) - { - parentAclId = dir.getAcl().getId(); - } - PlainFileNodeImpl newMe = new PlainFileNodeImpl(this, lPath.getAVMStore(), parentAclId, ACLCopyMode.COW); - newMe.setAncestor(this); - return newMe; - } - - /** - * Get the type of this node. - * @return The type. - */ - public int getType() - { - return AVMNodeType.PLAIN_FILE; - } - - /** - * Get a diagnostic string representation. - * @param lPath The Lookup. - * @return A diagnostic String representation. - */ - public String toString(Lookup lPath) - { - return "[PF:" + getId() + "]"; - } - - /** - * Get the descriptor for this node. - * @param lPath The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath, String name) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - if (path.endsWith("/")) - { - path = path + name; - } - else - { - path = path + "/" + name; - } - ContentData contentData = getContentData(); - return new AVMNodeDescriptor(path, - name, - AVMNodeType.PLAIN_FILE, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - contentData == null ? 0L : contentData.getSize(), - -1); - } - - /** - * Get the descriptor for this node. - * @param lPath The Lookup. - * @return A descriptor. - */ - public AVMNodeDescriptor getDescriptor(Lookup lPath) - { - BasicAttributes attrs = getBasicAttributes(); - String path = lPath.getRepresentedPath(); - ContentData contentData = getContentData(); - return new AVMNodeDescriptor(path, - path.substring(path.lastIndexOf("/") + 1), - AVMNodeType.PLAIN_FILE, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - contentData == null ? 0L : contentData.getSize(), - -1); - } - - /** - * Get the descriptor for this. - * @param parentPath The parent path. - * @param name The name this was looked up with. - * @param parentIndirection The parent indirection. - * @return The descriptor for this. - */ - public AVMNodeDescriptor getDescriptor(String parentPath, String name, String parentIndirection, int parentIndirectionVersion) - { - BasicAttributes attrs = getBasicAttributes(); - String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name; - ContentData contentData = getContentData(); - return new AVMNodeDescriptor(path, - name, - AVMNodeType.PLAIN_FILE, - attrs.getCreator(), - attrs.getOwner(), - attrs.getLastModifier(), - attrs.getCreateDate(), - attrs.getModDate(), - attrs.getAccessDate(), - getId(), - getGuid(), - getVersionID(), - null, - -1, - false, - -1, - false, - contentData == null ? 0L : contentData.getSize(), - -1); - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public String getContentURL() - { - return contentURL; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public void setContentURL(String contentURL) - { - this.contentURL = contentURL; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public String getMimeType() - { - return mimeType; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public void setMimeType(String mimeType) - { - this.mimeType = mimeType; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public String getEncoding() - { - return encoding; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public void setEncoding(String encoding) - { - this.encoding = encoding; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public long getLength() - { - return length; - } - - /** - * DAO accessor only. DO NOT USE in code. - */ - public void setLength(long length) - { - this.length = length; - } - - /** - * Set the ContentData for this file. - * @param contentData The value to set. - */ - public void setContentData(ContentData contentData) - { - // Remove any legacy-stored attributes to avoid confusion - if (isLegacyContentData()) - { - // Wipe over the old values - contentURL = PREFIX_CONTENT_DATA_ID + SUFFIX_CONTENT_DATA_NULL; - encoding = null; - length = 0L; - mimeType = null; - } - - Long oldContentDataId = getContentDataId(); - Long newContentDataId = null; - if (oldContentDataId == null) - { - if (contentData != null) - { - // There was no reference before, so just create a new one - newContentDataId = AVMDAOs.Instance().contentDataDAO.createContentData(contentData).getFirst(); - } - } - else - { - if (contentData != null) - { - // Update it. The ID will remain the same. - AVMDAOs.Instance().contentDataDAO.updateContentData(oldContentDataId, contentData); - newContentDataId = oldContentDataId; - } - else - { - // Delete the old instance - AVMDAOs.Instance().contentDataDAO.deleteContentData(oldContentDataId); - newContentDataId = null; - } - } - - // Set the pointer to the ContentData instance - if (newContentDataId == null) - { - contentURL = PREFIX_CONTENT_DATA_ID + SUFFIX_CONTENT_DATA_NULL; - } - else - { - contentURL = PREFIX_CONTENT_DATA_ID + newContentDataId; - } - } - - /** - * Get the ContentData for this file. - * @param lPath The lookup path used to get here. Unused here. - * @return The ContentData object for this file. - */ - public ContentData getContentData(Lookup lPath) - { - return getContentData(); - } - - /** - * {@inheritDoc} - *

- * If the content URL contains the special prefix, {@link PREFIX_CONTENT_DATA_ID}, - * then the data is pulled directly from the {@link ContentDataDAO}. - */ - public ContentData getContentData() - { - if (contentURL != null && contentURL.startsWith(PREFIX_CONTENT_DATA_ID)) - { - Long contentDataId = getContentDataId(); - try - { - if (contentDataId == null) - { - return new ContentData(null, null, 0L, null); - } - else - { - return AVMDAOs.Instance().contentDataDAO.getContentData(contentDataId).getSecond(); - } - } - catch (Throwable e) - { - throw new AlfrescoRuntimeException( - "AVM File node " + getId() + " has invalid ContentData id reference " + contentDataId, - e); - } - } - else - { - // This deals with legacy data - return new ContentData(contentURL, mimeType, length, encoding); - } - } - - /** - * Checks the content URL and if it contains the {@link #PREFIX_CONTENT_DATA_ID prefix} - * indicating the an new ContentData storage ID, returns true. - */ - public boolean isLegacyContentData() - { - return (contentURL == null || !contentURL.startsWith(PREFIX_CONTENT_DATA_ID)); - } - - /** - * Get the ID of the ContentData as given by the string in the ContentURL of - * form ID:12345 - */ - public Long getContentDataId() - { - String idStr = contentURL.substring(3); - if (idStr.equals(SUFFIX_CONTENT_DATA_NULL)) - { - // Nothing has been stored against this file - return null; - } - try - { - return Long.parseLong(idStr); - } - catch (Throwable e) - { - throw new AlfrescoRuntimeException( - "AVM File node " + getId() + " has malformed ContentData id reference " + idStr, - e); - } - } -} - diff --git a/source/java/org/alfresco/repo/avm/TransactionalLookupCache.java b/source/java/org/alfresco/repo/avm/TransactionalLookupCache.java deleted file mode 100644 index 1e79e97f56..0000000000 --- a/source/java/org/alfresco/repo/avm/TransactionalLookupCache.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.repo.avm.util.SimplePath; -import org.alfresco.repo.cache.SimpleCache; -import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; - -/** - * A Transactional? implementation of AVM path lookup cache - * - * @author britt - * - * @deprecated - */ -public class TransactionalLookupCache implements LookupCache, InitializingBean -{ - private static Log fgLogger = LogFactory.getLog(TransactionalLookupCache.class); - private static Log fgLoggerInit = LogFactory.getLog(TransactionalLookupCache.class.getName() + ".init"); - - - /** - * The Map of of keys to lookups. - */ - private SimpleCache fCache; - - /** - * Reference to the Node DAO. - */ - private AVMNodeDAO fAVMNodeDAO; - - /** - * Reference to the Store DAO. - */ - private AVMStoreDAO fAVMStoreDAO; - - /** - * Make one up. - */ - public TransactionalLookupCache() - { - } - - /** - * Set up the node dao. - * @param dao The dao to set. - */ - public void setAvmNodeDAO(AVMNodeDAO dao) - { - fAVMNodeDAO = dao; - } - - /** - * Set the store dao. - * @param dao The dao to set. - */ - public void setAvmStoreDAO(AVMStoreDAO dao) - { - fAVMStoreDAO = dao; - } - - public void setTransactionalCache(SimpleCache cache) - { - fCache = cache; - } - - /* (non-Javadoc) - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - public void afterPropertiesSet() throws Exception - { - if (fgLoggerInit.isDebugEnabled()) - fgLoggerInit.debug("Transactional AVM lookup cache initialised"); - } - - /** - * Lookup a path. Try to fulfill the request from the cache. - * @param store The AVMStore. - * @param version The versions. - * @param path The path we are looking up. - * @param write Whether this is a write lookup. - * @param includeDeleted - * @return - */ - public Lookup lookup(AVMStore store, int version, SimplePath path, - boolean write, boolean includeDeleted) - { - // Create a key object. - LookupKey key = new LookupKey(version, path, store.getName(), write, includeDeleted); - // Is it in the cache? - Lookup found = findInCache(key); - // TODO Testing. - // found = null; - if (found != null) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Cache Hit: " + key + ", " + found.getCurrentNode().getId()); - } - return found; - } - // Make up a Lookup to hold the results. - if (path.size() == 0) - { - return null; - } - Lookup result = new Lookup(store, store.getName(), version); - // Grab the root node to start the lookup. - DirectoryNode dir = null; - // Versions less than 0 mean get current. - if (version < 0) - { - dir = store.getRoot(); - } - else - { - VersionRoot vRoot = AVMDAOs.Instance().fVersionRootDAO.getByVersionID(store, version); - if (vRoot != null) - { - dir = vRoot.getRoot(); - } -// dir = fAVMNodeDAO.getAVMStoreRoot(store, version); - } - if (dir == null) - { - return null; - } - // Add an entry for the root. - result.add(dir, "", true, write); - dir = (DirectoryNode)result.getCurrentNode(); - if (path.size() == 1 && path.get(0).equals("")) - { - fCache.put(key, result); - return result; - } - // Now look up each path element in sequence up to one - // before the end. - for (int i = 0; i < path.size() - 1; i++) - { - if (!AVMRepository.GetInstance().can(null, dir, PermissionService.READ_CHILDREN, result.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read children: " + path.get(i)); - } - Pair child = dir.lookupChild(result, path.get(i), includeDeleted); - if (child == null) - { - return null; - } - // Every element that is not the last needs to be a directory. - if (child.getFirst().getType() != AVMNodeType.PLAIN_DIRECTORY && - child.getFirst().getType() != AVMNodeType.LAYERED_DIRECTORY) - { - return null; - } - result.add(child.getFirst(), path.get(i), child.getSecond(), write); - dir = (DirectoryNode)result.getCurrentNode(); - } - // Now look up the last element. - if (!AVMRepository.GetInstance().can(null, dir, PermissionService.READ_CHILDREN, result.getDirectlyContained())) - { - throw new AccessDeniedException("Not allowed to read children: " + path.get(path.size() - 1)); - } - Pair child = dir.lookupChild(result, path.get(path.size() - 1), - includeDeleted); - if (child == null) - { - return null; - } - result.add(child.getFirst(), path.get(path.size() - 1), child.getSecond(), write); - fCache.put(key, result); - return result; - } - - /** - * Try to find a match in the cache. - * @param key The lookup key. - * @return A valid for this session Lookup or null if not found. - */ - private synchronized Lookup findInCache(LookupKey key) - { - Lookup found = fCache.get(key); - if (found != null) - { - // Get a freshened Lookup. - Lookup result = new Lookup(found, fAVMNodeDAO, fAVMStoreDAO); - // Check that nothing horrible is wrong. This should - // be assertible, but I'll leave the check in for now. - if (!result.isValid()) - { - fgLogger.error("Invalid entry in cache: " + key); - return null; - } - return result; - } - // Alternatively for a read lookup a write can match. - if (!key.isWrite()) - { - // Make a copy of the key and set it to 'write' - LookupKey newKey = new LookupKey(key); - newKey.setWrite(true); - found = fCache.get(newKey); - if (found != null) - { - // We found it. Make a freshened copy of the Lookup. - Lookup result = new Lookup(found, fAVMNodeDAO, fAVMStoreDAO); - // Check for badness. This should be assertible but I'll - // leave the check in for now. - if (!result.isValid()) - { - fgLogger.error("Invalid entry in cache: " + newKey); - return null; - } - return result; - } - } - return null; - } - - // Following are the cache invalidation calls. - - /** - * Called when a simple write operation occurs. This - * invalidates all read lookups and all layered lookups. - */ - public synchronized void onWrite(String storeName) - { - // Invalidate if it's a read lookup in the store, or - // any read lookup is it's layered. - List keys = new ArrayList(); - for (LookupKey key : fCache.getKeys()) - { - keys.add(key); - } - for (LookupKey key : keys) - { - Lookup value = fCache.get(key); - if ((key.getStoreName().equals(storeName) && - !key.isWrite()) || value == null || - (!key.isWrite() && value.isLayered())) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Invalidating: " + key + ", " + (value != null ? value.getCurrentNode().getId() : -2)); - } - fCache.remove(key); - } - } - } - - /** - * Called when a delete has occurred in a store. This invalidates both - * reads and write lookups in that store. - */ - public synchronized void onDelete(String storeName) - { - // Invalidate any entries that are in the store or are layered lookups. - List keys = new ArrayList(); - for (LookupKey key : fCache.getKeys()) - { - keys.add(key); - } - for (LookupKey key : keys) - { - Lookup value = fCache.get(key); - if (key.getStoreName().equals(storeName) || - value == null || value.isLayered()) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Invalidating: " + key + ", " + (value != null ? value.getCurrentNode().getId() : -2)); - } - fCache.remove(key); - } - } - } - - /** - * Called when a snapshot occurs in a store. This invalidates write - * lookups. Read lookups stay untouched. - */ - public synchronized void onSnapshot(String storeName) - { - // Invalidate any entries that in the store and writes or - // any layered lookups. - List keys = new ArrayList(); - for (LookupKey key : fCache.getKeys()) - { - keys.add(key); - } - for (LookupKey key : keys) - { - Lookup value = fCache.get(key); - if ((key.getStoreName().equals(storeName) && - key.isWrite()) || - value == null || value.isLayered()) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Invalidating: " + key + ", " + (value != null ? value.getCurrentNode().getId() : -2)); - } - fCache.remove(key); - } - } - } - - public synchronized void reset() - { - fCache.clear(); - } -} diff --git a/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntry.java b/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntry.java deleted file mode 100644 index 9b3360de75..0000000000 --- a/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntry.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.avm; - -/** - * When a snapshot is created we stow away all of the layered - * nodes that were frozen by the snapshot so that subsequent - * snapshots can find them and force copies. - * @author britt - */ -public interface VersionLayeredNodeEntry -{ - /** - * Get the VersionRoot for this entry. - * @return The VersionRoot for this entry. - */ - public VersionRoot getVersion(); - - /** - * Get the path to this entries Layered Node. This - * is a store relative path. - * @return The path. - */ - public String getPath(); - - /** - * Get the MD5 sum of the path. - * @return - */ - public String getMd5Sum(); -} diff --git a/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryDAO.java b/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryDAO.java deleted file mode 100644 index 76fe8f1eb4..0000000000 --- a/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryDAO.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.avm; - -import java.util.List; - -/** - * DAO interface for VersionLayeredNodeEntries. - * @author britt - */ -public interface VersionLayeredNodeEntryDAO -{ - /** - * Save a newly created one. - * @param entry - */ - public void save(VersionLayeredNodeEntry entry); - - /** - * Get all entries for a given version. - * @param version - * @return - */ - public List get(VersionRoot version); - - /** - * Delete all entries for the given version. - * @param version - */ - public void delete(VersionRoot version); -} diff --git a/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryImpl.java b/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryImpl.java deleted file mode 100644 index 5b6a8d58ed..0000000000 --- a/source/java/org/alfresco/repo/avm/VersionLayeredNodeEntryImpl.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.avm; - -import java.io.Serializable; - -import org.alfresco.util.MD5; - -/** - * Implementation of entry for tracking layered nodes which were - * snapshotted in a particular Version. - * @author britt - */ -public class VersionLayeredNodeEntryImpl implements VersionLayeredNodeEntry, Serializable -{ - private static final long serialVersionUID = -5222079271680056311L; - - private VersionRoot fVersion; - - private String fMD5Sum; - - private String fPath; - - public VersionLayeredNodeEntryImpl() - { - } - - public VersionLayeredNodeEntryImpl(VersionRoot version, - String path) - { - fVersion = version; - fMD5Sum = MD5.Digest(path.getBytes()); - fPath = path; - } - - public void setPath(String path) - { - fPath = path; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionLayeredNodeEntry#getPath() - */ - public String getPath() - { - return fPath; - } - - public void setVersion(VersionRoot version) - { - fVersion = version; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionLayeredNodeEntry#getVersion() - */ - public VersionRoot getVersion() - { - return fVersion; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (!(obj instanceof VersionLayeredNodeEntry)) - { - return false; - } - VersionLayeredNodeEntry other = (VersionLayeredNodeEntry)obj; - return fVersion.equals(other.getVersion()) && - fMD5Sum.equals(other.getMd5Sum()); - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() - { - return fVersion.hashCode() + fMD5Sum.hashCode(); - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - builder.append("[VersionLayeredNodeEntry:"); - builder.append(fVersion.toString()); - builder.append(':'); - builder.append(fPath); - builder.append(']'); - return builder.toString(); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionLayeredNodeEntry#getMd5Sum() - */ - public String getMd5Sum() - { - return fMD5Sum; - } - - public void setMd5Sum(String sum) - { - fMD5Sum = sum; - } -} diff --git a/source/java/org/alfresco/repo/avm/VersionRoot.java b/source/java/org/alfresco/repo/avm/VersionRoot.java deleted file mode 100644 index 3fa1eb4683..0000000000 --- a/source/java/org/alfresco/repo/avm/VersionRoot.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm; - -/** - * Represents a single version root. - * @author britt - */ -public interface VersionRoot -{ - /** - * @return the createDate - */ - public long getCreateDate(); - - /** - * @param createDate the createDate to set - */ - public void setCreateDate(long createDate); - - /** - * @return the creator - */ - public String getCreator(); - - /** - * @param creator the creator to set - */ - public void setCreator(String creator); - - /** - * @return the id - */ - public Long getId(); - - /** - * @param id the id to set - */ - public void setId(long id); - - /** - * @return the AVMStore - */ - public AVMStore getAvmStore(); - - /** - * @param store the store to set - */ - public void setAvmStore(AVMStore store); - - /** - * @return the root - */ - public DirectoryNode getRoot(); - - /** - * @param root the root to set - */ - public void setRoot(DirectoryNode root); - - /** - * Set the version id. - * @param versionID - */ - public void setVersionID(int versionID); - - /** - * Get the version id. - * @return The version id. - */ - public int getVersionID(); - - /** - * Get the tag (short description). - * @return The tag. - */ - public String getTag(); - - /** - * Get the thick description. - * @return The thick description. - */ - public String getDescription(); - - /** - * Set the tag. - * @param tag - */ - public void setTag(String tag); - - /** - * Set the description. - * @param description - */ - public void setDescription(String description); -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/avm/VersionRootDAO.java b/source/java/org/alfresco/repo/avm/VersionRootDAO.java deleted file mode 100644 index c30a036be4..0000000000 --- a/source/java/org/alfresco/repo/avm/VersionRootDAO.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.util.Date; -import java.util.List; - -/** - * DAO for VersionRoot objects. - * @author britt - */ -public interface VersionRootDAO -{ - /** - * Save an unsaved VersionRoot. - * @param vr The VersionRoot to save. - */ - public void save(VersionRoot vr); - - public void update(VersionRoot vr); - - /** - * Delete a VersionRoot. - * @param vr The VersionRoot to delete. - */ - public void delete(VersionRoot vr); - - /** - * Get all the version roots in a given store. - * @param store The store. - * @return A List of VersionRoots. In id order. - */ - public List getAllInAVMStore(AVMStore store); - - /** - * Get the VersionRoot corresponding to the given id. - * @param store The store - * @param id The version id. - * @return The VersionRoot or null if not found. - */ - public VersionRoot getByVersionID(AVMStore store, int id); - - /** - * Get one from its root. - * @param root The root to match. - * @return The version root or null. - */ - public VersionRoot getByRoot(AVMNode root); - - /** - * Get the version of a store by dates. - * @param store The store. - * @param from The starting date. May be null but not with to null also. - * @param to The ending date. May be null but not with from null also. - * @return A List of VersionRoots. - */ - public List getByDates(AVMStore store, Date from, Date to); - - /** - * Get the highest numbered version in a store. - * @param store The store. - * @return The highest numbered version. - */ - public VersionRoot getMaxVersion(AVMStore store); - - /** - * Get the highest numbered id from all the versions in a store. - * @param store The store. - * @return The highest numbered id. - */ - public Integer getMaxVersionID(AVMStore store); - - /** - * @param store - * @param version - * @return - */ - public List getByVersionsTo(AVMStore store, int version); - - /** - * @param store - * @param version - * @return - */ - public List getByVersionsFrom(AVMStore store, int version); - - /** - * @param store - * @param startVersion - * @param endVersion - * @return - */ - public List getByVersionsBetween(AVMStore store, int startVersion, int endVersion); -} diff --git a/source/java/org/alfresco/repo/avm/VersionRootImpl.java b/source/java/org/alfresco/repo/avm/VersionRootImpl.java deleted file mode 100644 index 58152e3c46..0000000000 --- a/source/java/org/alfresco/repo/avm/VersionRootImpl.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm; - -import java.io.Serializable; - - -/** - * Hold a single version root. - * @author britt - */ -public class VersionRootImpl implements VersionRoot, Serializable -{ - static final long serialVersionUID = 8826954538210455917L; - - /** - * The object id - */ - private Long fID; - - /** - * The version id. - */ - private int fVersionID; - - /** - * The creation date. - */ - private long fCreateDate; - - /** - * The creator. - */ - private String fCreator; - - /** - * The AVMStore. - */ - private AVMStore fAVMStore; - - /** - * The root node. - */ - private DirectoryNode fRoot; - - /** - * The short description. - */ - private String fTag; - - /** - * The thick description. - */ - private String fDescription; - - /** - * A default constructor. - */ - public VersionRootImpl() - { - } - - /** - * Rich constructor. - * @param store - * @param root - * @param versionID - * @param createDate - * @param creator - */ - public VersionRootImpl(AVMStore store, - DirectoryNode root, - int versionID, - long createDate, - String creator, - String tag, - String description) - { - fAVMStore = store; - fRoot = root; - fVersionID = versionID; - fCreateDate = createDate; - fCreator = creator; - fTag = tag; - fDescription = description; - } - - public long getCreateDate() - { - return fCreateDate; - } - - public void setCreateDate(long createDate) - { - fCreateDate = createDate; - } - - public String getCreator() - { - return fCreator; - } - - public void setCreator(String creator) - { - fCreator = creator; - } - - public Long getId() - { - return fID; - } - - public void setId(long id) - { - fID = id; - } - - public AVMStore getAvmStore() - { - return fAVMStore; - } - - public void setAvmStore(AVMStore store) - { - fAVMStore = store; - } - - public DirectoryNode getRoot() - { - return fRoot; - } - - public void setRoot(DirectoryNode root) - { - fRoot = root; - } - - /** - * Set the versionID. - * @param versionID - */ - public void setVersionID(int versionID) - { - fVersionID = versionID; - } - - /** - * Get the version id. - * @return The version id. - */ - public int getVersionID() - { - return fVersionID; - } - - /** - * Check equality. Based on AVMStore equality and version id equality. - * @param obj - * @return Equality. - */ - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (!(obj instanceof VersionRoot)) - { - return false; - } - VersionRoot other = (VersionRoot)obj; - return fAVMStore.equals(other.getAvmStore()) - && fVersionID == other.getVersionID(); - } - - /** - * Generate a hash code. - * @return The hash code. - */ - @Override - public int hashCode() - { - return fAVMStore.hashCode() + fVersionID; - } - - /** - * Get the tag (short description). - * @return The tag. - */ - public String getTag() - { - return fTag; - } - - /** - * Set the tag (short description). - * @param tag The short description. - */ - public void setTag(String tag) - { - fTag = tag; - } - - /** - * Get the thick description. - * @return The thick description. - */ - public String getDescription() - { - return fDescription; - } - - /** - * Set the thick description. - * @param description The thick discription. - */ - public void setDescription(String description) - { - fDescription = description; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - builder.append("[VersionRoot:"); - builder.append(fAVMStore.getName()); - builder.append(':'); - builder.append(fVersionID); - builder.append(']'); - return builder.toString(); - } -} - diff --git a/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java b/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java deleted file mode 100644 index 9a24187af6..0000000000 --- a/source/java/org/alfresco/repo/avm/actions/SimpleAVMSubmitAction.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm.actions; - -import java.util.List; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.wcm.sandbox.SandboxConstants; -import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.action.ParameterDefinition; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.service.cmr.avmsync.AVMSyncException; -import org.alfresco.service.cmr.avmsync.AVMSyncService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.util.NameMatcher; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This action submits all the newer changes in the passed in NodeRef - * to its corresponding staging area. It ignores conflicts and older nodes. - * @author britt - * - * @deprecated see org.alfresco.wcm.actions.WCMSandboxSubmitAction or org.alfresco.wcm.SandboxService.submit - */ -public class SimpleAVMSubmitAction extends ActionExecuterAbstractBase -{ - private static Log fgLogger = LogFactory.getLog(SimpleAVMSubmitAction.class); - - public static String NAME = "simple-avm-submit"; - - /** - * The AVMService instance. - */ - private AVMService fAVMService; - - /** - * The AVMSyncService instance. - */ - private AVMSyncService fAVMSyncService; - - /** - * The Excluding NameMatcher. - */ - private NameMatcher fExcluder; - - /** - * Default constructor. - */ - public SimpleAVMSubmitAction() - { - super(); - } - - /** - * Set the AVMService. - * @param avmService The instance. - */ - public void setAvmService(AVMService avmService) - { - fAVMService = avmService; - } - - /** - * Set the AVMSyncService. - * @param avmSyncService The instance. - */ - public void setAvmSyncService(AVMSyncService avmSyncService) - { - fAVMSyncService = avmSyncService; - } - - // TODO This should be a parameter of the action execution really. - /** - * Set the excluder. - * @param excluder - */ - public void setExcluder(NameMatcher excluder) - { - fExcluder = excluder; - } - - /** - * Perform the action. The NodeRef must be an AVM NodeRef. - * @param action Don't actually need anything from this here. - * @param actionedUponNodeRef The AVM NodeRef. - */ - @Override - protected void executeImpl(Action action, NodeRef actionedUponNodeRef) - { - // Crack the NodeRef. - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(actionedUponNodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - // Get store name and path parts. - String [] storePath = path.split(":"); - if (storePath.length != 2) - { - throw new AVMSyncException("Malformed source path " + path); - } - // Get the .website.name property. - PropertyValue wsProp = - fAVMService.getStoreProperty(storePath[0], SandboxConstants.PROP_WEBSITE_NAME); - if (wsProp == null) - { - fgLogger.warn(SandboxConstants.PROP_WEBSITE_NAME.toString()+" property not found."); - return; - } - // And the actual web-site name. - String websiteName = wsProp.getStringValue(); - // Construct the submit destination path. - String avmDest = websiteName + ":" + storePath[1]; // note: it is implied that the website name is the same as staging name - // Get the difference between source and destination. - List diffs = - fAVMSyncService.compare(version, path, -1, avmDest, fExcluder); - // TODO fix update comments at some point. - // Do the update. - fAVMSyncService.update(diffs, fExcluder, false, false, true, true, - "Submit of item: " + AVMNodeConverter.SplitBase(path)[1], null); - // Cleanup by flattening the source relative to the destination. - fAVMSyncService.flatten(storePath[0] + ":/" + JNDIConstants.DIR_DEFAULT_WWW, websiteName + ":/" + JNDIConstants.DIR_DEFAULT_WWW); - } - - /** - * This action takes no parameters. - * @param paramList The List to add nothing to. - */ - @Override - protected void addParameterDefinitions(List paramList) - { - // No parameters for this action. - } -} diff --git a/source/java/org/alfresco/repo/avm/ibatis/AVMNodeDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/AVMNodeDAOIbatis.java deleted file mode 100644 index f281f63185..0000000000 --- a/source/java/org/alfresco/repo/avm/ibatis/AVMNodeDAOIbatis.java +++ /dev/null @@ -1,483 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ -package org.alfresco.repo.avm.ibatis; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMNode; -import org.alfresco.repo.avm.AVMNodeDAO; -import org.alfresco.repo.avm.AVMNodeImpl; -import org.alfresco.repo.avm.AVMNodeType; -import org.alfresco.repo.avm.AVMStore; -import org.alfresco.repo.avm.BasicAttributes; -import org.alfresco.repo.avm.BasicAttributesImpl; -import org.alfresco.repo.avm.DeletedNode; -import org.alfresco.repo.avm.DeletedNodeImpl; -import org.alfresco.repo.avm.DirectoryNode; -import org.alfresco.repo.avm.Layered; -import org.alfresco.repo.avm.LayeredDirectoryNode; -import org.alfresco.repo.avm.LayeredDirectoryNodeImpl; -import org.alfresco.repo.avm.LayeredFileNode; -import org.alfresco.repo.avm.LayeredFileNodeImpl; -import org.alfresco.repo.avm.PlainDirectoryNode; -import org.alfresco.repo.avm.PlainDirectoryNodeImpl; -import org.alfresco.repo.avm.PlainFileNode; -import org.alfresco.repo.avm.PlainFileNodeImpl; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.avm.AVMHistoryLinkEntity; -import org.alfresco.repo.domain.avm.AVMMergeLinkEntity; -import org.alfresco.repo.domain.avm.AVMNodeEntity; -import org.alfresco.repo.domain.avm.AVMVersionRootEntity; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.service.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * iBATIS DAO wrapper for AVMNode - * - * @author janv - * - */ -class AVMNodeDAOIbatis implements AVMNodeDAO -{ - private static Log logger = LogFactory.getLog(AVMNodeDAO.class); - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#save(org.alfresco.repo.avm.AVMNode) - */ - public void save(AVMNode node) - { - AVMNodeEntity nodeEntity = AVMDAOs.Instance().newAVMNodeDAO.createNode(convertNodeToNodeEntity(node)); - ((AVMNodeImpl)node).setId(nodeEntity.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#delete(org.alfresco.repo.avm.AVMNode) - */ - public void delete(AVMNode node) - { - AVMDAOs.Instance().newAVMNodeDAO.deleteNode(node.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#createAspect(long, long) - */ - public void createAspect(long nodeId, QName aspectQName) - { - AVMDAOs.Instance().newAVMNodeDAO.createAspect(nodeId, aspectQName); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#deleteAspect(long, long) - */ - public void deleteAspect(long nodeId, QName aspectQName) - { - AVMDAOs.Instance().newAVMNodeDAO.deleteAspect(nodeId, aspectQName); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#deleteAspects(long) - */ - public void deleteAspects(long nodeId) - { - AVMDAOs.Instance().newAVMNodeDAO.deleteAspects(nodeId); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getAspects(long) - */ - public Set getAspects(long nodeId) - { - return AVMDAOs.Instance().newAVMNodeDAO.getAspects(nodeId); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#createOrUpdateProperty(long, QName, org.alfresco.repo.domain.PropertyValue) - */ - public void createOrUpdateProperty(long nodeId, QName qname, PropertyValue value) - { - AVMDAOs.Instance().newAVMNodeDAO.createOrUpdateNodeProperty(nodeId, qname, value); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#deleteProperty(long, QName) - */ - public void deleteProperty(long nodeId, QName propQName) - { - AVMDAOs.Instance().newAVMNodeDAO.deleteNodeProperty(nodeId, propQName); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#deleteProperties(long) - */ - public void deleteProperties(long nodeId) - { - AVMDAOs.Instance().newAVMNodeDAO.deleteNodeProperties(nodeId); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getProperties(long) - */ - public Map getProperties(long nodeId) - { - return AVMDAOs.Instance().newAVMNodeDAO.getNodeProperties(nodeId); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getByID(long) - */ - public AVMNode getByID(long id) - { - return convertNodeEntityToNode(AVMDAOs.Instance().newAVMNodeDAO.getNode(id)); - } - - /* package */ AVMNode getRootNodeByID(AVMStore store, long rootNodeId) - { - AVMNodeEntity rootNodeEntity = null; - - try - { - rootNodeEntity = AVMDAOs.Instance().newAVMNodeDAO.getNode(rootNodeId); - } - catch (RuntimeException re) - { - if (logger.isWarnEnabled()) - { - logger.warn("Root node ("+rootNodeId+") not found for store: "+store); - } - throw re; - } - - AVMNode rootNode = null; - if (rootNodeEntity.getStoreNewId() != null) - { - rootNode = convertNodeEntityToNode(rootNodeEntity, false); - rootNode.setStoreNew(store); - } - else - { - rootNode = convertNodeEntityToNode(rootNodeEntity); - } - - return rootNode; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#update(org.alfresco.repo.avm.AVMNode) - */ - public void update(AVMNode node) - { - AVMNodeEntity nodeEntity = convertNodeToNodeEntity(node); - AVMDAOs.Instance().newAVMNodeDAO.updateNode(nodeEntity); - ((AVMNodeImpl)node).setVers(nodeEntity.getVers()); - } - - /** - * TODO review - * - * @deprecated - */ - public void updateModTimeAndGuid(AVMNode node) - { - AVMNodeEntity nodeEntity = convertNodeToNodeEntity(node); - AVMDAOs.Instance().newAVMNodeDAO.updateNodeModTimeAndGuid(nodeEntity); - ((AVMNodeImpl)node).setVers(nodeEntity.getVers()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getAVMStoreRoot(org.alfresco.repo.avm.AVMStore, int) - */ - public DirectoryNode getAVMStoreRoot(AVMStore store, int version) - { - AVMVersionRootEntity vrEntity = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionID(store.getId(), version); - - if (vrEntity == null) - { - return null; - } - - return (DirectoryNode) getByID(vrEntity.getRootNodeId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getAncestor(org.alfresco.repo.avm.AVMNode) - */ - public AVMNode getAncestor(AVMNode descendent) - { - AVMHistoryLinkEntity hlEntity = AVMDAOs.Instance().newAVMNodeLinksDAO.getHistoryLinkByDescendent(descendent.getId()); - if (hlEntity == null) - { - return null; - } - return AVMDAOs.Instance().fAVMNodeDAO.getByID(hlEntity.getAncestorNodeId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getMergedFrom(org.alfresco.repo.avm.AVMNode) - */ - public AVMNode getMergedFrom(AVMNode mTo) - { - AVMMergeLinkEntity mlEntity = AVMDAOs.Instance().newAVMNodeLinksDAO.getMergeLinkByTo(mTo.getId()); - if (mlEntity == null) - { - return null; - } - return AVMDAOs.Instance().fAVMNodeDAO.getByID(mlEntity.getMergeFromNodeId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getOrphans(int) - */ - public List getOrphans(int batchSize) - { - List nodeEntities = AVMDAOs.Instance().newAVMNodeDAO.getNodeOrphans(batchSize); - - if (nodeEntities == null) - { - return new ArrayList(0); - } - - List nodes = new ArrayList(nodeEntities.size()); - for (AVMNodeEntity nodeEntity : nodeEntities) - { - nodes.add(convertNodeEntityToNode(nodeEntity)); - } - return nodes; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getNewInStore(org.alfresco.repo.avm.AVMStore) - */ - public List getNewInStore(AVMStore store) - { - List nodeEntities = AVMDAOs.Instance().newAVMNodeDAO.getNodesNewInStore(store.getId()); - - if (nodeEntities == null) - { - return new ArrayList(0); - } - - List nodes = new ArrayList(nodeEntities.size()); - for (AVMNodeEntity nodeEntity : nodeEntities) - { - nodes.add(convertNodeEntityToNode(nodeEntity)); - } - return nodes; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#clear() - */ - public void clear() - { - AVMDAOs.Instance().newAVMNodeDAO.clearNodeEntityCache(); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#clearNewInStore(org.alfresco.repo.avm.AVMStore) - */ - public void clearNewInStore(AVMStore store) - { - AVMDAOs.Instance().newAVMNodeDAO.updateNodesClearNewInStore(store.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getNewLayeredInStoreIDs(org.alfresco.repo.avm.AVMStore) - */ - public List getNewLayeredInStoreIDs(AVMStore store) - { - return AVMDAOs.Instance().newAVMNodeDAO.getLayeredNodesNewInStoreIDs(store.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMNodeDAO#getNewLayeredInStore(org.alfresco.repo.avm.AVMStore) - */ - public List getNewLayeredInStore(AVMStore store) - { - List nodeEntities = AVMDAOs.Instance().newAVMNodeDAO.getLayeredNodesNewInStore(store.getId()); - - if (nodeEntities == null) - { - return new ArrayList(0); - } - - List nodes = new ArrayList(nodeEntities.size()); - for (AVMNodeEntity nodeEntity : nodeEntities) - { - nodes.add((Layered)convertNodeEntityToNode(nodeEntity)); - } - return nodes; - } - - private AVMNodeEntity convertNodeToNodeEntity(AVMNode node) - { - AVMNodeEntity nodeEntity = new AVMNodeEntity(); - - nodeEntity.setId(node.getId()); - - nodeEntity.setAccessDate(node.getBasicAttributes().getAccessDate()); - nodeEntity.setOwner(node.getBasicAttributes().getOwner()); - nodeEntity.setCreator(node.getBasicAttributes().getCreator()); - nodeEntity.setCreatedDate(node.getBasicAttributes().getCreateDate()); - nodeEntity.setModifier(node.getBasicAttributes().getLastModifier()); - nodeEntity.setModifiedDate(node.getBasicAttributes().getModDate()); - - nodeEntity.setType(node.getType()); - nodeEntity.setVersion(new Long(node.getVersionID())); - nodeEntity.setVers(((AVMNodeImpl)node).getVers()); - nodeEntity.setAclId((node.getAcl() == null ? null : node.getAcl().getId())); - - nodeEntity.setGuid(node.getGuid()); - nodeEntity.setStoreNewId(node.getStoreNew() == null ? null : node.getStoreNew().getId()); - nodeEntity.setRoot(node.getIsRoot()); - - if (node instanceof PlainFileNode) - { - PlainFileNode pfNode = (PlainFileNode)node; - nodeEntity.setEncoding(pfNode.getEncoding()); - nodeEntity.setLength(pfNode.getLength()); - nodeEntity.setMimetype(pfNode.getMimeType()); - nodeEntity.setContentUrl(pfNode.getContentURL()); - } - else if (node instanceof LayeredFileNode) - { - LayeredFileNode lfNode = (LayeredFileNode)node; - nodeEntity.setIndirection(lfNode.getIndirection()); - nodeEntity.setIndirectionVersion(lfNode.getIndirectionVersion()); - } - else if (node instanceof PlainDirectoryNode) - { - // no additional - } - else if (node instanceof LayeredDirectoryNode) - { - LayeredDirectoryNode ldNode = (LayeredDirectoryNode)node; - nodeEntity.setIndirection(ldNode.getIndirection()); - nodeEntity.setIndirectionVersion(ldNode.getIndirectionVersion()); - nodeEntity.setLayerId(ldNode.getLayerID()); - nodeEntity.setPrimaryIndirection(ldNode.getPrimaryIndirection()); - nodeEntity.setOpacity(ldNode.getOpacity()); - } - else if (node instanceof DeletedNode) - { - DeletedNode dNode = (DeletedNode)node; - nodeEntity.setDeletedType(dNode.getDeletedType()); - } - - return nodeEntity; - } - - private AVMNode convertNodeEntityToNode(AVMNodeEntity nodeEntity) - { - return convertNodeEntityToNode(nodeEntity, true); - } - - private AVMNode convertNodeEntityToNode(AVMNodeEntity nodeEntity, boolean withStore) - { - if (nodeEntity == null) - { - return null; - } - - AVMNodeImpl node = null; - if (nodeEntity.getType() == AVMNodeType.PLAIN_FILE) - { - node = new PlainFileNodeImpl(); - PlainFileNodeImpl pfNode = (PlainFileNodeImpl) node; - pfNode.setMimeType(nodeEntity.getMimetype()); - pfNode.setEncoding(nodeEntity.getEncoding()); - pfNode.setLength(nodeEntity.getLength()); - pfNode.setContentURL(nodeEntity.getContentUrl()); - } - else if (nodeEntity.getType() == AVMNodeType.PLAIN_DIRECTORY) - { - node = new PlainDirectoryNodeImpl(); - - // no additional - } - else if (nodeEntity.getType() == AVMNodeType.LAYERED_FILE) - { - node = new LayeredFileNodeImpl(); - - ((LayeredFileNodeImpl)node).setIndirection(nodeEntity.getIndirection()); - ((LayeredFileNodeImpl)node).setIndirectionVersion(nodeEntity.getIndirectionVersion()); - } - else if (nodeEntity.getType() == AVMNodeType.LAYERED_DIRECTORY) - { - node = new LayeredDirectoryNodeImpl(); - - ((LayeredDirectoryNodeImpl)node).setIndirection(nodeEntity.getIndirection()); - ((LayeredDirectoryNodeImpl)node).setIndirectionVersion(nodeEntity.getIndirectionVersion()); - ((LayeredDirectoryNodeImpl)node).setPrimaryIndirection(nodeEntity.isPrimaryIndirection()); - ((LayeredDirectoryNodeImpl)node).setLayerID(nodeEntity.getLayerId()); - ((LayeredDirectoryNodeImpl)node).setOpacity(nodeEntity.getOpacity()); - } - else if (nodeEntity.getType() == AVMNodeType.DELETED_NODE) - { - node = new DeletedNodeImpl(); - ((DeletedNodeImpl)node).setDeletedType(nodeEntity.getDeletedType()); - } - else - { - // belts-and-braces - throw new AlfrescoRuntimeException("Unexpected node type: "+nodeEntity.getType()); - } - - node.setId(nodeEntity.getId()); - node.setIsRoot(nodeEntity.isRoot()); - node.setGuid(nodeEntity.getGuid()); - node.setVersionID(nodeEntity.getVersion().intValue()); - node.setVers(nodeEntity.getVers()); - - BasicAttributes ba = new BasicAttributesImpl(); - ba.setAccessDate(nodeEntity.getAccessDate()); - ba.setModDate(nodeEntity.getModifiedDate()); - ba.setCreateDate(nodeEntity.getCreatedDate()); - ba.setLastModifier(nodeEntity.getModifier()); - ba.setCreator(nodeEntity.getCreator()); - ba.setOwner(nodeEntity.getOwner()); - - node.setBasicAttributes(ba); - - AVMStore store = null; - if (withStore) - { - if (nodeEntity.getStoreNewId() != null) - { - store = AVMDAOs.Instance().fAVMStoreDAO.getByID(nodeEntity.getStoreNewId()); - } - } - - node.setStoreNew(store); - - Acl acl = null; - if (nodeEntity.getAclId() != null) - { - acl = AVMDAOs.Instance().fAclDAO.getAcl(nodeEntity.getAclId()); - } - node.setAcl(acl); - - return node; - } -} diff --git a/source/java/org/alfresco/repo/avm/ibatis/AVMStoreDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/AVMStoreDAOIbatis.java deleted file mode 100644 index 3da2dcaeca..0000000000 --- a/source/java/org/alfresco/repo/avm/ibatis/AVMStoreDAOIbatis.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm.ibatis; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMNode; -import org.alfresco.repo.avm.AVMStore; -import org.alfresco.repo.avm.AVMStoreDAO; -import org.alfresco.repo.avm.AVMStoreImpl; -import org.alfresco.repo.avm.DirectoryNode; -import org.alfresco.repo.domain.avm.AVMStoreEntity; -import org.alfresco.repo.domain.permissions.Acl; -import org.alfresco.service.cmr.avm.AVMException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * iBATIS DAO wrapper for AVMStore - * - * @author janv - */ -class AVMStoreDAOIbatis implements AVMStoreDAO -{ - private static Log logger = LogFactory.getLog(AVMStoreDAOIbatis.class); - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#save(org.alfresco.repo.avm.AVMStore) - */ - public void save(AVMStore store) - { - AVMStoreEntity storeEntity = AVMDAOs.Instance().newAVMStoreDAO.createStore(store.getName()); - ((AVMStoreImpl)store).setId(storeEntity.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#delete(org.alfresco.repo.avm.AVMStore) - */ - public void delete(AVMStore store) - { - AVMDAOs.Instance().newAVMStoreDAO.deleteStore(store.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#getAll() - */ - public List getAll() - { - List storeEntities = AVMDAOs.Instance().newAVMStoreDAO.getAllStores(); - List result = new ArrayList(storeEntities.size()); - for (AVMStoreEntity storeEntity : storeEntities) - { - result.add(getByID(storeEntity.getId())); - } - return result; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#getByName(java.lang.String) - */ - public AVMStore getByName(String name) - { - AVMStoreEntity storeEntity = AVMDAOs.Instance().newAVMStoreDAO.getStore(name); - return convertStoreEntityToStore(storeEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#getByRoot(org.alfresco.repo.avm.AVMNode) - */ - public AVMStore getByRoot(AVMNode root) - { - AVMStoreEntity storeEntity = AVMDAOs.Instance().newAVMStoreDAO.getStoreByRoot(root.getId()); - return convertStoreEntityToStore(storeEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#update(org.alfresco.repo.avm.AVMStore) - */ - public void update(AVMStore store) - { - AVMStoreEntity storeEntity = convertStoreToStoreEntity(store); - AVMDAOs.Instance().newAVMStoreDAO.updateStore(storeEntity); - ((AVMStoreImpl)store).setVers(storeEntity.getVers()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#getByID(long) - */ - public AVMStore getByID(long id) - { - AVMStoreEntity storeEntity = AVMDAOs.Instance().newAVMStoreDAO.getStore(id); - return convertStoreEntityToStore(storeEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStoreDAO#invalidateCache() - */ - public void invalidateCache() - { - AVMDAOs.Instance().newAVMStoreDAO.clearStoreEntityCache(); - } - - private AVMStore convertStoreEntityToStore(AVMStoreEntity storeEntity) - { - if (storeEntity == null) - { - return null; - } - - AVMStoreImpl store = new AVMStoreImpl(); - store.setId(storeEntity.getId()); - store.setName(storeEntity.getName()); - - store.setNextVersionID(storeEntity.getVersion().intValue()); - store.setVers(storeEntity.getVers()); - - Acl acl = null; - if (storeEntity.getAclId() != null) - { - acl = AVMDAOs.Instance().fAclDAO.getAcl(storeEntity.getAclId()); - } - store.setStoreAcl(acl); - - Long rootNodeId = storeEntity.getRootNodeId(); - if (rootNodeId == null) - { - if (logger.isWarnEnabled()) - { - logger.warn("Root node id is null for store: "+storeEntity); - } - throw new AVMException(storeEntity.toString()); - } - - DirectoryNode rootNode = (DirectoryNode) ((AVMNodeDAOIbatis)AVMDAOs.Instance().fAVMNodeDAO).getRootNodeByID(store, rootNodeId); - if (rootNode == null) - { - // belts-and-braces - if (logger.isWarnEnabled()) - { - logger.warn("Root node ("+rootNodeId+") not found for store: "+storeEntity); - } - throw new AVMException(storeEntity.toString()); - } - - store.setRoot(rootNode); - - return store; - } - - private AVMStoreEntity convertStoreToStoreEntity(AVMStore store) - { - AVMStoreEntity storeEntity = new AVMStoreEntity(); - - storeEntity.setId(store.getId()); - storeEntity.setName(store.getName()); - storeEntity.setRootNodeId(store.getRoot().getId()); - storeEntity.setVersion(new Long(store.getNextVersionID())); - storeEntity.setVers(((AVMStoreImpl)store).getVers()); - storeEntity.setAclId((store.getStoreAcl() == null ? null : store.getStoreAcl().getId())); - - return storeEntity; - } -} diff --git a/source/java/org/alfresco/repo/avm/ibatis/AVMStorePropertyDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/AVMStorePropertyDAOIbatis.java deleted file mode 100644 index d81a183214..0000000000 --- a/source/java/org/alfresco/repo/avm/ibatis/AVMStorePropertyDAOIbatis.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm.ibatis; - -import java.util.Map; - -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMStore; -import org.alfresco.repo.avm.AVMStoreProperty; -import org.alfresco.repo.avm.AVMStorePropertyDAO; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.service.namespace.QName; - -/** - * iBATIS DAO wrapper for AVMStoreProperty - * - * @author janv - */ -class AVMStorePropertyDAOIbatis implements AVMStorePropertyDAO -{ - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStorePropertyDAO#save(org.alfresco.repo.avm.AVMStoreProperty) - */ - public void save(AVMStoreProperty prop) - { - AVMDAOs.Instance().newAVMStoreDAO.createOrUpdateStoreProperty(prop.getStore().getId(), prop.getQname(), prop.getValue()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStorePropertyDAO#get(org.alfresco.repo.avm.AVMStore, org.alfresco.service.namespace.QName) - */ - public PropertyValue get(AVMStore store, QName name) - { - return AVMDAOs.Instance().newAVMStoreDAO.getStoreProperty(store.getId(), name); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStorePropertyDAO#get(org.alfresco.repo.avm.AVMStore) - */ - public Map get(AVMStore store) - { - return AVMDAOs.Instance().newAVMStoreDAO.getStoreProperties(store.getId()); - } - - /** - * Query store properties by key pattern. - * @param store The store. - * @param keyPattern An sql 'like' pattern wrapped up in a QName - * @return A List of matching AVMStoreProperties. - */ - public Map queryByKeyPattern(AVMStore store, QName keyPattern) - { - // Get the URI and LocalName parts - String uri = keyPattern.getNamespaceURI(); - if (uri == null || uri.length() == 0) - { - uri = "%"; - } - String localName = keyPattern.getLocalName(); - if (localName == null || localName.length() == 0) - { - localName = "%"; - } - - return AVMDAOs.Instance().newAVMStoreDAO.getStorePropertiesByStoreAndKeyPattern(store.getId(), uri, localName); - } - - /** - * Query all stores' properties by key pattern. - * @param keyPattern The sql 'like' pattern wrapped up in a QName - * @return A List of match AVMStoreProperties. - */ - public Map> queryByKeyPattern(QName keyPattern) - { - // Get the URI and LocalName parts - String uri = keyPattern.getNamespaceURI(); - if (uri == null || uri.length() == 0) - { - uri = "%"; - } - String localName = keyPattern.getLocalName(); - if (localName == null || localName.length() == 0) - { - localName = "%"; - } - - return AVMDAOs.Instance().newAVMStoreDAO.getStorePropertiesByKeyPattern(uri, localName); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStorePropertyDAO#update(org.alfresco.repo.avm.AVMStoreProperty) - */ - public void update(AVMStoreProperty prop) - { - // NOOP - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStorePropertyDAO#delete(org.alfresco.repo.avm.AVMStore, org.alfresco.service.namespace.QName) - */ - public void delete(AVMStore store, QName name) - { - AVMDAOs.Instance().newAVMStoreDAO.deleteStoreProperty(store.getId(), name); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.AVMStorePropertyDAO#delete(org.alfresco.repo.avm.AVMStore) - */ - public void delete(AVMStore store) - { - AVMDAOs.Instance().newAVMStoreDAO.deleteStoreProperties(store.getId()); - } -} diff --git a/source/java/org/alfresco/repo/avm/ibatis/ChildEntryDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/ChildEntryDAOIbatis.java deleted file mode 100644 index 5a2a61296d..0000000000 --- a/source/java/org/alfresco/repo/avm/ibatis/ChildEntryDAOIbatis.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm.ibatis; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMNode; -import org.alfresco.repo.avm.ChildEntry; -import org.alfresco.repo.avm.ChildEntryDAO; -import org.alfresco.repo.avm.ChildEntryImpl; -import org.alfresco.repo.avm.ChildKey; -import org.alfresco.repo.avm.DirectoryNode; -import org.alfresco.repo.domain.avm.AVMChildEntryEntity; -import org.springframework.dao.ConcurrencyFailureException; - -/** - * iBATIS DAO wrapper for ChildEntry - * - * @author jan - */ -class ChildEntryDAOIbatis implements ChildEntryDAO -{ - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#save(org.alfresco.repo.avm.ChildEntry) - */ - public void save(ChildEntry entry) - { - AVMDAOs.Instance().newAVMNodeLinksDAO.createChildEntry(entry.getKey().getParent().getId(), entry.getKey().getName(), entry.getChild().getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#get(org.alfresco.repo.avm.ChildKey) - */ - public ChildEntry get(ChildKey key) - { - AVMChildEntryEntity childEntryEntity = AVMDAOs.Instance().newAVMNodeLinksDAO.getChildEntry(key.getParent().getId(), key.getName()); - return getChildEntryForParent(key.getParent(), childEntryEntity); - - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#getByParent(org.alfresco.repo.avm.DirectoryNode, java.lang.String) - */ - public List getByParent(DirectoryNode parent, String childNamePattern) - { - List childEntryEntities = AVMDAOs.Instance().newAVMNodeLinksDAO.getChildEntriesByParent(parent.getId(), childNamePattern); - - List result = new ArrayList(childEntryEntities.size()); - for (AVMChildEntryEntity childEntryEntity : childEntryEntities) - { - result.add(getChildEntryForParent(parent, childEntryEntity)); - } - - return result; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#getByParentChild(org.alfresco.repo.avm.DirectoryNode, org.alfresco.repo.avm.AVMNode) - */ - public boolean existsParentChild(DirectoryNode parent, AVMNode child) - { - AVMChildEntryEntity childEntryEntity = AVMDAOs.Instance().newAVMNodeLinksDAO.getChildEntry(parent.getId(), child.getId()); - return (childEntryEntity != null); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#getByChild(org.alfresco.repo.avm.AVMNode) - */ - public List getByChild(AVMNode child) - { - List childEntryEntities = AVMDAOs.Instance().newAVMNodeLinksDAO.getChildEntriesByChild(child.getId()); - - List result = new ArrayList(childEntryEntities.size()); - for (AVMChildEntryEntity childEntryEntity : childEntryEntities) - { - result.add(getChildEntryForChild(child, childEntryEntity)); - } - - return result; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#rename(org.alfresco.repo.avm.ChildKey, String) - */ - public void rename(ChildKey key, String newName) - { - // direct rename should only be used if changing case - if (! key.getName().equalsIgnoreCase(newName)) - { - throw new AlfrescoRuntimeException("Invalid rename (can only change case"); - } - - AVMChildEntryEntity childEntryEntity = AVMDAOs.Instance().newAVMNodeLinksDAO.getChildEntry(key.getParent().getId(), key.getName()); - - childEntryEntity.setName(newName); - - AVMDAOs.Instance().newAVMNodeLinksDAO.updateChildEntry(childEntryEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#delete(org.alfresco.repo.avm.ChildEntry) - */ - public void delete(ChildEntry child) - { - AVMChildEntryEntity childEntryEntity = new AVMChildEntryEntity(); - childEntryEntity.setParentNodeId(child.getKey().getParent().getId()); - childEntryEntity.setName(child.getKey().getName()); - childEntryEntity.setChildNodeId(child.getChild().getId()); - - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteChildEntry(childEntryEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#deleteByParent(org.alfresco.repo.avm.AVMNode) - */ - public void deleteByParent(AVMNode parent) - { - AVMDAOs.Instance().newAVMNodeLinksDAO.deleteChildEntriesByParent(parent.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.ChildEntryDAO#evict(org.alfresco.repo.avm.ChildEntry) - */ - public void evict(ChildEntry entry) - { - // NOOP - } - - private ChildEntry getChildEntryForParent(DirectoryNode parentNode, AVMChildEntryEntity childEntryEntity) - { - if (childEntryEntity == null) - { - return null; - } - - AVMNode childNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(childEntryEntity.getChildId()); - - if (childNode == null) - { - throw new ConcurrencyFailureException("Child node (" + childEntryEntity.getParentNodeId() + ", " + childEntryEntity.getChildId() + ") no longer exists"); - } - - ChildEntry ce = new ChildEntryImpl(new ChildKey(parentNode, childEntryEntity.getName()), childNode); - return ce; - } - - private ChildEntry getChildEntryForChild(AVMNode childNode, AVMChildEntryEntity childEntryEntity) - { - if (childEntryEntity == null) - { - return null; - } - - DirectoryNode parentNode = (DirectoryNode)AVMDAOs.Instance().fAVMNodeDAO.getByID(childEntryEntity.getParentNodeId()); - - if (parentNode == null) - { - throw new ConcurrencyFailureException("Parent node (" + childEntryEntity.getParentNodeId() + ", " + childEntryEntity.getChildId() + ") no longer exists"); - } - - ChildEntry ce = new ChildEntryImpl(new ChildKey(parentNode, childEntryEntity.getName()), childNode); - return ce; - } -} diff --git a/source/java/org/alfresco/repo/avm/ibatis/VersionLayeredNodeEntryDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/VersionLayeredNodeEntryDAOIbatis.java deleted file mode 100644 index c53cccc42b..0000000000 --- a/source/java/org/alfresco/repo/avm/ibatis/VersionLayeredNodeEntryDAOIbatis.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.avm.ibatis; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.VersionLayeredNodeEntry; -import org.alfresco.repo.avm.VersionLayeredNodeEntryDAO; -import org.alfresco.repo.avm.VersionLayeredNodeEntryImpl; -import org.alfresco.repo.avm.VersionRoot; -import org.alfresco.repo.domain.avm.AVMVersionLayeredNodeEntryEntity; - -/** - * iBATIS DAO wrapper for VersionLayeredNodeEntry - * - * @author janv - */ -class VersionLayeredNodeEntryDAOIbatis implements VersionLayeredNodeEntryDAO -{ - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionLayeredNodeEntryDAO#delete(org.alfresco.repo.avm.VersionRoot) - */ - public void delete(VersionRoot version) - { - AVMDAOs.Instance().newAVMVersionRootDAO.deleteVersionLayeredNodeEntries(version.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionLayeredNodeEntryDAO#get(org.alfresco.repo.avm.VersionRoot) - */ - public List get(VersionRoot version) - { - List vlneEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getVersionLayeredNodeEntries(version.getId()); - - List vlnes = new ArrayList(vlneEntities.size()); - for(AVMVersionLayeredNodeEntryEntity vlneEntity : vlneEntities) - { - VersionLayeredNodeEntryImpl vlne = new VersionLayeredNodeEntryImpl(); - vlne.setVersion(version); - vlne.setMd5Sum(vlneEntity.getMd5sum()); - vlne.setPath(vlneEntity.getPath()); - - vlnes.add(vlne); - } - - return vlnes; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionLayeredNodeEntryDAO#save(org.alfresco.repo.avm.VersionLayeredNodeEntry) - */ - public void save(VersionLayeredNodeEntry entry) - { - AVMDAOs.Instance().newAVMVersionRootDAO.createVersionLayeredNodeEntry(entry.getVersion().getId(), entry.getMd5Sum(), entry.getPath()); - } -} diff --git a/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java deleted file mode 100644 index 3abcde681d..0000000000 --- a/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm.ibatis; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMNode; -import org.alfresco.repo.avm.AVMStore; -import org.alfresco.repo.avm.DirectoryNode; -import org.alfresco.repo.avm.VersionRoot; -import org.alfresco.repo.avm.VersionRootDAO; -import org.alfresco.repo.avm.VersionRootImpl; -import org.alfresco.repo.domain.avm.AVMVersionRootEntity; - -/** - * iBATIS DAO wrapper for VersionRoot - * - * @author janv - */ -class VersionRootDAOIbatis implements VersionRootDAO -{ - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#save(org.alfresco.repo.avm.VersionRoot) - */ - public void save(VersionRoot vr) - { - AVMVersionRootEntity vrEntity = AVMDAOs.Instance().newAVMVersionRootDAO.createVersionRoot( - vr.getAvmStore().getId(), - vr.getRoot().getId(), - vr.getVersionID(), - vr.getCreator(), - vr.getTag(), - vr.getDescription()); - - ((VersionRootImpl)vr).setId(vrEntity.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#update(org.alfresco.repo.avm.VersionRoot) - */ - public void update(VersionRoot vr) - { - // note: tag and description only - AVMDAOs.Instance().newAVMVersionRootDAO.updateVersionRoot(convertVersionRootToVersionRootEntity(vr)); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#delete(org.alfresco.repo.avm.VersionRoot) - */ - public void delete(VersionRoot vr) - { - AVMDAOs.Instance().newAVMVersionRootDAO.deleteVersionRoot(vr.getId()); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#getAllInAVMStore(org.alfresco.repo.avm.AVMStore) - */ - public List getAllInAVMStore(AVMStore store) - { - List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getAllInStore(store.getId()); - List vrs = new ArrayList(vrEntities.size()); - for (AVMVersionRootEntity vrEntity : vrEntities) - { - vrs.add(convertVersionRootEntityToVersionRoot(vrEntity)); - } - return vrs; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#getByDates(org.alfresco.repo.avm.AVMStore, java.util.Date, java.util.Date) - */ - public List getByDates(AVMStore store, Date from, Date to) - { - List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByDates(store.getId(), from, to); - List vrs = new ArrayList(vrEntities.size()); - for (AVMVersionRootEntity vrEntity : vrEntities) - { - vrs.add(convertVersionRootEntityToVersionRoot(vrEntity)); - } - return vrs; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#getByVersionID(org.alfresco.repo.avm.AVMStore, int) - */ - public synchronized VersionRoot getByVersionID(AVMStore store, int id) - { - AVMVersionRootEntity vrEntity = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionID(store.getId(), id); - return convertVersionRootEntityToVersionRoot(vrEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#getByRoot(org.alfresco.repo.avm.AVMNode) - */ - public VersionRoot getByRoot(AVMNode root) - { - AVMVersionRootEntity vrEntity = AVMDAOs.Instance().newAVMVersionRootDAO.getByRoot(root.getId()); - return convertVersionRootEntityToVersionRoot(vrEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#getMaxVersion(org.alfresco.repo.avm.AVMStore) - */ - public VersionRoot getMaxVersion(AVMStore rep) - { - AVMVersionRootEntity vrEntity = AVMDAOs.Instance().newAVMVersionRootDAO.getMaxVersion(rep.getId()); - return convertVersionRootEntityToVersionRoot(vrEntity); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.avm.VersionRootDAO#getMaxVersionID(org.alfresco.repo.avm.AVMStore) - */ - public Integer getMaxVersionID(AVMStore store) - { - Long maxVersionId = AVMDAOs.Instance().newAVMVersionRootDAO.getMaxVersionID(store.getId()); - if (maxVersionId == null) - { - return null; - } - return new Integer(maxVersionId.intValue()); - } - - - - public List getByVersionsTo(AVMStore store, int version) - { - List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionsTo(store.getId(), version); - List vrs = new ArrayList(vrEntities.size()); - for (AVMVersionRootEntity vrEntity : vrEntities) - { - vrs.add(convertVersionRootEntityToVersionRoot(vrEntity)); - } - return vrs; - } - - public List getByVersionsFrom(AVMStore store, int version) - { - List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionsFrom(store.getId(), version); - List vrs = new ArrayList(vrEntities.size()); - for (AVMVersionRootEntity vrEntity : vrEntities) - { - vrs.add(convertVersionRootEntityToVersionRoot(vrEntity)); - } - return vrs; - } - - - - public List getByVersionsBetween(AVMStore store, int startVersion, int endVersion) - { - List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionsBetween(store.getId(), startVersion, endVersion); - List vrs = new ArrayList(vrEntities.size()); - for (AVMVersionRootEntity vrEntity : vrEntities) - { - vrs.add(convertVersionRootEntityToVersionRoot(vrEntity)); - } - return vrs; - } - - private AVMVersionRootEntity convertVersionRootToVersionRootEntity(VersionRoot vr) - { - if (vr == null) - { - return null; - } - - AVMVersionRootEntity vrEntity = new AVMVersionRootEntity(); - vrEntity.setCreatedDate(vr.getCreateDate()); - vrEntity.setCreator(vr.getCreator()); - vrEntity.setDescription(vr.getDescription()); - vrEntity.setId(vr.getId()); - vrEntity.setRootNodeId(vr.getRoot().getId()); - vrEntity.setStoreId(vr.getAvmStore().getId()); - vrEntity.setTag(vr.getTag()); - vrEntity.setVersion(vr.getVersionID()); - - return vrEntity; - } - - private VersionRoot convertVersionRootEntityToVersionRoot(AVMVersionRootEntity vrEntity) - { - if (vrEntity == null) - { - return null; - } - - AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByID(vrEntity.getStoreId()); - AVMNode rootNode = AVMDAOs.Instance().fAVMNodeDAO.getByID(vrEntity.getRootNodeId()); - - VersionRootImpl vr = new VersionRootImpl( - store, - (DirectoryNode)rootNode, - vrEntity.getVersion().intValue(), - vrEntity.getCreatedDate(), - vrEntity.getCreator(), - vrEntity.getTag(), - vrEntity.getDescription()); - - vr.setId(vrEntity.getId()); - - return vr; - } -} diff --git a/source/java/org/alfresco/repo/avm/util/RawServices.java b/source/java/org/alfresco/repo/avm/util/RawServices.java deleted file mode 100644 index 2c2e25268a..0000000000 --- a/source/java/org/alfresco/repo/avm/util/RawServices.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm.util; - -import org.alfresco.repo.avm.LookupCache; -import org.alfresco.repo.content.ContentStore; -import org.alfresco.repo.security.authentication.AuthenticationContext; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.MimetypeService; -import org.alfresco.service.cmr.security.AuthorityService; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -/** - * Simple access to Raw versions of service singletons. - * @author britt - */ -public class RawServices implements ApplicationContextAware -{ - /** - * The instance of RawServices - */ - private static RawServices fgInstance; - - /** - * The Application Context. - */ - private ApplicationContext fContext; - - /** - * The AuthenticationContext. - */ - private AuthenticationContext fAuthenticationContext; - - /** - * The Content Service. - */ - private ContentService fContentService; - - /** - * The Mimetype Service. - */ - private MimetypeService fMimetypeService; - - /** - * The Dictionary Service. - */ - private DictionaryService fDictionaryService; - - /** - * The Content Store. - */ - private ContentStore fContentStore; - - /** - * The LookupCache. - */ - private LookupCache fLookupCache; - - /** - * The Authority Service. - */ - private AuthorityService fAuthorityService; - - /** - * Default constructor. - */ - public RawServices() - { - fgInstance = this; - } - - public static RawServices Instance() - { - return fgInstance; - } - - public void setApplicationContext(ApplicationContext applicationContext) - { - fContext = applicationContext; - } - - public AuthenticationContext getAuthenticationContext() - { - if (fAuthenticationContext == null) - { - fAuthenticationContext = - (AuthenticationContext)fContext.getBean("authenticationContext"); - } - return fAuthenticationContext; - } - - public ContentService getContentService() - { - if (fContentService == null) - { - fContentService = - (ContentService)fContext.getBean("contentService"); - } - return fContentService; - } - - public MimetypeService getMimetypeService() - { - if (fMimetypeService == null) - { - fMimetypeService = - (MimetypeService)fContext.getBean("mimetypeService"); - } - return fMimetypeService; - } - - public DictionaryService getDictionaryService() - { - if (fDictionaryService == null) - { - fDictionaryService = - (DictionaryService)fContext.getBean("dictionaryService"); - } - return fDictionaryService; - } - - public ContentStore getContentStore() - { - if (fContentStore == null) - { - fContentStore = - (ContentStore)fContext.getBean("fileContentStore"); - } - return fContentStore; - } - - public LookupCache getLookupCache() - { - if (fLookupCache == null) - { - fLookupCache = (LookupCache)fContext.getBean("lookupCache"); - } - return fLookupCache; - } - - public AuthorityService getAuthorityService() - { - if (fAuthorityService == null) - { - // TODO change this back to the unwrapped bean before production. - fAuthorityService = (AuthorityService)fContext.getBean("AuthorityService"); - } - return fAuthorityService; - } - - public ApplicationContext getContext() - { - return fContext; - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java deleted file mode 100644 index 30f54dc804..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMClearSubmittedHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm.wf; - -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; - - -/** - * No-op stub for the no longer used AVMSubmittedApsect. - */ -public class AVMClearSubmittedHandler extends JBPMSpringActionHandler -{ - private static final long serialVersionUID = 4113360751217684995L; - - /** - * Initialize service references. - * @param factory The BeanFactory to get references from. - */ - @Override - protected void initialiseHandler(BeanFactory factory) - { - } - - /** - * Do the actual work. - * @param executionContext The context to get stuff from. - */ - public void execute(ExecutionContext executionContext) throws Exception - { - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMDeployHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMDeployHandler.java deleted file mode 100644 index 7f7f6a50f3..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMDeployHandler.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm.wf; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.actions.AVMDeployWebsiteAction; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.workflow.jbpm.JBPMNode; -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.service.cmr.avm.deploy.DeploymentService; -import org.alfresco.wcm.sandbox.SandboxConstants; -import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; - - -/** - * Deploys the latest snapshot of the staging area the submission was for. - * - * @author Gavin Cornwell - */ -public class AVMDeployHandler extends JBPMSpringActionHandler -{ - private DeploymentService deploymentService; - private AVMService avmService; - private ActionService actionService; - private NodeService unprotectedNodeService; - private PermissionService unprotectedPermissionService; - - private static final String BEAN_DEPLOYMENT_SERVICE = "deploymentService"; - private static final String BEAN_AVM_SERVICE = "AVMService"; - private static final String BEAN_ACTION_SERVICE = "actionService"; - private static final String BEAN_NODE_SERVICE = "nodeService"; - private static final String BEAN_PERMISSION_SERVICE = "permissionService"; - - private static final long serialVersionUID = 5590265401983087178L; - private static final Log logger = LogFactory.getLog(AVMDeployHandler.class); - - /** - * Initialize service references. - * @param factory The BeanFactory to get references from. - */ - @Override - protected void initialiseHandler(BeanFactory factory) - { - this.deploymentService = (DeploymentService)factory.getBean(BEAN_DEPLOYMENT_SERVICE); - this.avmService = (AVMService)factory.getBean(BEAN_AVM_SERVICE); - this.actionService = (ActionService)factory.getBean(BEAN_ACTION_SERVICE); - this.unprotectedNodeService = (NodeService)factory.getBean(BEAN_NODE_SERVICE); - this.unprotectedPermissionService = (PermissionService)factory.getBean(BEAN_PERMISSION_SERVICE); - } - - /** - * Do the actual work. - * @param executionContext The context to get stuff from. - */ - public void execute(ExecutionContext executionContext) throws Exception - { - // determine if the auto deploy needs to be executed - Boolean autoDeploy = (Boolean)executionContext.getContextInstance().getVariable("wcmwf_autoDeploy"); - - if (logger.isDebugEnabled()) - { - String label = (String)executionContext.getContextInstance().getVariable("wcmwf_label"); - long workflowId = executionContext.getProcessInstance().getId(); - - logger.debug("autoDeploy state for submission (workflowid: jbpm$" + workflowId + - ", label: " + label + ") is: " + autoDeploy); - } - - if (autoDeploy != null && autoDeploy.booleanValue()) - { - // get the web project node for the submission - JBPMNode webProjNode = (JBPMNode)executionContext.getContextInstance().getVariable("wcmwf_webproject"); - NodeRef webProjectRef = webProjNode.getNodeRef(); - - // get the list of live servers for the project that have the auto deploy flag turned on - List servers = deploymentService.findLiveDeploymentServers(webProjectRef); - - // if there are servers do the deploy - if (servers.size() > 0) - { - // Get the staging store name - NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef(); - Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg); - String [] workflowStorePath = pkgPath.getSecond().split(":"); - String workflowStoreName = workflowStorePath[0]; - PropertyValue propVal = this.avmService.getStoreProperty(workflowStoreName, - SandboxConstants.PROP_WEBSITE_NAME); - String store = propVal.getStringValue(); - - if (logger.isDebugEnabled()) - logger.debug("Attempting auto deploy to store: " + store); - - // retrieve the latest snapshot number for the store - int snapshotVersionToDeploy = this.avmService.getLatestSnapshotID(store); - - // work out the path of the store that needs deploying - String pathToDeploy = store + ":/" + JNDIConstants.DIR_DEFAULT_WWW + - '/' + JNDIConstants.DIR_DEFAULT_APPBASE; - NodeRef websiteRef = AVMNodeConverter.ToNodeRef(snapshotVersionToDeploy, pathToDeploy); - - // create a deploymentattempt node to represent this deployment - String attemptId = GUID.generate(); - Map props = new HashMap(8, 1.0f); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTID, attemptId); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTTYPE, WCMAppModel.CONSTRAINT_LIVESERVER); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTSTORE, store); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTVERSION, snapshotVersionToDeploy); - props.put(WCMAppModel.PROP_DEPLOYATTEMPTTIME, new Date()); - NodeRef attempt = unprotectedNodeService.createNode(webProjectRef, - WCMAppModel.ASSOC_DEPLOYMENTATTEMPT, WCMAppModel.ASSOC_DEPLOYMENTATTEMPT, - WCMAppModel.TYPE_DEPLOYMENTATTEMPT, props).getChildRef(); - - // allow anyone to add child nodes to the deploymentattempt node - unprotectedPermissionService.setPermission(attempt, PermissionService.ALL_AUTHORITIES, - PermissionService.ADD_CHILDREN, true); - - // iterate round each server and fire off a deplyoment action - List selectedDeployToNames = new ArrayList(); - for (NodeRef serverRef: servers) - { - if (unprotectedNodeService.exists(serverRef)) - { - // get all properties of the target server - Map serverProps = unprotectedNodeService.getProperties(serverRef); - - String serverUri = AVMDeployWebsiteAction.calculateServerUri(serverProps); - String serverName = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERNAME); - if (serverName == null || serverName.length() == 0) - { - serverName = serverUri; - } - - // remember the servers deployed to - selectedDeployToNames.add(serverName); - - if (logger.isDebugEnabled()) - logger.debug("Auto deploying '" + websiteRef.toString() + "' to server: " + serverName); - - // create and execute the action asynchronously - Map args = new HashMap(1, 1.0f); - args.put(AVMDeployWebsiteAction.PARAM_WEBPROJECT, webProjectRef); - args.put(AVMDeployWebsiteAction.PARAM_SERVER, serverRef); - args.put(AVMDeployWebsiteAction.PARAM_ATTEMPT, attempt); - Action action = this.actionService.createAction(AVMDeployWebsiteAction.NAME, args); - this.actionService.executeAction(action, websiteRef, false, true); - } - } - - // now we know the list of selected servers set the property on the attempt node - unprotectedNodeService.setProperty(attempt, WCMAppModel.PROP_DEPLOYATTEMPTSERVERS, - (Serializable)selectedDeployToNames); - - // set the deploymentattempid property on the store this deployment was for - this.avmService.deleteStoreProperty(store, SandboxConstants.PROP_LAST_DEPLOYMENT_ID); - this.avmService.setStoreProperty(store, SandboxConstants.PROP_LAST_DEPLOYMENT_ID, - new PropertyValue(DataTypeDefinition.TEXT, attemptId)); - } - } - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMReleaseTestServerHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMReleaseTestServerHandler.java deleted file mode 100644 index acea3194f0..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMReleaseTestServerHandler.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm.wf; - -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.workflow.jbpm.JBPMNode; -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; - -/** - * Releases the test deploy server used by the workflow (if any). - * - * @author Gavin Cornwell - */ -public class AVMReleaseTestServerHandler extends JBPMSpringActionHandler -{ - private SearchService searchService; - private NodeService unprotectedNodeService; - - private static final String BEAN_NODE_SERVICE = "nodeService"; - private static final String BEAN_SEARCH_SERVICE = "searchService"; - - private static final long serialVersionUID = -202652488887586866L; - private static final Log logger = LogFactory.getLog(AVMReleaseTestServerHandler.class); - - /** - * Initialize service references. - * @param factory The BeanFactory to get references from. - */ - @Override - protected void initialiseHandler(BeanFactory factory) - { - this.searchService = (SearchService)factory.getBean(BEAN_SEARCH_SERVICE); - this.unprotectedNodeService = (NodeService)factory.getBean(BEAN_NODE_SERVICE); - } - - /** - * Do the actual work. - * @param executionContext The context to get stuff from. - */ - public void execute(ExecutionContext executionContext) throws Exception - { - // get the store name - NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef(); - Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg); - String [] workflowStorePath = pkgPath.getSecond().split(":"); - String workflowStoreName = workflowStorePath[0]; - - // get the web project node for the submission - JBPMNode webProjNode = (JBPMNode)executionContext.getContextInstance().getVariable("wcmwf_webproject"); - NodeRef webProjectRef = webProjNode.getNodeRef(); - - if (logger.isDebugEnabled()) - logger.debug("Looking for test server to release for store: " + workflowStoreName); - - // query for the allocated test server (if one) - NodeRef testServer = findAllocatedServer(webProjectRef, workflowStoreName); - - if (testServer != null) - { - // reset the allocatedto property on the test server node - this.unprotectedNodeService.setProperty(testServer, WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO, null); - - if (logger.isDebugEnabled()) - logger.debug("Released test server '" + testServer + "' from store: " + workflowStoreName); - } - else if (logger.isDebugEnabled()) - { - logger.debug("Store '" + workflowStoreName + "' didn't have an allocated test server to release"); - } - } - - private NodeRef findAllocatedServer(NodeRef webProjectRef, String store) - { - StringBuilder query = new StringBuilder("@"); - query.append(NamespaceService.WCMAPP_MODEL_PREFIX); - query.append("\\:"); - query.append(WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO.getLocalName()); - query.append(":\""); - query.append(store); - query.append("\""); - - ResultSet results = null; - NodeRef testServer = null; - try - { - // execute the query - results = this.searchService.query(webProjectRef.getStoreRef(), - SearchService.LANGUAGE_LUCENE, query.toString()); - - if (results.length() == 1) - { - testServer = results.getNodeRef(0); - } - else if (results.length() > 1) - { - // get the first one and warn that we found many! - testServer = results.getNodeRef(0); - - if (logger.isWarnEnabled()) - logger.warn("More than one allocated test server for store '" + - store + "' was found, should only be one, first one found returned!"); - } - } - finally - { - if (results != null) - { - results.close(); - } - } - - return testServer; - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMRemoveAllSrcWebappsHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMRemoveAllSrcWebappsHandler.java deleted file mode 100644 index 4f1266ec3f..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMRemoveAllSrcWebappsHandler.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.avm.wf; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.mbeans.VirtServerRegistry; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.util.RawServices; -import org.alfresco.repo.workflow.jbpm.JBPMNode; -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.util.Pair; -import org.alfresco.wcm.util.WCMUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.context.ApplicationContext; - -/** - * Remove all webapps in a sandbox - * - * @author Jon Cox - */ -public class AVMRemoveAllSrcWebappsHandler extends JBPMSpringActionHandler -{ - static final long serialVersionUID = 3004374776252613278L; - - private static Log logger = LogFactory.getLog(AVMRemoveAllSrcWebappsHandler.class); - - /** - * Initialize service references. - * @param factory The BeanFactory to get references from. - */ - @Override - protected void initialiseHandler(BeanFactory factory) - { - } - - /** - * Do the actual work. - * @param executionContext The context to get stuff from. - */ - public void execute(ExecutionContext executionContext) throws Exception - { - String workflowName = executionContext.getProcessDefinition().getName(); - - // optimization: direct submits no longer virtualize the workflow sandbox - boolean isSubmitDirectWorkflowSandbox = ((workflowName != null) && (workflowName.equals(WCMUtil.WORKFLOW_SUBMITDIRECT_NAME))); - - if (logger.isDebugEnabled()) - { - logger.debug("AVMRemoveAllSrcWebappsHandler.execute: "+workflowName); - } - - if (! isSubmitDirectWorkflowSandbox) - { - // retrieve submitted package - NodeRef pkg = ((JBPMNode)executionContext.getContextInstance(). - getVariable("bpm_package")).getNodeRef(); - - Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg); - - Integer version = pkgPath.getFirst(); - String www_dir = pkgPath.getSecond(); - String appbase_dir = www_dir + "/" + JNDIConstants.DIR_DEFAULT_APPBASE; - - ApplicationContext springContext = RawServices.Instance().getContext(); - VirtServerRegistry vServerRegistry = (VirtServerRegistry) - springContext.getBean("VirtServerRegistry"); - - if (logger.isDebugEnabled()) - { - logger.debug("Sending JMX message to shut down workflow webapps: ["+version+", "+appbase_dir+"]"); - } - - vServerRegistry.removeAllWebapps( version, appbase_dir, true ); - - if (logger.isDebugEnabled()) - { - logger.debug("Sent JMX message to shut down workflow webapps: ["+version+", "+appbase_dir+"]"); - } - } - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java deleted file mode 100644 index bd413f8a88..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMRemoveWFStoreHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm.wf; - -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.workflow.jbpm.JBPMNode; -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.util.Pair; -import org.alfresco.wcm.sandbox.SandboxFactory; -import org.alfresco.wcm.util.WCMUtil; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; - - -/** - * Remove WF sandbox - * - * @author brittp - */ -public class AVMRemoveWFStoreHandler extends JBPMSpringActionHandler -{ - private static final long serialVersionUID = 4113360751217684995L; - - private SandboxFactory sandboxFactory; - - /** - * Initialize service references. - * @param factory The BeanFactory to get references from. - */ - @Override - protected void initialiseHandler(BeanFactory factory) - { - sandboxFactory = (SandboxFactory)factory.getBean("sandboxFactory"); - } - - /** - * Do the actual work. - * @param executionContext The context to get stuff from. - */ - public void execute(ExecutionContext executionContext) throws Exception - { - // TODO: Allow submit parameters to be passed into this action handler - // rather than pulling directly from execution context - - // retrieve submitted package - NodeRef pkg = ((JBPMNode)executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef(); - Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg); - - String workflowName = executionContext.getProcessDefinition().getName(); - - // optimization: direct submits no longer virtualize the workflow sandbox - final boolean isSubmitDirectWorkflowSandbox = ((workflowName != null) && (workflowName.equals(WCMUtil.WORKFLOW_SUBMITDIRECT_NAME))); - - // Now delete the stores in the WCM workflow sandbox - final String avmPath = pkgPath.getSecond(); - - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - sandboxFactory.deleteSandbox(WCMUtil.getSandboxStoreId(avmPath), isSubmitDirectWorkflowSandbox); - - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMSubmitHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMSubmitHandler.java deleted file mode 100644 index 9edef2cfd0..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMSubmitHandler.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . */ - -package org.alfresco.repo.avm.wf; - -import java.util.List; - -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.wcm.sandbox.SandboxConstants; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.service.cmr.avmsync.AVMSyncService; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; - -/** - * Performs a 'submit' operation: update from one sandbox layer to - * its corresponding staging sandbox. - * @author britt - */ -public class AVMSubmitHandler extends JBPMSpringActionHandler -{ - private static final long serialVersionUID = 7561005904505181493L; - - private static Log fgLogger = LogFactory.getLog(AVMSubmitHandler.class); - - /** - * The AVMSyncService. - */ - private AVMSyncService fAVMSyncService; - - /** - * The AVMService. - */ - private AVMService fAVMService; - - /** - * Set any bean references necessary. - * @param factory The BeanFactory from which to get beans. - */ - @Override - protected void initialiseHandler(BeanFactory factory) - { - fAVMSyncService = (AVMSyncService)factory.getBean("AVMSyncService"); - fAVMService = (AVMService)factory.getBean("AVMService"); - } - - /** - * Do the actual submit work. - * @param executionContext The jBPM context. - */ - public void execute(ExecutionContext executionContext) throws Exception - { - String avmSource = (String)executionContext.getContextInstance().getVariable("sourcePath"); - String [] storePath = avmSource.split(":"); - if (storePath.length != 2) - { - fgLogger.error("Malformed path: " + avmSource); - return; - } - String webSiteName = - fAVMService.getStoreProperty(storePath[0], SandboxConstants.PROP_WEBSITE_NAME). - getStringValue(); - String avmDest = webSiteName + ":" + storePath[1]; // note: it is implied that the website name is the same as staging name - List diffs = - fAVMSyncService.compare(-1, avmSource, -1, avmDest, null); - // TODO fix update comments if needed. - // Ignore conflicts and older nodes for now. - fAVMSyncService.update(diffs, null, true, true, false, false, null, null); - // Now flatten out the source. - fAVMSyncService.flatten(avmSource, avmDest); - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java b/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java deleted file mode 100644 index b80fa8527b..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMSubmitPackageHandler.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.avm.wf; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; - -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.workflow.jbpm.JBPMNode; -import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler; -import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.locking.AVMLockingService; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.service.cmr.avmsync.AVMSyncService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.util.Pair; -import org.alfresco.wcm.util.WCMUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jbpm.graph.exe.ExecutionContext; -import org.springframework.beans.factory.BeanFactory; - -public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements Serializable -{ - private static final long serialVersionUID = 4113360751217684995L; - - private static final Log logger = LogFactory.getLog(AVMSubmitPackageHandler.class); - - /** The AVMService instance. */ - private AVMService fAVMService; - - /** The AVMSyncService instance. */ - private AVMSyncService fAVMSyncService; - - /** The AVMLockingService instance. */ - private AVMLockingService fAVMLockingService; - - /** - * The AVMSubmitTransactionListener instance (for JMX notification of virtualization server after commit/rollback). - */ - private AVMSubmitTransactionListener fAVMSubmitTransactionListener; - - /** - * Initialize service references. - * - * @param factory - * The BeanFactory to get references from. - */ - @Override - protected void initialiseHandler(final BeanFactory factory) - { - fAVMService = (AVMService) factory.getBean(ServiceRegistry.AVM_SERVICE.getLocalName()); - fAVMSyncService = (AVMSyncService) factory.getBean(ServiceRegistry.AVM_SYNC_SERVICE.getLocalName()); - fAVMLockingService = (AVMLockingService) factory.getBean(ServiceRegistry.AVM_LOCKING_SERVICE.getLocalName()); - fAVMSubmitTransactionListener = (AVMSubmitTransactionListener) factory.getBean("AVMSubmitTransactionListener"); - - AlfrescoTransactionSupport.bindListener(fAVMSubmitTransactionListener); - } - - /** - * Do the actual work. - * - * @param executionContext - * The context to get stuff from. - */ - public void execute(final ExecutionContext executionContext) throws Exception - { - // TODO: Allow submit parameters to be passed into this action handler - // rather than pulling directly from execution context - final NodeRef pkg = ((JBPMNode) executionContext.getContextInstance().getVariable("bpm_package")).getNodeRef(); - final Pair pkgPath = AVMNodeConverter.ToAVMVersionPath(pkg); - final AVMNodeDescriptor pkgDesc = fAVMService.lookup(pkgPath.getFirst(), pkgPath.getSecond()); - - if (pkgDesc == null) - { - logger.warn("Submit skipped since workflow package does not exist: "+pkgPath); - } - else - { - final String from = (String) executionContext.getContextInstance().getVariable("wcmwf_fromPath"); - final String targetPath = pkgDesc.getIndirection(); - - if (logger.isDebugEnabled()) - { - logger.debug("handling submit of " + pkgPath.getSecond() + " from " + from + " to " + targetPath); - } - - // submit the package changes - final String description = (String) executionContext.getContextInstance().getVariable("bpm_workflowDescription"); - final String tag = (String) executionContext.getContextInstance().getVariable("wcmwf_label"); - - final String webProject = WCMUtil.getWebProject(fAVMService, AVMUtil.getStoreName(targetPath)); - - final List stagingDiffs = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, targetPath, null); - - // Allow AVMSubmitTransactionListener to inspect the staging diffs - // so it can notify the virtualization server via JMX if when this - // submit succeeds or fails. This allows virtual webapps devoted - // to the workarea to be destroyed, and staging to be updated in - // the event that some of the files alter the behavior of the - // webapp itself (e.g.: WEB-INF/web.xml, WEB-INF/lib/*.jar), etc. - - AlfrescoTransactionSupport.bindResource("staging_diffs", stagingDiffs); - - // Workflow does this as system as the staging area has restricted access and reviewers - // may not have permission to flatten the store the workflow was submitted from - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() - { - public Object doWork() throws Exception - { - fAVMSyncService.update(stagingDiffs, null, false, false, true, true, tag, description); - fAVMSyncService.flatten(pkgPath.getSecond(), targetPath); - - if (webProject != null) - { - for (final AVMDifference diff : stagingDiffs) - { - recursivelyRemoveLocks(webProject, -1, diff.getSourcePath()); - } - } - else - { - logger.warn("No webproject (hence no locks removed) for submit of " + pkgPath.getSecond() + " from " + from + " to " + targetPath); - } - - // flatten source folder where changes were submitted from - if (from != null && from.length() > 0) - { - // first, submit changes back to sandbox forcing addition of edits in workflow (and submission - // flag removal). second, flatten sandbox, removing modified items that have been submitted - // TODO: Without locking on the sandbox, it's possible that a change to a "submitted" item - // may get lost when the item is finally approved - final List sandboxDiffs = fAVMSyncService.compare(pkgPath.getFirst(), pkgPath.getSecond(), -1, from, null); - fAVMSyncService.update(sandboxDiffs, null, true, true, false, false, tag, description); - fAVMSyncService.flatten(from, targetPath); - } - - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - } - - /** - * Recursively remove locks from a path. Walking child folders looking for files to remove locks from. - */ - private void recursivelyRemoveLocks(String wpStoreId, int version, String wfPath) - { - AVMNodeDescriptor desc = fAVMService.lookup(version, wfPath, true); - if (desc.isFile() || desc.isDeletedFile()) - { - String relativePath = WCMUtil.getStoreRelativePath(wfPath); - - if (logger.isDebugEnabled()) - { - logger.debug("removing file lock on " + relativePath + " (store id: "+wpStoreId+")"); - } - - fAVMLockingService.removeLock(wpStoreId, relativePath); - } - else - { - if (desc.isDeletedDirectory() == false) - { - Map list = fAVMService.getDirectoryListing(desc, true); - for (AVMNodeDescriptor child : list.values()) - { - recursivelyRemoveLocks(wpStoreId, version, child.getPath()); - } - } - } - } -} diff --git a/source/java/org/alfresco/repo/avm/wf/AVMSubmitTransactionListener.java b/source/java/org/alfresco/repo/avm/wf/AVMSubmitTransactionListener.java deleted file mode 100644 index 24303a9b6c..0000000000 --- a/source/java/org/alfresco/repo/avm/wf/AVMSubmitTransactionListener.java +++ /dev/null @@ -1,147 +0,0 @@ -/*----------------------------------------------------------------------------- -* Copyright 2007-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see .* -* -* Author Jon Cox -* File AVMSubmitTransactionListener.java -*----------------------------------------------------------------------------*/ - -package org.alfresco.repo.avm.wf; - -import java.util.List; - -import org.alfresco.mbeans.VirtServerRegistry; -import org.alfresco.repo.avm.util.RawServices; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.TransactionListenerAdapter; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.util.VirtServerUtils; -import org.springframework.context.ApplicationContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** -* Gets callbacks at critical moments within a transaction -* (commit, rollback, etc.) to perform JMX update notifications -* to the virtualization server. -*/ -public class AVMSubmitTransactionListener extends TransactionListenerAdapter -{ - private static Log log = - LogFactory.getLog(AVMSubmitTransactionListener.class); - - public AVMSubmitTransactionListener() { } - - /** - * Notify virtualization server that webapps in workflow sandbox - * are not longer needed, and possibly trigger a notification - * instrucing the virtualization server to reload staging - * and every virtual webapp that depends on it. - */ - @Override - public void afterCommit() - { - List stagingDiffs = - (List) - AlfrescoTransactionSupport.getResource("staging_diffs"); - - if ( stagingDiffs == null) { return; } // TODO: log this? - - AVMDifference requiresUpdate = null; - - for (AVMDifference diff : stagingDiffs) - { - // Example values: - // - // diff.getSourceVersion() == -1; diff.getSourcePath() == - // mysite--workflow-21edf548-b17e-11db-bd90-35dd2ee4a5c6:/www/avm_webapps/ROOT/x.txt - // - // diff.getDestinationVersion() == -1; diff.getDestinationPath() == - // mysite:/www/avm_webapps/ROOT/x.txt - - if ( requiresUpdate == null ) - { - if ( VirtServerUtils.requiresUpdateNotification( diff.getDestinationPath() ) ) - { - requiresUpdate = diff; - } - } - } - - ApplicationContext springContext = RawServices.Instance().getContext(); - VirtServerRegistry vServerRegistry = (VirtServerRegistry) - springContext.getBean("VirtServerRegistry"); - - - - // TODO: In the future, we might want to allow a single submit to - // update multiple staging areas & versions. If so, - // the logic above will have to look for each unique - // version/webapp tuple, rather than assume everything - // is going into the same version and into the same - // store/webapp. - - - // Only update staging if necessary - if ( requiresUpdate != null ) - { - vServerRegistry.updateAllWebapps( requiresUpdate.getDestinationVersion(), - requiresUpdate.getDestinationPath(), - true - ); - if (log.isDebugEnabled()) - log.debug("JMX update to virt server called after commit." + - " Version: " + requiresUpdate.getDestinationVersion() + - " Path: " + requiresUpdate.getDestinationPath()); - } - - // Remove virtual webapps from workflow sandbox prior to - // AVMRemoveWFStoreHandler in the "process-end" clause. - // This way, even if the workflow is aborted, the JMX message - // to the virt server is still sent. Therefore, no longer - // doing this here: - // - // if ( ! stagingDiffs.isEmpty() ) - // { - // // All the files are from the same workflow sandbox; - // // so to remove all the webapps, you just need to - // // look at the 1st difference - // - // AVMDifference d = stagingDiffs.iterator().next(); - // vServerRegistry.removeAllWebapps( d.getSourceVersion(), - // d.getSourcePath(), true ); - // } - - AlfrescoTransactionSupport.unbindResource("staging_diffs"); - - if (log.isDebugEnabled()) - log.debug("staging_diff resource unbound after commit"); - } - - - /** - * Handle failed transaction. - */ - @Override - public void afterRollback() - { - AlfrescoTransactionSupport.unbindResource("staging_diffs"); - - if (log.isDebugEnabled()) - log.debug("staging_diff resource unbound after rollback"); - } -} diff --git a/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleaner.java b/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleaner.java index 392fee3025..ed995395f0 100644 --- a/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleaner.java +++ b/source/java/org/alfresco/repo/content/cleanup/ContentStoreCleaner.java @@ -1,430 +1,433 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.content.cleanup; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.TreeMap; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.domain.avm.AVMNodeDAO; -import org.alfresco.repo.domain.contentdata.ContentDataDAO; -import org.alfresco.repo.domain.contentdata.ContentDataDAO.ContentUrlHandler; -import org.alfresco.repo.lock.JobLockService; -import org.alfresco.repo.lock.LockAcquisitionException; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.Pair; -import org.alfresco.util.PropertyCheck; -import org.alfresco.util.VmShutdownListener; -import org.alfresco.util.VmShutdownListener.VmShutdownException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This component is responsible cleaning up orphaned content. - * - * Clean-up happens at two levels.

- * Eager cleanup: (since 3.2)

- * If {@link #setEagerOrphanCleanup(boolean) eager cleanup} is activated, then this - * component listens to all content property change events and recorded for post-transaction - * processing. All orphaned content is deleted from the registered store(s). Note that - * any {@link #setListeners(List) listeners} are called as normal; backup or scrubbing - * procedures should be plugged in as listeners if this is required. - *

- * Lazy cleanup:

- * This is triggered by means of a {@link ContentStoreCleanupJob Quartz job}. This process - * gets content URLs that have been marked as orphaned and cleans up the various stores. - * Once again, the listeners are called appropriately. - *

- * How backup policies are affected:

- * When restoring the system from a backup, the type of restore required is dictated by - * the cleanup policy being enforced. If eager cleanup is active, the system must
- * (a) have a listeners configured to backup the deleted content - * e.g. {@link DeletedContentBackupCleanerListener}, or
- * (b) ensure consistent backups across the database and content stores: backup - * when the system is not running; use a DB-based content store. This is the - * recommended route when running with eager cleanup. - *

- * Lazy cleanup protects the content for a given period (e.g. 7 days) giving plenty of - * time for a backup to be taken; this allows hot backup without needing metadata-content - * consistency to be enforced. - * - * @author Derek Hulley - */ -public class ContentStoreCleaner -{ - /* - * TODO: Use the ScheduledJobLockExecuter, which borrows (and fixes) some of the code use here - */ - - /** - * Enumeration of actions to take in the even that an orphaned binary fails to get deleted. - * Most stores are able to delete orphaned content, but it is possible that stores have - * protection against binary deletion that is outside of the Alfresco server's control. - * - * @author Derek Hulley - * @since 3.3.5 - */ - public enum DeleteFailureAction - { - /** - * Failure to clean up a binary is logged, but the URL is discarded for good i.e. - * there will be no further attempt to clean up the binary or any remaining record - * of its existence. - */ - IGNORE, - /** - * Failure to clean up the binary is logged and then a URL record is created with a - * orphan time of 0; there will be no further attempts to delete the URL binary, but - * the record will also not be destroyed. - */ - KEEP_URL; - } - - private static final QName LOCK_QNAME = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentStoreCleaner"); - private static final long LOCK_TTL = 30000L; - private static ThreadLocal> lockThreadLocal = new ThreadLocal>(); - - private static Log logger = LogFactory.getLog(ContentStoreCleaner.class); - - /** kept to notify the thread that it should quit */ - private static VmShutdownListener vmShutdownListener = new VmShutdownListener("ContentStoreCleaner"); - - private EagerContentStoreCleaner eagerContentStoreCleaner; - private JobLockService jobLockService; - private ContentDataDAO contentDataDAO; - private DictionaryService dictionaryService; - private ContentService contentService; - private AVMNodeDAO avmNodeDAO; - private TransactionService transactionService; - private int protectDays; - private DeleteFailureAction deletionFailureAction; - - public ContentStoreCleaner() - { - this.protectDays = 7; - this.deletionFailureAction = DeleteFailureAction.IGNORE; - } - - /** - * Set the component that will do the physical deleting - */ - public void setEagerContentStoreCleaner(EagerContentStoreCleaner eagerContentStoreCleaner) - { - this.eagerContentStoreCleaner = eagerContentStoreCleaner; - } - - /** - * @param jobLockService service used to ensure that cleanup runs are not duplicated - */ - public void setJobLockService(JobLockService jobLockService) - { - this.jobLockService = jobLockService; - } - - /** - * @param contentDataDAO DAO used for enumerating DM content URLs - */ - public void setContentDataDAO(ContentDataDAO contentDataDAO) - { - this.contentDataDAO = contentDataDAO; - } - - /** - * @param dictionaryService used to determine which properties are content properties - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * @param contentService service to copy content binaries - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - /** - * @param avmNodeDAO The AVM Node DAO to get urls with. - */ - public void setAvmNodeDAO(AVMNodeDAO avmNodeDAO) - { - this.avmNodeDAO = avmNodeDAO; - } - - /** - * @param transactionService the component to ensure proper transactional wrapping - */ - public void setTransactionService(TransactionService transactionService) - { - this.transactionService = transactionService; - } - - /** - * Set the minimum number of days old that orphaned content must be - * before deletion is possible. The default is 7 days. - * - * @param protectDays minimum age (in days) of deleted content - */ - public void setProtectDays(int protectDays) - { - this.protectDays = protectDays; - } - - /** - * Set the action to take in the event that an orphaned binary failed to get deleted. - * The default is {@link DeleteFailureAction#IGNORE}. - * - * @param deletionFailureAction the action to take when deletes fail - */ - public void setDeletionFailureAction(DeleteFailureAction deletionFailureAction) - { - this.deletionFailureAction = deletionFailureAction; - } - - /** - * Initializes the cleaner based on the {@link #setEagerOrphanCleanup(boolean) eagerCleanup} flag. - */ - public void init() - { - checkProperties(); - } - - /** - * Perform basic checks to ensure that the necessary dependencies were injected. - */ - private void checkProperties() - { - PropertyCheck.mandatory(this, "jobLockService", jobLockService); - PropertyCheck.mandatory(this, "contentDataDAO", contentDataDAO); - PropertyCheck.mandatory(this, "dictionaryService", dictionaryService); - PropertyCheck.mandatory(this, "contentService", contentService); - PropertyCheck.mandatory(this, "avmNodeDAO", avmNodeDAO); - PropertyCheck.mandatory(this, "transactionService", transactionService); - PropertyCheck.mandatory(this, "eagerContentStoreCleaner", eagerContentStoreCleaner); - - // check the protect days - if (protectDays < 0) - { - throw new AlfrescoRuntimeException("Property 'protectDays' must be 0 or greater (0 is not recommended)"); - } - else if (protectDays == 0) - { - logger.warn( - "Property 'protectDays' is set to 0. " + - "Please ensure that your backup strategy is appropriate for this setting."); - } - } - - /** - * Lazily update the job lock - */ - private void refreshLock() - { - Pair lockPair = lockThreadLocal.get(); - if (lockPair == null) - { - String lockToken = jobLockService.getLock(LOCK_QNAME, LOCK_TTL); - Long lastLock = new Long(System.currentTimeMillis()); - // We have not locked before - lockPair = new Pair(lastLock, lockToken); - lockThreadLocal.set(lockPair); - } - else - { - long now = System.currentTimeMillis(); - long lastLock = lockPair.getFirst().longValue(); - String lockToken = lockPair.getSecond(); - // Only refresh the lock if we are past a threshold - if (now - lastLock > (long)(LOCK_TTL/2L)) - { - jobLockService.refreshLock(lockToken, LOCK_QNAME, LOCK_TTL); - lastLock = System.currentTimeMillis(); - lockPair = new Pair(lastLock, lockToken); - lockThreadLocal.set(lockPair); - } - } - } - - /** - * Release the lock after the job completes - */ - private void releaseLock() - { - Pair lockPair = lockThreadLocal.get(); - if (lockPair != null) - { - // We can't release without a token - try - { - jobLockService.releaseLock(lockPair.getSecond(), LOCK_QNAME); - } - finally - { - // Reset - lockThreadLocal.set(null); - } - } - // else: We can't release without a token - } - - public void execute() - { - checkProperties(); - - // Bypass if the system is in read-only mode - if (transactionService.isReadOnly()) - { - logger.debug("Content store cleanup bypassed; the system is read-only."); - return; - } - - try - { - logger.debug("Content store cleanup started."); - refreshLock(); - executeInternal(); - // Done - if (logger.isDebugEnabled()) - { - logger.debug(" Content store cleanup completed."); - } - } - catch (LockAcquisitionException e) - { - // Job being done by another process - if (logger.isDebugEnabled()) - { - logger.debug(" Content store cleanup already underway."); - } - } - catch (VmShutdownException e) - { - // Aborted - if (logger.isDebugEnabled()) - { - logger.debug(" Content store cleanup aborted."); - } - } - finally - { - releaseLock(); - } - } - - private void executeInternal() - { - final long maxOrphanTime = System.currentTimeMillis() - (protectDays * 24 * 3600 * 1000L); - // execute in READ-WRITE txn - RetryingTransactionCallback getAndDeleteWork = new RetryingTransactionCallback() - { - public Long execute() throws Exception - { - return cleanBatch(maxOrphanTime, 1000); - }; - }; - while (true) - { - refreshLock(); - Long lastProcessedOrphanId = transactionService.getRetryingTransactionHelper().doInTransaction(getAndDeleteWork); - if (vmShutdownListener.isVmShuttingDown()) - { - throw new VmShutdownException(); - } - if (lastProcessedOrphanId == null) - { - // There is no more to process - break; - } - // There is still more to delete, so continue - if (logger.isDebugEnabled()) - { - logger.debug(" Removed orphaned content URLs up orphan time " + new Date(lastProcessedOrphanId)); - } - } - // Done - } - - /** - * - * @param minIdInclusive the min content URL ID (inclusive) - * @param maxTimeExclusive the max orphan time (exclusive) - * @param batchSize the maximum number of orphans to process - * @return Returns the last processed orphan ID or null if nothing was processed - */ - private Long cleanBatch(final long maxTimeExclusive, final int batchSize) - { - // Get a bunch of cleanable URLs - final TreeMap urlsById = new TreeMap(); - ContentUrlHandler contentUrlHandler = new ContentUrlHandler() - { - @Override - public void handle(Long id, String contentUrl, Long orphanTime) - { - urlsById.put(id, contentUrl); - } - }; - // Get a bunch of cleanable URLs - contentDataDAO.getContentUrlsOrphaned(contentUrlHandler, maxTimeExclusive, batchSize); - - // Shortcut, if necessary - if (urlsById.size() == 0) - { - return null; - } - - // Compile list of IDs and do a mass delete, recording the IDs to find the largest - Long lastId = urlsById.lastKey(); - List ids = new ArrayList(urlsById.keySet()); - contentDataDAO.deleteContentUrls(ids); - // No problems, so far (ALF-1998: contentStoreCleanerJob leads to foreign key exception) - - // Now attempt to physically delete the URLs - for (Long id : ids) - { - String contentUrl = urlsById.get(id); - // Handle failures - boolean deleted = eagerContentStoreCleaner.deleteFromStores(contentUrl); - if (!deleted) - { - switch (deletionFailureAction) - { - case KEEP_URL: - // Keep the URL, but with an orphan time of 0 so that it is recorded - contentDataDAO.createContentUrlOrphaned(contentUrl, new Date(0L)); - case IGNORE: - break; - default: - throw new IllegalStateException("Unknown deletion failure action: " + deletionFailureAction); - } - } - } - - // Done - return lastId; - } -} +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.content.cleanup; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TreeMap; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.domain.avm.AVMNodeDAO; +import org.alfresco.repo.domain.contentdata.ContentDataDAO; +import org.alfresco.repo.domain.contentdata.ContentDataDAO.ContentUrlHandler; +import org.alfresco.repo.lock.JobLockService; +import org.alfresco.repo.lock.LockAcquisitionException; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.Pair; +import org.alfresco.util.PropertyCheck; +import org.alfresco.util.VmShutdownListener; +import org.alfresco.util.VmShutdownListener.VmShutdownException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This component is responsible cleaning up orphaned content. + * + * Clean-up happens at two levels.

+ * Eager cleanup: (since 3.2)

+ * If {@link #setEagerOrphanCleanup(boolean) eager cleanup} is activated, then this + * component listens to all content property change events and recorded for post-transaction + * processing. All orphaned content is deleted from the registered store(s). Note that + * any {@link #setListeners(List) listeners} are called as normal; backup or scrubbing + * procedures should be plugged in as listeners if this is required. + *

+ * Lazy cleanup:

+ * This is triggered by means of a {@link ContentStoreCleanupJob Quartz job}. This process + * gets content URLs that have been marked as orphaned and cleans up the various stores. + * Once again, the listeners are called appropriately. + *

+ * How backup policies are affected:

+ * When restoring the system from a backup, the type of restore required is dictated by + * the cleanup policy being enforced. If eager cleanup is active, the system must
+ * (a) have a listeners configured to backup the deleted content + * e.g. {@link DeletedContentBackupCleanerListener}, or
+ * (b) ensure consistent backups across the database and content stores: backup + * when the system is not running; use a DB-based content store. This is the + * recommended route when running with eager cleanup. + *

+ * Lazy cleanup protects the content for a given period (e.g. 7 days) giving plenty of + * time for a backup to be taken; this allows hot backup without needing metadata-content + * consistency to be enforced. + * + * @author Derek Hulley + */ +public class ContentStoreCleaner +{ + /* + * TODO: Use the ScheduledJobLockExecuter, which borrows (and fixes) some of the code use here + */ + + /** + * Enumeration of actions to take in the even that an orphaned binary fails to get deleted. + * Most stores are able to delete orphaned content, but it is possible that stores have + * protection against binary deletion that is outside of the Alfresco server's control. + * + * @author Derek Hulley + * @since 3.3.5 + */ + public enum DeleteFailureAction + { + /** + * Failure to clean up a binary is logged, but the URL is discarded for good i.e. + * there will be no further attempt to clean up the binary or any remaining record + * of its existence. + */ + IGNORE, + /** + * Failure to clean up the binary is logged and then a URL record is created with a + * orphan time of 0; there will be no further attempts to delete the URL binary, but + * the record will also not be destroyed. + */ + KEEP_URL; + } + + private static final QName LOCK_QNAME = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentStoreCleaner"); + private static final long LOCK_TTL = 30000L; + private static ThreadLocal> lockThreadLocal = new ThreadLocal>(); + + private static Log logger = LogFactory.getLog(ContentStoreCleaner.class); + + /** kept to notify the thread that it should quit */ + private static VmShutdownListener vmShutdownListener = new VmShutdownListener("ContentStoreCleaner"); + + private EagerContentStoreCleaner eagerContentStoreCleaner; + private JobLockService jobLockService; + private ContentDataDAO contentDataDAO; + private DictionaryService dictionaryService; + private ContentService contentService; + private AVMNodeDAO avmNodeDAO; + private TransactionService transactionService; + private int protectDays; + private DeleteFailureAction deletionFailureAction; + + public ContentStoreCleaner() + { + this.protectDays = 7; + this.deletionFailureAction = DeleteFailureAction.IGNORE; + } + + /** + * Set the component that will do the physical deleting + */ + public void setEagerContentStoreCleaner(EagerContentStoreCleaner eagerContentStoreCleaner) + { + this.eagerContentStoreCleaner = eagerContentStoreCleaner; + } + + /** + * @param jobLockService service used to ensure that cleanup runs are not duplicated + */ + public void setJobLockService(JobLockService jobLockService) + { + this.jobLockService = jobLockService; + } + + /** + * @param contentDataDAO DAO used for enumerating DM content URLs + */ + public void setContentDataDAO(ContentDataDAO contentDataDAO) + { + this.contentDataDAO = contentDataDAO; + } + + /** + * @param dictionaryService used to determine which properties are content properties + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @param contentService service to copy content binaries + */ + public void setContentService(ContentService contentService) + { + this.contentService = contentService; + } + + /** + * @param avmNodeDAO The AVM Node DAO to get urls with. + */ + public void setAvmNodeDAO(AVMNodeDAO avmNodeDAO) + { + this.avmNodeDAO = avmNodeDAO; + } + + /** + * @param transactionService the component to ensure proper transactional wrapping + */ + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + /** + * Set the minimum number of days old that orphaned content must be + * before deletion is possible. The default is 7 days. + * + * @param protectDays minimum age (in days) of deleted content + */ + public void setProtectDays(int protectDays) + { + this.protectDays = protectDays; + } + + /** + * Set the action to take in the event that an orphaned binary failed to get deleted. + * The default is {@link DeleteFailureAction#IGNORE}. + * + * @param deletionFailureAction the action to take when deletes fail + */ + public void setDeletionFailureAction(DeleteFailureAction deletionFailureAction) + { + this.deletionFailureAction = deletionFailureAction; + } + + /** + * Initializes the cleaner based on the {@link #setEagerOrphanCleanup(boolean) eagerCleanup} flag. + */ + public void init() + { + checkProperties(); + } + + /** + * Perform basic checks to ensure that the necessary dependencies were injected. + */ + private void checkProperties() + { + PropertyCheck.mandatory(this, "jobLockService", jobLockService); + PropertyCheck.mandatory(this, "contentDataDAO", contentDataDAO); + PropertyCheck.mandatory(this, "dictionaryService", dictionaryService); + PropertyCheck.mandatory(this, "contentService", contentService); + + // Sparta: remove WCM/AVM + //PropertyCheck.mandatory(this, "avmNodeDAO", avmNodeDAO); + + PropertyCheck.mandatory(this, "transactionService", transactionService); + PropertyCheck.mandatory(this, "eagerContentStoreCleaner", eagerContentStoreCleaner); + + // check the protect days + if (protectDays < 0) + { + throw new AlfrescoRuntimeException("Property 'protectDays' must be 0 or greater (0 is not recommended)"); + } + else if (protectDays == 0) + { + logger.warn( + "Property 'protectDays' is set to 0. " + + "Please ensure that your backup strategy is appropriate for this setting."); + } + } + + /** + * Lazily update the job lock + */ + private void refreshLock() + { + Pair lockPair = lockThreadLocal.get(); + if (lockPair == null) + { + String lockToken = jobLockService.getLock(LOCK_QNAME, LOCK_TTL); + Long lastLock = new Long(System.currentTimeMillis()); + // We have not locked before + lockPair = new Pair(lastLock, lockToken); + lockThreadLocal.set(lockPair); + } + else + { + long now = System.currentTimeMillis(); + long lastLock = lockPair.getFirst().longValue(); + String lockToken = lockPair.getSecond(); + // Only refresh the lock if we are past a threshold + if (now - lastLock > (long)(LOCK_TTL/2L)) + { + jobLockService.refreshLock(lockToken, LOCK_QNAME, LOCK_TTL); + lastLock = System.currentTimeMillis(); + lockPair = new Pair(lastLock, lockToken); + lockThreadLocal.set(lockPair); + } + } + } + + /** + * Release the lock after the job completes + */ + private void releaseLock() + { + Pair lockPair = lockThreadLocal.get(); + if (lockPair != null) + { + // We can't release without a token + try + { + jobLockService.releaseLock(lockPair.getSecond(), LOCK_QNAME); + } + finally + { + // Reset + lockThreadLocal.set(null); + } + } + // else: We can't release without a token + } + + public void execute() + { + checkProperties(); + + // Bypass if the system is in read-only mode + if (transactionService.isReadOnly()) + { + logger.debug("Content store cleanup bypassed; the system is read-only."); + return; + } + + try + { + logger.debug("Content store cleanup started."); + refreshLock(); + executeInternal(); + // Done + if (logger.isDebugEnabled()) + { + logger.debug(" Content store cleanup completed."); + } + } + catch (LockAcquisitionException e) + { + // Job being done by another process + if (logger.isDebugEnabled()) + { + logger.debug(" Content store cleanup already underway."); + } + } + catch (VmShutdownException e) + { + // Aborted + if (logger.isDebugEnabled()) + { + logger.debug(" Content store cleanup aborted."); + } + } + finally + { + releaseLock(); + } + } + + private void executeInternal() + { + final long maxOrphanTime = System.currentTimeMillis() - (protectDays * 24 * 3600 * 1000L); + // execute in READ-WRITE txn + RetryingTransactionCallback getAndDeleteWork = new RetryingTransactionCallback() + { + public Long execute() throws Exception + { + return cleanBatch(maxOrphanTime, 1000); + }; + }; + while (true) + { + refreshLock(); + Long lastProcessedOrphanId = transactionService.getRetryingTransactionHelper().doInTransaction(getAndDeleteWork); + if (vmShutdownListener.isVmShuttingDown()) + { + throw new VmShutdownException(); + } + if (lastProcessedOrphanId == null) + { + // There is no more to process + break; + } + // There is still more to delete, so continue + if (logger.isDebugEnabled()) + { + logger.debug(" Removed orphaned content URLs up orphan time " + new Date(lastProcessedOrphanId)); + } + } + // Done + } + + /** + * + * @param minIdInclusive the min content URL ID (inclusive) + * @param maxTimeExclusive the max orphan time (exclusive) + * @param batchSize the maximum number of orphans to process + * @return Returns the last processed orphan ID or null if nothing was processed + */ + private Long cleanBatch(final long maxTimeExclusive, final int batchSize) + { + // Get a bunch of cleanable URLs + final TreeMap urlsById = new TreeMap(); + ContentUrlHandler contentUrlHandler = new ContentUrlHandler() + { + @Override + public void handle(Long id, String contentUrl, Long orphanTime) + { + urlsById.put(id, contentUrl); + } + }; + // Get a bunch of cleanable URLs + contentDataDAO.getContentUrlsOrphaned(contentUrlHandler, maxTimeExclusive, batchSize); + + // Shortcut, if necessary + if (urlsById.size() == 0) + { + return null; + } + + // Compile list of IDs and do a mass delete, recording the IDs to find the largest + Long lastId = urlsById.lastKey(); + List ids = new ArrayList(urlsById.keySet()); + contentDataDAO.deleteContentUrls(ids); + // No problems, so far (ALF-1998: contentStoreCleanerJob leads to foreign key exception) + + // Now attempt to physically delete the URLs + for (Long id : ids) + { + String contentUrl = urlsById.get(id); + // Handle failures + boolean deleted = eagerContentStoreCleaner.deleteFromStores(contentUrl); + if (!deleted) + { + switch (deletionFailureAction) + { + case KEEP_URL: + // Keep the URL, but with an orphan time of 0 so that it is recorded + contentDataDAO.createContentUrlOrphaned(contentUrl, new Date(0L)); + case IGNORE: + break; + default: + throw new IllegalStateException("Unknown deletion failure action: " + deletionFailureAction); + } + } + } + + // Done + return lastId; + } +} diff --git a/source/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java index e7c25b8bed..a420a4ddff 100644 --- a/source/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java +++ b/source/java/org/alfresco/repo/domain/permissions/ADMAccessControlListDAO.java @@ -26,7 +26,6 @@ import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.repo.domain.node.NodeIdAndAclId; -import org.alfresco.repo.domain.permissions.AVMAccessControlListDAO.CounterSet; import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.repo.security.permissions.ACLType; import org.alfresco.repo.security.permissions.AccessControlList; @@ -479,4 +478,76 @@ public class ADMAccessControlListDAO implements AccessControlListDAO } } } + + /** + * + * Counter for each type of ACL change + * @author andyh + * + */ + public static class CounterSet extends HashMap + { + /** + * + */ + private static final long serialVersionUID = -3682278258679211481L; + + CounterSet() + { + super(); + this.put(ACLType.DEFINING, new Counter()); + this.put(ACLType.FIXED, new Counter()); + this.put(ACLType.GLOBAL, new Counter()); + this.put(ACLType.LAYERED, new Counter()); + this.put(ACLType.OLD, new Counter()); + this.put(ACLType.SHARED, new Counter()); + } + + void add(ACLType type, Counter c) + { + Counter counter = get(type); + counter.add(c.getCounter()); + } + + void increment(ACLType type) + { + Counter counter = get(type); + counter.increment(); + } + + void add(CounterSet other) + { + add(ACLType.DEFINING, other.get(ACLType.DEFINING)); + add(ACLType.FIXED, other.get(ACLType.FIXED)); + add(ACLType.GLOBAL, other.get(ACLType.GLOBAL)); + add(ACLType.LAYERED, other.get(ACLType.LAYERED)); + add(ACLType.OLD, other.get(ACLType.OLD)); + add(ACLType.SHARED, other.get(ACLType.SHARED)); + } + } + + /** + * Simple counter + * @author andyh + * + */ + public static class Counter + { + int counter; + + void increment() + { + counter++; + } + + int getCounter() + { + return counter; + } + + void add(int i) + { + counter += i; + } + } } diff --git a/source/java/org/alfresco/repo/domain/permissions/AVMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/permissions/AVMAccessControlListDAO.java deleted file mode 100644 index 90eed13a5d..0000000000 --- a/source/java/org/alfresco/repo/domain/permissions/AVMAccessControlListDAO.java +++ /dev/null @@ -1,1216 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -package org.alfresco.repo.domain.permissions; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.AVMRepository; -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.domain.avm.AVMNodeDAO; -import org.alfresco.repo.domain.avm.AVMNodeEntity; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptorImpl.StoreType; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.permissions.ACLType; -import org.alfresco.repo.security.permissions.AccessControlEntry; -import org.alfresco.repo.security.permissions.AccessControlList; -import org.alfresco.repo.security.permissions.SimpleAccessControlListProperties; -import org.alfresco.repo.security.permissions.impl.AclChange; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.InvalidStoreRefException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.EqualsHelper; -import org.alfresco.util.Pair; -import org.alfresco.wcm.util.WCMUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * The AVM implementation for getting and setting ACLs. - * - * @author britt - */ -public class AVMAccessControlListDAO implements AccessControlListDAO -{ - private static Log s_logger = LogFactory.getLog(AVMAccessControlListDAO.class); - - private AVMRepository fAVMRepository; - private AVMService fAVMService; - private AclDAO aclDaoComponent; - private AVMNodeDAO avmNodeDAO; - - /** - * Set the AVM repository - * - * @param repository - */ - public void setAvmRepository(AVMRepository repository) - { - fAVMRepository = repository; - } - - /** - * Set the AVM service - * - * @param avmService - */ - public void setAvmService(AVMService avmService) - { - fAVMService = avmService; - } - - /** - * Set the ACL DAO component - * - * @param aclDAO - */ - public void setAclDAO(AclDAO aclDaoComponent) - { - this.aclDaoComponent = aclDaoComponent; - } - - public void setAvmNodeDAO(AVMNodeDAO avmNodeDAO) - { - this.avmNodeDAO = avmNodeDAO; - } - - - /** - * Default constructor - */ - public AVMAccessControlListDAO() - { - } - - public Long getIndirectAcl(NodeRef nodeRef) - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", nodeRef); - } - String path = avmVersionPath.getSecond(); - try - { - AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); - if (descriptor == null) - { - return null; - } - if (descriptor.isPrimary()) - { - Acl acl = getAclAsSystem(descriptor.getIndirectionVersion(), descriptor.getIndirection()); - if (acl == null) - { - return null; - } - else - { - return acl.getId(); - } - } - else - { - Acl acl = getAclAsSystem(version, path); - if (acl == null) - { - return null; - } - else - { - return acl.getId(); - } - } - } - catch (AVMException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - public Long getInheritedAcl(NodeRef nodeRef) - { - // TODO OK, for now we'll simply return the single parent that corresponds - // to the path stuffed in the NodeRef. - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - String path = avmVersionPath.getSecond(); - @SuppressWarnings("unused") - List result = new ArrayList(); - String[] splitPath = AVMNodeConverter.SplitBase(path); - if (splitPath[0] == null) - { - return null; - } - - Acl acl = getAclAsSystem(avmVersionPath.getFirst(), splitPath[0]); - if (acl == null) - { - return null; - } - else - { - return acl.getId(); - } - - } - - /** - * Get the ACL from a node. - * - * @param nodeRef - * The reference to the node. - * @return The ACL. - * @throws InvalidNodeRefException - */ - public Acl getAccessControlList(NodeRef nodeRef) - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - try - { - return getAclAsSystem(version, path); - } - catch (AVMException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - /** - * Set the ACL on a node. - * - * @param nodeRef - * The reference to the node. - * @param acl - * The ACL. - * @throws InvalidNodeRefException - */ - public void setAccessControlList(NodeRef nodeRef, Acl acl) - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", nodeRef); - } - String path = avmVersionPath.getSecond(); - try - { - setAclAsSystem(path, acl); - } - catch (AVMException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - public void setAccessControlList(NodeRef nodeRef, Long aclId) - { - throw new UnsupportedOperationException("Not implemented for AVM: setAccessControlList(NodeRef nodeRef, Long aclId)"); - } - - public void updateChangedAcls(NodeRef startingPoint, List changes) - { - // If their are no actual changes there is nothing to do (the changes are all in TX and have already COWed so - // they can just change) - - boolean hasChanges = false; - Long after = null; - for (AclChange change : changes) - { - if (change.getBefore() == null) - { - after = change.getAfter(); - } - else if (change.getTypeBefore() != change.getTypeAfter()) - { - after = change.getAfter(); - } - - if (!EqualsHelper.nullSafeEquals(change.getTypeBefore(), change.getTypeAfter())) - { - hasChanges = true; - } - if (!EqualsHelper.nullSafeEquals(change.getBefore(), change.getAfter())) - { - hasChanges = true; - } - } - - if (!hasChanges) - { - return; - } - - Long inherited = null; - if (after != null) - { - inherited = aclDaoComponent.getInheritedAccessControlList(after); - } - - AVMNodeDescriptor descriptor = getDesc(startingPoint); - Map> indirections = buildIndirections(descriptor); - updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after, indirections); - } - - private void updateChangedAclsImpl(NodeRef startingPoint, List changes, SetMode mode, Long inherited, Long setAcl, Map> indirections) - { - HashMap changeMap = new HashMap(); - HashSet unchangedSet = new HashSet(); - for (AclChange change : changes) - { - if (change.getBefore() == null) - { - // null is treated using the inherited acl - } - else if (!change.getBefore().equals(change.getAfter())) - { - changeMap.put(change.getBefore(), change.getAfter()); - } - else - { - unchangedSet.add(change.getBefore()); - } - } - unchangedSet.add(inherited); - unchangedSet.add(setAcl); - - if (inherited != null) - { - updateReferencingLayeredAcls(startingPoint, inherited, indirections); - } - updateInheritedChangedAcls(startingPoint, changeMap, unchangedSet, inherited, mode, indirections); - updateLayeredAclsChangedByInheritance(changes, changeMap, unchangedSet, indirections); - } - - public void forceCopy(NodeRef nodeRef) - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", nodeRef); - } - String path = avmVersionPath.getSecond(); - try - { - fAVMRepository.forceCopy(path); - } - catch (AVMException e) - { - throw new InvalidNodeRefException(nodeRef); - } - } - - private AVMNodeDescriptor getDesc(NodeRef node) - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(node); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", node); - } - String path = avmVersionPath.getSecond(); - try - { - AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); - return descriptor; - } - catch (AVMException e) - { - throw new InvalidNodeRefException(node); - } - } - - /** - * Support to describe AVM indirections for permission performance improvements when permissions are set. - * - * @author andyh - */ - public static class Indirection - { - Long from; - String to; - Integer toVersion; - - Indirection(Long from, String to, Integer toVersion) - { - this.from = from; - this.to = to; - this.toVersion = toVersion; - } - - /** - * @return - from id - */ - public Long getFrom() - { - return from; - } - - /** - * @return - to id - */ - public String getTo() - { - return to; - } - - /** - * @return - version - */ - public Integer getToVersion() - { - return toVersion; - } - } - - - /** - * Find layered directories Used to improve performance during patching and cascading the effect of permission - * changes between layers - * - * @return - layered directories - */ - private List getLayeredDirectories() - { - List ldNodeEntities = avmNodeDAO.getAllLayeredDirectories(); - - ArrayList indirections = new ArrayList(ldNodeEntities.size()); - - for (AVMNodeEntity ldNodeEntity : ldNodeEntities) - { - Long from = ldNodeEntity.getId(); - String to = ldNodeEntity.getIndirection(); - Integer version = ldNodeEntity.getIndirectionVersion(); - indirections.add(new Indirection(from, to, version)); - } - return indirections; - } - - /** - * Find layered files Used to improve performance during patching and cascading the effect of permission changes - * between layers - * - * @return - layered files - */ - private List getLayeredFiles() - { - List lfNodeEntities = avmNodeDAO.getAllLayeredFiles(); - - ArrayList indirections = new ArrayList(lfNodeEntities.size()); - - for (AVMNodeEntity lfNodeEntity : lfNodeEntities) - { - Long from = lfNodeEntity.getId(); - String to = lfNodeEntity.getIndirection(); - Integer version = lfNodeEntity.getIndirectionVersion(); - indirections.add(new Indirection(from, to, version)); - } - return indirections; - } - - private List getAvmIndirections() - { - List dirList = getLayeredDirectories(); - List fileList = getLayeredFiles(); - ArrayList answer = new ArrayList(dirList.size() + fileList.size()); - answer.addAll(dirList); - answer.addAll(fileList); - return answer; - } - - private Map> buildIndirections(AVMNodeDescriptor desc) - { - if ((desc != null) && (desc.getVersionID() == 1)) - { - String[] pathParts = AVMUtil.splitPath(desc.getPath()); - if ((pathParts[1].equals(AVMUtil.AVM_PATH_SEPARATOR+JNDIConstants.DIR_DEFAULT_WWW)) && (WCMUtil.isStagingStore(pathParts[0]))) - { - // WCM optimisation - skip when creating web project - return null; - } - } - return buildIndirections(); - } - - private Map> buildIndirections() - { - long start = System.currentTimeMillis(); - - Map> answer = new HashMap>(); - - List indirections = getAvmIndirections(); - for (Indirection indirection : indirections) - { - AVMNodeDescriptor toDesc = fAVMService.lookup(indirection.getToVersion(), indirection.getTo(), true); - if (toDesc != null) - { - Long toId = Long.valueOf(toDesc.getId()); - Set referees = answer.get(toId); - if (referees == null) - { - referees = new HashSet(); - answer.put(toId, referees); - } - referees.add(indirection.getFrom()); - } - } - - if (s_logger.isDebugEnabled()) - { - s_logger.debug("buildIndirections: ("+indirections.size()+", "+answer.size()+") in "+(System.currentTimeMillis()-start)+" msecs"); - } - return answer; - } - - private void updateReferencingLayeredAcls(NodeRef node, Long inherited, Map> indirections) - { - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(node); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", node); - } - String path = avmVersionPath.getSecond(); - try - { - AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); - if ((descriptor == null) || (indirections == null)) - { - return; - } - else - { - Set avmNodeIds = indirections.get(Long.valueOf(descriptor.getId())); - if (avmNodeIds != null) - { - for (Long id : avmNodeIds) - { - // need to fix up inheritance as is has changed - AVMNodeDescriptor layerDesc = new AVMNodeDescriptor(null, null, 0, null, null, null, 0, 0, 0, id, null, 0, null, 0, false, 0, false, 0, 0); - - List> layerPaths = fAVMRepository.getHeadPaths(layerDesc); - // Update all locations with the updated ACL - - for (Pair layerPath : layerPaths) - { - Acl target = getAclAsSystem(-1, layerPath.getSecond()); - if (target != null) - { - if (target.getAclType() == ACLType.LAYERED) - { - fAVMService.forceCopy(layerPath.getSecond()); - - List layeredChanges = aclDaoComponent.mergeInheritedAccessControlList(inherited, target.getId()); - NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, layerPath.getSecond()); - for (AclChange change : layeredChanges) - { - if (change.getBefore().equals(target.getId())) - { - Long newInherited = null; - if (change.getAfter() != null) - { - newInherited = aclDaoComponent.getInheritedAccessControlList(change.getAfter()); - } - updateChangedAclsImpl(layeredNode, layeredChanges, SetMode.DIRECT_ONLY, newInherited, change.getAfter(), indirections); - break; - } - } - } - } - } - } - } - } - } - catch (AVMException e) - { - throw new InvalidNodeRefException(node); - } - } - - private void updateLayeredAclsChangedByInheritance(List changes, HashMap changeMap, Set unchanged, Map> indirections) - { - for (AclChange change : changes) - { - if ((change.getTypeBefore() == ACLType.LAYERED) && (change.getTypeAfter() == ACLType.LAYERED)) - { - // Query for affected nodes - List avmNodeIds = aclDaoComponent.getAVMNodesByAcl(change.getBefore(), -1); - - for (Long id : avmNodeIds) - { - // Find all paths to the nodes - AVMNodeDescriptor desc = new AVMNodeDescriptor(null, null, 0, null, null, null, 0, 0, 0, id, null, 0, null, 0, false, 0, false, 0, 0); - List> paths = fAVMRepository.getHeadPaths(desc); - // Update all locations with the updated ACL - for (Pair path : paths) - { - // No need to force COW - any inherited ACL will have COWED if the top ACL required it - setAclAsSystem(path.getSecond(), aclDaoComponent.getAcl(change.getAfter())); - NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, path.getSecond()); - updateInheritedChangedAcls(layeredNode, changeMap, unchanged, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), SetMode.DIRECT_ONLY, - indirections); - } - } - } - } - } - - private void updateInheritedChangedAcls(NodeRef startingPoint, HashMap changeMap, Set unchanged, Long unsetAcl, SetMode mode, - Map> indirections) - { - // Walk children and fix up any that reference the given list .. - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(startingPoint); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", startingPoint); - } - String path = avmVersionPath.getSecond(); - try - { - AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); - if (descriptor == null) - { - return; - } - else - { - - if (descriptor.isLayeredDirectory()) - { - setInheritanceForDirectChildren(descriptor, changeMap, getAclAsSystem(-1, descriptor.getPath()).getId(), - indirections); - } - fixUpAcls(descriptor, changeMap, unchanged, unsetAcl, mode, indirections); - } - } - catch (AVMException e) - { - throw new InvalidNodeRefException(startingPoint); - } - } - - private void fixUpAcls(AVMNodeDescriptor descriptor, Map changes, Set unchanged, Long unsetAcl, SetMode mode, Map> indirections) - { - Acl acl = getAclAsSystem(-1, descriptor.getPath()); - Long id = null; - if (acl != null) - { - id = acl.getId(); - } - - if (id == null) - { - // No need to force COW - ACL should have COWed if required - setAclAsSystem(descriptor.getPath(), aclDaoComponent.getAcl(unsetAcl)); - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath()); - updateReferencingLayeredAcls(nodeRef, unsetAcl, indirections); - } - else if (changes.containsKey(id)) - { - Long updateId = changes.get(id); - if (!id.equals(updateId)) - { - Acl newAcl = aclDaoComponent.getAcl(updateId); - // No need to force COW - ACL should have COWed if required - setAclAsSystem(descriptor.getPath(), newAcl); - } - } - else if (unchanged.contains(id)) - { - // carry on - } - else - { - // Not in the list - return; - } - if (descriptor.isDirectory()) - { - Map children; - switch (mode) - { - case ALL: - children = fAVMService.getDirectoryListing(descriptor, false); - break; - case DIRECT_ONLY: - children = fAVMService.getDirectoryListingDirect(descriptor, false); - break; - default: - throw new IllegalStateException(); - } - for (AVMNodeDescriptor child : children.values()) - { - fixUpAcls(child, changes, unchanged, unsetAcl, mode, indirections); - } - } - - } - - private void setInheritanceForDirectChildren(AVMNodeDescriptor descriptor, Map changeMap, Long inheritFrom, Map> indirections) - { - List changes = new ArrayList(); - setFixedAcls(descriptor, inheritFrom, null, changes, SetMode.DIRECT_ONLY, false, indirections); - for (AclChange change : changes) - { - if (!change.getBefore().equals(change.getAfter())) - { - changeMap.put(change.getBefore(), change.getAfter()); - } - } - } - - public List setInheritanceForChildren(NodeRef parent, Long inheritFrom, Long sharedAclToReplace) - { - // Walk children and fix up any that reference the given list .. - // If previous is null we need to visit all descendants with a null acl and set - Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(parent); - int version = avmVersionPath.getFirst(); - if (version >= 0) - { - throw new InvalidNodeRefException("Read Only Node.", parent); - } - String path = avmVersionPath.getSecond(); - try - { - List changes = new ArrayList(); - AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); - Map> indirections = buildIndirections(descriptor); - setFixedAcls(descriptor, inheritFrom, null, changes, SetMode.ALL, false, indirections); - return changes; - - } - catch (AVMException e) - { - throw new InvalidNodeRefException(parent); - } - } - - /** - * Support to set a shared ACL on a node and all of its children. - * - * @param descriptor - * the descriptor - * @param inheritFrom - * the parent node's ACL - * @param mergeFrom - * the shared ACL, if already known. If null, will be retrieved / created lazily - * @param changes - * the list in which to record changes - * @param mode - * the mode - * @param set - * set the shared ACL on the parent ? - * @param indirections - * the indirections - */ - public void setFixedAcls(AVMNodeDescriptor descriptor, Long inheritFrom, Long mergeFrom, List changes, SetMode mode, boolean set, Map> indirections) - { - if (descriptor == null) - { - return; - } - else - { - if (set) - { - // Lazily retrieve/create the shared ACL - if (mergeFrom == null) - { - mergeFrom = aclDaoComponent.getInheritedAccessControlList(inheritFrom); - } - - // Simple set does not require any special COW wire up - // The AVM node will COW as required - Acl previous = getAclAsSystem(-1, descriptor.getPath()); - setAclAsSystem(descriptor.getPath(), aclDaoComponent.getAcl(mergeFrom)); - if (previous == null) - { - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath()); - updateReferencingLayeredAcls(nodeRef, mergeFrom, indirections); - } - } - - if (descriptor.isDirectory()) - { - Map children; - switch (mode) - { - case ALL: - children = fAVMService.getDirectoryListing(descriptor, false); - break; - case DIRECT_ONLY: - children = fAVMService.getDirectoryListingDirect(descriptor, false); - break; - default: - throw new IllegalStateException(); - } - - for (String key : children.keySet()) - { - // Lazily retrieve/create the shared ACL - if (mergeFrom == null) - { - mergeFrom = aclDaoComponent.getInheritedAccessControlList(inheritFrom); - } - - AVMNodeDescriptor child = children.get(key); - - Acl acl = getAclAsSystem(-1, child.getPath()); - - if (acl == null) - { - setFixedAcls(child, inheritFrom, mergeFrom, changes, mode, true, indirections); - } - else if (acl.getAclType() == ACLType.LAYERED) - { - // nothing to do - } - else if (acl.getAclType() == ACLType.DEFINING) - { - // Can require copy on right to be triggered for ACLS - // So we force a copy on write (which marks ACLS and below to copy if required) - fAVMService.forceCopy(child.getPath()); - - List newChanges = aclDaoComponent.mergeInheritedAccessControlList(mergeFrom, acl.getId()); - - for (AclChange change : newChanges) - { - if (change.getBefore().equals(acl.getId())) - { - setAclAsSystem(child.getPath(), aclDaoComponent.getAcl(change.getAfter())); - setFixedAcls(child, change.getAfter(), null, newChanges, SetMode.DIRECT_ONLY, false, indirections); - changes.addAll(newChanges); - break; - } - } - } - else - { - setFixedAcls(child, inheritFrom, mergeFrom, changes, mode, true, indirections); - } - } - } - } - } - - /** - * Mode to sue when setting ACLs - * @author andyh - * - */ - private enum SetMode - { - /** - * Set ALL - */ - ALL, - /** - * Set only direct children (not those present by layering) - */ - DIRECT_ONLY; - } - - public Map patchAcls() - { - CounterSet result = new CounterSet(); - List stores = fAVMService.getStores(); - Map> indirections = buildIndirections(); - for (AVMStoreDescriptor store : stores) - { - AVMNodeDescriptor root = fAVMService.getStoreRoot(-1, store.getName()); - CounterSet update; - - Map storeProperties = fAVMService.getStoreProperties(store.getName()); - - switch (StoreType.getStoreType(store.getName(), store, storeProperties)) - { - case AUTHOR: - case AUTHOR_PREVIEW: - case AUTHOR_WORKFLOW: - case AUTHOR_WORKFLOW_PREVIEW: - case STAGING: - case STAGING_PREVIEW: - case WORKFLOW: - case WORKFLOW_PREVIEW: - AVMNodeDescriptor www = fAVMService.lookup(-1, store.getName() + ":/www"); - if (www != null) - { - update = fixOldAvmAcls(www, false, indirections); - result.add(update); - } - else - { - update = fixOldAvmAcls(root, true, indirections); - result.add(update); - } - break; - case UNKNOWN: - default: - update = fixOldAvmAcls(root, true, indirections); - result.add(update); - } - - } - - HashMap toReturn = new HashMap(); - toReturn.put(ACLType.DEFINING, Integer.valueOf(result.get(ACLType.DEFINING).getCounter())); - toReturn.put(ACLType.FIXED, Integer.valueOf(result.get(ACLType.FIXED).getCounter())); - toReturn.put(ACLType.GLOBAL, Integer.valueOf(result.get(ACLType.GLOBAL).getCounter())); - toReturn.put(ACLType.LAYERED, Integer.valueOf(result.get(ACLType.LAYERED).getCounter())); - toReturn.put(ACLType.OLD, Integer.valueOf(result.get(ACLType.OLD).getCounter())); - toReturn.put(ACLType.SHARED, Integer.valueOf(result.get(ACLType.SHARED).getCounter())); - return toReturn; - } - - private CounterSet fixOldAvmAcls(AVMNodeDescriptor node, boolean searchDirectories, Map> indirections) - { - return fixOldAvmAclsImpl(node, searchDirectories, indirections); - } - - private CounterSet fixOldAvmAclsImpl(AVMNodeDescriptor node, boolean searchDirectories, Map> indirections) - { - CounterSet result = new CounterSet(); - // Do the children first - - if (searchDirectories && node.isDirectory()) - { - Map children = fAVMRepository.getListingDirect(node, true); - for (AVMNodeDescriptor child : children.values()) - { - CounterSet update = fixOldAvmAcls(child, searchDirectories, indirections); - result.add(update); - } - } - - Acl existingAcl = getAclAsSystem(-1, node.getPath()); - - if (existingAcl != null) - { - if (existingAcl.getAclType() == ACLType.OLD) - { - result.increment(ACLType.DEFINING); - // - SimpleAccessControlListProperties properties = new SimpleAccessControlListProperties(); - properties.setAclType(ACLType.DEFINING); - properties.setVersioned(true); - - Acl newAcl = aclDaoComponent.createAccessControlList(properties); - long id = newAcl.getId(); - - AccessControlList existing = aclDaoComponent.getAccessControlList(existingAcl.getId()); - for (AccessControlEntry entry : existing.getEntries()) - { - if (entry.getPosition() == 0) - { - aclDaoComponent.setAccessControlEntry(id, entry); - } - } - setAclAsSystem(node.getPath(), newAcl); - - // Cascade to children - changes should all be 1-1 so we do not have to post fix - - List changes = new ArrayList(); - - setFixedAcls(node, id, null, changes, SetMode.DIRECT_ONLY, false, indirections); - - for (AclChange change : changes) - { - if (!change.getBefore().equals(change.getAfter())) - { - s_logger.warn("ACL fix should not change the acl ids - unexpected COW!"); - } - - } - } - else - { - s_logger.warn("Skipping new style ACLs"); - } - } - else if (node.isLayeredDirectory()) - { - result.increment(ACLType.LAYERED); - // create layered permission entry - if (node.getIndirection() != null) - { - AVMNodeDescriptor referencedNode = fAVMService.lookup(-1, node.getIndirection(), false); - if ((referencedNode != null) && (referencedNode.isDirectory())) - { - Acl acl = getAclAsSystem(-1, referencedNode.getPath()); - if (acl != null) - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(acl.getId())); - } - else - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(null)); - } - } - else - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(null)); - } - } - else - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(null)); - } - List changes = new ArrayList(); - - setFixedAcls(node, getAclAsSystem(-1, node.getPath()).getId(), null, changes, SetMode.DIRECT_ONLY, false, indirections); - - for (AclChange change : changes) - { - if (!change.getBefore().equals(change.getAfter())) - { - s_logger.warn("ACL fix should not change the acl ids - unexpected COW!"); - } - - } - } - else if (node.isLayeredFile()) - { - result.increment(ACLType.LAYERED); - if (node.getIndirection() != null) - { - AVMNodeDescriptor referencedNode = fAVMService.lookup(-1, node.getIndirection(), false); - if (referencedNode != null) - { - Acl acl = getAclAsSystem(-1, referencedNode.getPath()); - if (acl != null) - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(acl.getId())); - } - else - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(null)); - } - } - else - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(null)); - } - } - else - { - setAclAsSystem(node.getPath(), aclDaoComponent.createLayeredAcl(null)); - } - List changes = new ArrayList(); - - setFixedAcls(node, getAclAsSystem(-1, node.getPath()).getId(), null, changes, SetMode.DIRECT_ONLY, false, indirections); - - for (AclChange change : changes) - { - if (!change.getBefore().equals(change.getAfter())) - { - throw new IllegalStateException("ACL fix should not change the acl ids - unexpected COW!"); - } - - } - } - return result; - } - - /** - * - * Counter for each type of ACL change - * @author andyh - * - */ - public static class CounterSet extends HashMap - { - /** - * - */ - private static final long serialVersionUID = -3682278258679211481L; - - CounterSet() - { - super(); - this.put(ACLType.DEFINING, new Counter()); - this.put(ACLType.FIXED, new Counter()); - this.put(ACLType.GLOBAL, new Counter()); - this.put(ACLType.LAYERED, new Counter()); - this.put(ACLType.OLD, new Counter()); - this.put(ACLType.SHARED, new Counter()); - } - - void add(ACLType type, Counter c) - { - Counter counter = get(type); - counter.add(c.getCounter()); - } - - void increment(ACLType type) - { - Counter counter = get(type); - counter.increment(); - } - - void add(CounterSet other) - { - add(ACLType.DEFINING, other.get(ACLType.DEFINING)); - add(ACLType.FIXED, other.get(ACLType.FIXED)); - add(ACLType.GLOBAL, other.get(ACLType.GLOBAL)); - add(ACLType.LAYERED, other.get(ACLType.LAYERED)); - add(ACLType.OLD, other.get(ACLType.OLD)); - add(ACLType.SHARED, other.get(ACLType.SHARED)); - } - } - - /** - * Simple counter - * @author andyh - * - */ - public static class Counter - { - int counter; - - void increment() - { - counter++; - } - - int getCounter() - { - return counter; - } - - void add(int i) - { - counter += i; - } - } - - private Acl getStoreAclAsSystem(final String storeName) - { - return AuthenticationUtil.runAs(new RunAsWork() - { - - public Acl doWork() throws Exception - { - return fAVMRepository.getStoreAcl(storeName); - } - }, AuthenticationUtil.getSystemUserName()); - } - - private void setStoreAclAsSystem(final String storeName, final Acl acl) - { - AuthenticationUtil.runAs(new RunAsWork() - { - - public Object doWork() throws Exception - { - fAVMRepository.setStoreAcl(storeName, acl); - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - - private Acl getAclAsSystem(final int version, final String path) - { - return AuthenticationUtil.runAs(new RunAsWork() - { - - public Acl doWork() throws Exception - { - return fAVMRepository.getACL(version, path); - } - }, AuthenticationUtil.getSystemUserName()); - } - - private void setAclAsSystem(final String path, final Acl acl) - { - AuthenticationUtil.runAs(new RunAsWork() - { - - public Object doWork() throws Exception - { - fAVMRepository.setACL(path, acl); - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - - public Acl getAccessControlList(StoreRef storeRef) - { - try - { - return getStoreAclAsSystem(storeRef.getIdentifier()); - } - catch (AVMException e) - { - throw new InvalidStoreRefException(storeRef); - } - } - - public void setAccessControlList(StoreRef storeRef, Acl acl) - { - try - { - setStoreAclAsSystem(storeRef.getIdentifier(), acl); - } - catch (AVMException e) - { - throw new InvalidStoreRefException(storeRef); - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.domain.AccessControlListDAO#updateInheritance(java.lang.Long, java.lang.Long, java.lang.Long) - */ - public void updateInheritance(Long childNodeId, Long oldParentNodeId, Long newParentNodeId) - { - throw new UnsupportedOperationException(); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.domain.permissions.AccessControlListDAO#setFixedAcls(java.lang.Long, java.lang.Long, java.lang.Long, java.lang.Long, java.util.List, boolean) - */ - @Override - public void setFixedAcls(Long nodeId, Long inheritFrom, Long mergeFrom, Long sharedAclToReplace, List changes, boolean set) - { - throw new UnsupportedOperationException(); - - } - -} diff --git a/source/java/org/alfresco/repo/domain/permissions/AbstractAclCrudDAOImpl.java b/source/java/org/alfresco/repo/domain/permissions/AbstractAclCrudDAOImpl.java index 1336cf5fcd..31d40cb7d4 100644 --- a/source/java/org/alfresco/repo/domain/permissions/AbstractAclCrudDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/permissions/AbstractAclCrudDAOImpl.java @@ -20,6 +20,7 @@ package org.alfresco.repo.domain.permissions; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -263,7 +264,9 @@ public abstract class AbstractAclCrudDAOImpl implements AclCrudDAO public List getAVMNodesByAcl(long aclEntityId, int maxResults) { - return getAVMNodeEntityIdsByAcl(aclEntityId, maxResults); + // Sparta: remove WCM/AVM + //return getAVMNodeEntityIdsByAcl(aclEntityId, maxResults); + return Collections.emptyList(); } public void updateAcl(AclUpdateEntity entity) diff --git a/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java b/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java deleted file mode 100644 index 4364c1eaa6..0000000000 --- a/source/java/org/alfresco/repo/node/index/AVMFullIndexRecoveryComponent.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.node.index; - -import java.util.LinkedHashMap; -import java.util.List; - -import org.alfresco.repo.node.index.FullIndexRecoveryComponent.RecoveryMode; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; -import org.alfresco.repo.search.IndexMode; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Check and recover the indexes for AVM stores - * - * @author andyh - */ -public class AVMFullIndexRecoveryComponent extends AbstractReindexComponent -{ - private static Log logger = LogFactory.getLog(AVMFullIndexRecoveryComponent.class); - - private RecoveryMode recoveryMode; - - private boolean lockServer; - - private AVMService avmService; - - private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; - - /** - * Set the type of recovery to perform. Default is {@link RecoveryMode#VALIDATE to validate} the indexes only. - * - * @param recoveryMode - * one of the {@link RecoveryMode } values - */ - public void setRecoveryMode(String recoveryMode) - { - this.recoveryMode = RecoveryMode.valueOf(recoveryMode); - } - - /** - * Set this on to put the server into READ-ONLY mode for the duration of the index recovery. The default is - * true, i.e. the server will be locked against further updates. - * - * @param lockServer - * true to force the server to be read-only - */ - public void setLockServer(boolean lockServer) - { - this.lockServer = lockServer; - } - - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) - { - this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; - } - - @Override - protected void reindexImpl() - { - processStores(); - } - - private void processStores() - { - List stores = avmService.getStores(); - LinkedHashMap actions = new LinkedHashMap(); - if (stores.size() == 0) - { - return; - } - switch (recoveryMode) - { - case AUTO: - case VALIDATE: - int count = 0; - int tracker = -1; - if (logger.isDebugEnabled()) - { - logger.debug("Checking indexes for AVM Stores: " + recoveryMode); - } - for (AVMStoreDescriptor store : stores) - { - if (isShuttingDown()) - { - return; - } - actions.put(store.getName(), checkStore(store.getName())); - count++; - if (count * 10l / stores.size() > tracker) - { - tracker = (int) (count * 10l / stores.size()); - if (logger.isDebugEnabled()) - { - logger.debug(" Store check " + (tracker * 10) + "% complete"); - } - } - } - if (logger.isDebugEnabled()) - { - logger.debug("Finished checking indexes for AVM Stores"); - } - break; - case FULL: - case NONE: - for (AVMStoreDescriptor store : stores) - { - if (isShuttingDown()) - { - return; - } - actions.put(store.getName(), checkStore(store.getName())); - } - break; - default: - } - - int full = 0; - int auto = 0; - int invalid = 0; - for (String store : actions.keySet()) - { - RecoveryMode mode = actions.get(store); - switch (mode) - { - case AUTO: - auto++; - break; - case FULL: - full++; - break; - case VALIDATE: - invalid++; - break; - case NONE: - default: - } - } - - if (recoveryMode != RecoveryMode.NONE) - { - if (logger.isDebugEnabled()) - { - logger.debug("Invalid indexes: " + invalid); - logger.debug("Indexes for full rebuild: " + full); - logger.debug("Indexes for auto update: " + auto); - } - } - - int count = 0; - int tracker = -1; - int total = full + auto; - if (total > 0) - { - logger.info("Rebuilding indexes for " + total + " AVM Stores"); - for (String store : actions.keySet()) - { - RecoveryMode mode = actions.get(store); - if (isShuttingDown()) - { - return; - } - if ((mode == RecoveryMode.FULL) || (mode == RecoveryMode.AUTO)) - { - processStore(store, mode); - count++; - } - if (count * 10l / total > tracker) - { - tracker = (int) (count * 10l / total); - logger.info(" Reindex " + (tracker * 10) + "% complete"); - } - } - logger.info("Finished rebuilding indexes for AVM Stores"); - } - - } - - private RecoveryMode checkStore(String store) - { - if (logger.isDebugEnabled()) - { - logger.debug("Checking AVM store for index recovery: " + recoveryMode + " on store " + store); - } - - // do we just ignore - if (recoveryMode == RecoveryMode.NONE) - { - return RecoveryMode.NONE; - } - - // Nothing to do for unindexed stores - if (avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(store) == IndexMode.UNINDEXED) - { - return RecoveryMode.NONE; - } - - if (recoveryMode == RecoveryMode.FULL) // no validate required - { - return RecoveryMode.FULL; - } - else - // validate first - { - if (!avmSnapShotTriggeredIndexingMethodInterceptor.hasIndexBeenCreated(store)) - { - logger.warn(" Index for avm store " + store + " is out of date"); - return recoveryMode; - } - int lastActualSnapshotId = avmService.getLatestSnapshotID(store); - if (lastActualSnapshotId <= 0) - { - return RecoveryMode.NONE; - } - int lastIndexedSnapshotId = avmSnapShotTriggeredIndexingMethodInterceptor.getLastIndexedSnapshot(store); - if (lastActualSnapshotId != lastIndexedSnapshotId) - { - logger.warn(" Index for avm store " + store + " is out of date"); - return recoveryMode; - } - else - { - return RecoveryMode.NONE; - } - } - - } - - private void processStore(String store, RecoveryMode mode) - { - - QName vetoName = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "AVMFullIndexRecoveryComponent"); - - // put the server into read-only mode for the duration - try - { - if (lockServer) - { - // set the server into read-only mode - transactionService.setAllowWrite(false, vetoName); - } - - recoverStore(store, mode); - - } - finally - { - // remove veto - transactionService.setAllowWrite(true, vetoName); - } - - } - - private void recoverStore(final String store, final RecoveryMode mode) - { - IndexMode storeIndexMode = avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(store); - if (storeIndexMode != IndexMode.UNINDEXED) - { - if (mode == RecoveryMode.AUTO) - { - logger.info(" Auto recovering index for " + store); - } - else if (mode == RecoveryMode.FULL) - { - logger.info(" Rebuilding index for " + store); - // delete existing index - RetryingTransactionCallback deleteWork = new RetryingTransactionCallback() - { - public Void execute() throws Exception - { - avmSnapShotTriggeredIndexingMethodInterceptor.deleteIndex(store); - return null; - } - }; - transactionService.getRetryingTransactionHelper().doInTransaction(deleteWork, true, true); - } - - final int latest = avmService.getLatestSnapshotID(store); - if (latest <= 0) - { - if (!avmSnapShotTriggeredIndexingMethodInterceptor.hasIndexBeenCreated(store)) - { - avmSnapShotTriggeredIndexingMethodInterceptor.createIndex(store); - } - return; - } - - final int latestIndexed = avmSnapShotTriggeredIndexingMethodInterceptor.getLastIndexedSnapshot(store); - - RetryingTransactionCallback reindexWork = new RetryingTransactionCallback() - { - public Object execute() throws Exception - { - if (mode == RecoveryMode.AUTO) - { - logger.info(" Rebuilding index for snapshots " + latestIndexed +" to "+latest); - avmSnapShotTriggeredIndexingMethodInterceptor.indexSnapshot(store, latestIndexed, latest); - - } - else - { - logger.info(" Rebuilding index for snapshots " + 0 +" to "+latest); - avmSnapShotTriggeredIndexingMethodInterceptor.indexSnapshot(store, 0, latest); - } - return null; - - } - }; - transactionService.getRetryingTransactionHelper().doInTransaction(reindexWork, true, true); - - if (logger.isDebugEnabled()) - { - logger.debug(" Index updated for " + store + "("+storeIndexMode.toString()+")"); - } - } - else - { - if (logger.isDebugEnabled()) - { - logger.debug(" Index skipped for " + store+ "("+storeIndexMode.toString()+")"); - } - } - } -} diff --git a/source/java/org/alfresco/repo/node/index/AVMRemoteSnapshotTracker.java b/source/java/org/alfresco/repo/node/index/AVMRemoteSnapshotTracker.java deleted file mode 100644 index 788f9e9f91..0000000000 --- a/source/java/org/alfresco/repo/node/index/AVMRemoteSnapshotTracker.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.node.index; - -import java.util.List; - -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; -import org.alfresco.repo.search.IndexMode; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Track and update when snapshots are created and indexed in a cluster - * - * @author Andy Hind - * @since 2.1.0 - */ -public class AVMRemoteSnapshotTracker extends AbstractReindexComponent -{ - private static Log logger = LogFactory.getLog(AVMRemoteSnapshotTracker.class); - - private AVMService avmService; - - private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; - - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) - { - this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; - } - - @Override - protected void reindexImpl() - { - processStores(); - } - - /** - * Loop throught the avm stores and compare the latest snapshot to that in the index. Update the index if it has - * fallen behind. - */ - private void processStores() - { - List stores = avmService.getStores(); - if (stores.size() == 0) - { - return; - } - - boolean upToDate; - do - { - upToDate = true; - for (AVMStoreDescriptor store : stores) - { - if (isShuttingDown()) - { - break; - } - - if (avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(store.getName()) != IndexMode.UNINDEXED) - { - int current = avmService.getLatestSnapshotID(store.getName()); - int lastIndexed = avmSnapShotTriggeredIndexingMethodInterceptor.getLastIndexedSnapshot(store.getName()); - - if (lastIndexed < current) - { - if (logger.isDebugEnabled()) - { - logger.debug("Reindexing snapshots for AVM store " + store.getName() + " from " + lastIndexed + " to " + current); - } - recoverSnapShot(store.getName(), lastIndexed, current); - upToDate = false; - } - } - } - if (upToDate) - { - if (logger.isDebugEnabled()) - { - logger.debug("Reindex check complete for AVM stores"); - } - } - } - while (!upToDate); - - } - - /** - * Do the index update in one lump (not individual snapshots) - * - * @param store - * @param lastIndexed - * @param current - */ - private void recoverSnapShot(final String store, final int lastIndexed, final int current) - { - - RetryingTransactionCallback reindexWork = new RetryingTransactionCallback() - { - public Object execute() throws Exception - { - if (lastIndexed == -1) - { - avmSnapShotTriggeredIndexingMethodInterceptor.createIndex(store); - } - avmSnapShotTriggeredIndexingMethodInterceptor.indexSnapshot(store, lastIndexed, current); - return null; - } - }; - transactionService.getRetryingTransactionHelper().doInTransaction(reindexWork, true); - } - -} diff --git a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java b/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java deleted file mode 100644 index 330a2cf647..0000000000 --- a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search; - -import java.util.List; - -import org.alfresco.repo.search.impl.lucene.AVMLuceneIndexer; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.namespace.QName; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -/** - * @author Andy - * - */ -public interface AVMSnapShotTriggeredIndexingMethodInterceptor extends MethodInterceptor -{ - - public final static QName PROP_SANDBOX_STAGING_MAIN = QName.createQName(null, ".sandbox.staging.main"); - - public final static QName PROP_SANDBOX_STAGING_PREVIEW = QName.createQName(null, ".sandbox.staging.preview"); - - public final static QName PROP_SANDBOX_AUTHOR_MAIN = QName.createQName(null, ".sandbox.author.main"); - - public final static QName PROP_SANDBOX_AUTHOR_PREVIEW = QName.createQName(null, ".sandbox.author.preview"); - - public final static QName PROP_SANDBOX_WORKFLOW_MAIN = QName.createQName(null, ".sandbox.workflow.main"); - - public final static QName PROP_SANDBOX_WORKFLOW_PREVIEW = QName.createQName(null, ".sandbox.workflow.preview"); - - public final static QName PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN = QName.createQName(null, ".sandbox.author.workflow.main"); - - public final static QName PROP_SANDBOX_AUTHOR_WORKFLOW_PREVIEW = QName.createQName(null, ".sandbox.author.workflow.preview"); - - @SuppressWarnings("unchecked") - public abstract Object invoke(MethodInvocation mi) throws Throwable; - - /** - * Set the AVM service - * - * @param avmService - */ - public abstract void setAvmService(AVMService avmService); - - /** - * Set the AVM indexer and searcher - * - * @param indexerAndSearcher - */ - public abstract void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher); - - /** - * Enable or disable indexing - * - * @param enableIndexing - */ - public abstract void setEnableIndexing(boolean enableIndexing); - - /** - * Set the index modes.... Strings of the form ... (ASYNCHRONOUS | SYNCHRONOUS | UNINDEXED):(NAME | TYPE):regexp - * - * @param definitions - */ - public abstract void setIndexingDefinitions(List definitions); - - /** - * Set the default index mode = used when there are no matches - * - * @param defaultMode - */ - public abstract void setDefaultMode(IndexMode defaultMode); - - /** - * Is snapshot triggered indexing enabled - * - * @return true if indexing is enabled for AVM - */ - public abstract boolean isIndexingEnabled(); - - /** - * @param store - * @param before - * @param after - */ - public abstract void indexSnapshot(String store, int before, int after); - - /** - * @param store - * @param after - */ - public abstract void indexSnapshot(String store, int after); - - /** - * @param store - * @return - the last indexed snapshot - */ - public abstract int getLastIndexedSnapshot(String store); - - /** - * Is the snapshot applied to the index? Is there an entry for any node that was added OR have all the nodes in the - * transaction been deleted as expected? - * - * @param store - * @param id - * @return - true if applied, false if not - */ - public abstract boolean isSnapshotIndexed(String store, int id); - - /** - * Check if the index is up to date according to its index defintion and that all asynchronous work is done. - * - * @param store - * @return - */ - public abstract boolean isIndexUpToDateAndSearchable(String store); - - /** - * Check if the index is up to date according to its index defintion i it does not check that all asynchronous work - * is done. - * - * @param store - * @return - */ - public abstract boolean isIndexUpToDate(String store); - - /** - * Given an avm store name determine if it is indexed and if so how. - * - * @param store - * @return - */ - public abstract IndexMode getIndexMode(String store); - - public abstract boolean hasIndexBeenCreated(String store); - - public abstract void createIndex(String store); - - public abstract AVMLuceneIndexer getIndexer(String store); - - public abstract void deleteIndex(String store); - -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptorImpl.java b/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptorImpl.java deleted file mode 100644 index 77cdd6b37b..0000000000 --- a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptorImpl.java +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.management.subsystems.SwitchableApplicationContextFactory; -import org.alfresco.repo.search.impl.lucene.AVMLuceneIndexer; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.QName; -import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Method interceptor for atomic indexing of AVM entries The properties can defined how stores are indexed based on type - * (as set by Alfresco the Web site management UI) or based on the name of the store. Creates and deletes are indexed - * synchronously. Updates may be asynchronous, synchronous or ignored by the index. - * - * @author andyh - */ -public class AVMSnapShotTriggeredIndexingMethodInterceptorImpl implements AVMSnapShotTriggeredIndexingMethodInterceptor -{ - private static Log logger = LogFactory.getLog(AVMSnapShotTriggeredIndexingMethodInterceptorImpl.class); - - // Copy of store properties used to tag avm stores (a store propertry) - - private AVMService avmService; - - private IndexerAndSearcher indexerAndSearcher; - - private boolean enableIndexing = true; - - private IndexMode defaultMode = IndexMode.ASYNCHRONOUS; - - private Map modeCache = new HashMap(); - - private List indexingDefinitions = new ArrayList(); - - private SwitchableApplicationContextFactory searchApplicationContextFactory; - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) - */ - @Override - @SuppressWarnings("unchecked") - public Object invoke(MethodInvocation mi) throws Throwable - { - if (enableIndexing) - { - if (mi.getMethod().getName().equals("createSnapshot")) - { - // May cause any number of other stores to do snap shot under the covers via layering or do nothing - // So we have to watch what actually changes - - Object returnValue = mi.proceed(); - - Map snapShots = (Map) returnValue; - - // Index any stores that have moved on - for (String store : snapShots.keySet()) - { - int after = snapShots.get(store).intValue(); - indexSnapshot(store, after); - } - return returnValue; - } - else if (mi.getMethod().getName().equals("purgeStore")) - { - String store = (String) mi.getArguments()[0]; - Object returnValue = mi.proceed(); - - if (getIndexMode(store) != IndexMode.UNINDEXED) - { - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("purgeStore " + store, new Exception("Stack Trace")); - } - avmIndexer.deleteIndex(store, IndexMode.SYNCHRONOUS); - } - } - return returnValue; - } - else if (mi.getMethod().getName().equals("createStore")) - { - String store = (String) mi.getArguments()[0]; - Object returnValue = mi.proceed(); - if (getIndexMode(store) != IndexMode.UNINDEXED) - { - createIndex(store); - } - return returnValue; - } - else if (mi.getMethod().getName().equals("renameStore")) - { - String from = (String) mi.getArguments()[0]; - String to = (String) mi.getArguments()[1]; - Object returnValue = mi.proceed(); - int after = avmService.getLatestSnapshotID(to); - - if (getIndexMode(from) != IndexMode.UNINDEXED) - { - AVMLuceneIndexer avmIndexer = getIndexer(from); - if (avmIndexer != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("renameStore deleteIndex " + from, new Exception("Stack Trace")); - } - avmIndexer.deleteIndex(from, IndexMode.SYNCHRONOUS); - } - } - - if (getIndexMode(to) != IndexMode.UNINDEXED) - { - AVMLuceneIndexer avmIndexer = getIndexer(to); - if (avmIndexer != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("renameStore createIndex " + to + "(0, " + after + ")", new Exception("Stack Trace")); - } - avmIndexer.createIndex(to, IndexMode.SYNCHRONOUS); - avmIndexer.index(to, 0, after, getIndexMode(to)); - } - } - return returnValue; - } - else - { - return mi.proceed(); - } - } - else - { - return mi.proceed(); - } - } - - - - /** - * @param searchApplicationContextFactory the searchApplicationContextFactory to set - */ - public void setSearchApplicationContextFactory(SwitchableApplicationContextFactory searchApplicationContextFactory) - { - this.searchApplicationContextFactory = searchApplicationContextFactory; - } - - - - /** - * @return the searchApplicationContextFactory - */ - public SwitchableApplicationContextFactory getSearchApplicationContextFactory() - { - return searchApplicationContextFactory; - } - - - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#setAvmService(org.alfresco.service.cmr.avm.AVMService) - */ - @Override - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#setIndexerAndSearcher(org.alfresco.repo.search.IndexerAndSearcher) - */ - @Override - public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher) - { - this.indexerAndSearcher = indexerAndSearcher; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#setEnableIndexing(boolean) - */ - @Override - public void setEnableIndexing(boolean enableIndexing) - { - this.enableIndexing = enableIndexing; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#setIndexingDefinitions(java.util.List) - */ - @Override - public void setIndexingDefinitions(List definitions) - { - indexingDefinitions.clear(); - for (String def : definitions) - { - IndexingDefinition id = new IndexingDefinition(def); - indexingDefinitions.add(id); - } - } - - - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#setDefaultMode(org.alfresco.repo.search.IndexMode) - */ - @Override - public void setDefaultMode(IndexMode defaultMode) - { - this.defaultMode = defaultMode; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#isIndexingEnabled() - */ - @Override - public boolean isIndexingEnabled() - { - return enableIndexing; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#indexSnapshot(java.lang.String, int, int) - */ - @Override - public void indexSnapshot(String store, int before, int after) - { - indexSnapshotImpl(store, before, after); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#indexSnapshot(java.lang.String, int) - */ - @Override - public void indexSnapshot(String store, int after) - { - indexSnapshotImpl(store, -1, after); - } - - private void indexSnapshotImpl(String store, int before, int after) - { - if (getIndexMode(store) != IndexMode.UNINDEXED) - { - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - int last = getLastIndexedSnapshot(avmIndexer, store); - - if ((last == -1) && (! hasIndexBeenCreated(store))) - { - createIndex(store); - // ALF-7845 - last = getLastIndexedSnapshot(avmIndexer, store); - } - - int from = before != -1 ? before : last; - - if (from > after) - { - if (logger.isTraceEnabled()) - { - logger.trace("skip indexSnapshotImpl " + store + " (" + (before == -1 ? "-1, " : "") + from +", " + after +")", new Exception("Stack Trace")); - } - } - else - { - if (logger.isDebugEnabled()) - { - logger.debug("indexSnapshotImpl " + store + " (" + (before == -1 ? "-1, " : "") + from +", " + after +")", new Exception("Stack Trace")); - } - avmIndexer.index(store, from, after, getIndexMode(store)); - } - } - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#getLastIndexedSnapshot(java.lang.String) - */ - @Override - public int getLastIndexedSnapshot(String store) - { - - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - return getLastIndexedSnapshot(avmIndexer, store); - } - return -1; - } - - private int getLastIndexedSnapshot(AVMLuceneIndexer avmIndexer, String store) - { - return avmIndexer.getLastIndexedSnapshot(store); - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#isSnapshotIndexed(java.lang.String, int) - */ - @Override - public boolean isSnapshotIndexed(String store, int id) - { - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - return avmIndexer.isSnapshotIndexed(store, id); - } - return false; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#isIndexUpToDateAndSearchable(java.lang.String) - */ - @Override - public boolean isIndexUpToDateAndSearchable(String store) - { - - switch (getIndexMode(store)) - { - case UNINDEXED: - return false; - case SYNCHRONOUS: - case ASYNCHRONOUS: - int last = avmService.getLatestSnapshotID(store); - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - avmIndexer.flushPending(); - return avmIndexer.isSnapshotSearchable(store, last); - } - return false; - default: - return false; - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#isIndexUpToDate(java.lang.String) - */ - @Override - public boolean isIndexUpToDate(String store) - { - switch (getIndexMode(store)) - { - case UNINDEXED: - return true; - case SYNCHRONOUS: - case ASYNCHRONOUS: - int last = avmService.getLatestSnapshotID(store); - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - avmIndexer.flushPending(); - return avmIndexer.isSnapshotIndexed(store, last); - } - return false; - default: - return false; - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#getIndexMode(java.lang.String) - */ - @Override - public synchronized IndexMode getIndexMode(String store) - { - IndexMode mode = modeCache.get(store); - if (mode == null) - { - for (IndexingDefinition def : indexingDefinitions) - { - if (def.definitionType == DefinitionType.NAME) - { - if (def.pattern.matcher(store).matches()) - { - mode = def.indexMode; - modeCache.put(store, mode); - break; - } - } - else - { - AVMStoreDescriptor avmStoreDescriptor = avmService.getStore(store); - Map storeProperties = null; - if (avmStoreDescriptor != null) - { - storeProperties = avmService.getStoreProperties(store); - } - String storeType = StoreType.getStoreType(store, avmStoreDescriptor, storeProperties).toString(); - if (def.pattern.matcher(storeType).matches()) - { - mode = def.indexMode; - modeCache.put(store, mode); - break; - } - - } - } - } - // No definition - if (mode == null) - { - mode = defaultMode; - modeCache.put(store, mode); - } - return mode; - } - - private class IndexingDefinition - { - IndexMode indexMode; - - DefinitionType definitionType; - - Pattern pattern; - - IndexingDefinition(String definition) - { - String[] split = definition.split(":", 3); - if (split.length != 3) - { - throw new AlfrescoRuntimeException("Invalid index defintion. Must be of of the form IndexMode:DefinitionType:regular expression"); - } - indexMode = IndexMode.valueOf(split[0].toUpperCase()); - definitionType = DefinitionType.valueOf(split[1].toUpperCase()); - pattern = Pattern.compile(split[2]); - } - } - - private enum DefinitionType - { - NAME, TYPE; - } - - public enum StoreType - { - STAGING, STAGING_PREVIEW, AUTHOR, AUTHOR_PREVIEW, WORKFLOW, WORKFLOW_PREVIEW, AUTHOR_WORKFLOW, AUTHOR_WORKFLOW_PREVIEW, UNKNOWN; - - public static StoreType getStoreType(String name, AVMStoreDescriptor storeDescriptor, Map storeProperties) - { - // if (avmService.getStore(name) != null) - if (storeDescriptor != null) - { - // Map storeProperties = avmService.getStoreProperties(name); - if (storeProperties.containsKey(PROP_SANDBOX_STAGING_MAIN)) - { - return StoreType.STAGING; - } - else if (storeProperties.containsKey(PROP_SANDBOX_STAGING_PREVIEW)) - { - return StoreType.STAGING_PREVIEW; - } - else if (storeProperties.containsKey(PROP_SANDBOX_AUTHOR_MAIN)) - { - return StoreType.AUTHOR; - } - else if (storeProperties.containsKey(PROP_SANDBOX_AUTHOR_PREVIEW)) - { - return StoreType.AUTHOR_PREVIEW; - } - else if (storeProperties.containsKey(PROP_SANDBOX_WORKFLOW_MAIN)) - { - return StoreType.WORKFLOW; - } - else if (storeProperties.containsKey(PROP_SANDBOX_WORKFLOW_PREVIEW)) - { - return StoreType.WORKFLOW_PREVIEW; - } - else if (storeProperties.containsKey(PROP_SANDBOX_AUTHOR_WORKFLOW_MAIN)) - { - return StoreType.AUTHOR_WORKFLOW; - } - else if (storeProperties.containsKey(PROP_SANDBOX_AUTHOR_WORKFLOW_PREVIEW)) - { - return StoreType.AUTHOR_WORKFLOW_PREVIEW; - } - else - { - return StoreType.UNKNOWN; - } - } - else - { - return StoreType.UNKNOWN; - } - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#hasIndexBeenCreated(java.lang.String) - */ - @Override - public boolean hasIndexBeenCreated(String store) - { - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - avmIndexer.flushPending(); - return avmIndexer.hasIndexBeenCreated(store); - } - return false; - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#createIndex(java.lang.String) - */ - @Override - public void createIndex(String store) - { - AVMLuceneIndexer avmIndexer = getIndexer(store); - if (avmIndexer != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("createIndex " + store, new Exception("Stack Trace")); - } - avmIndexer.createIndex(store, IndexMode.SYNCHRONOUS); - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#getIndexer(java.lang.String) - */ - @Override - public AVMLuceneIndexer getIndexer(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - Indexer indexer = indexerAndSearcher.getIndexer(storeRef); - if (indexer instanceof AVMLuceneIndexer) - { - AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer; - return avmIndexer; - } - else - { - if(searchApplicationContextFactory.getCurrentSourceBeanName().equals("solr")) - { - throw new AlfrescoRuntimeException("No AVM Indexer available (AVM is not supported with SOLR"); - //return null; - } - else - { - return null; - } - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor#deleteIndex(java.lang.String) - */ - @Override - public void deleteIndex(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - Indexer indexer = indexerAndSearcher.getIndexer(storeRef); - if (indexer instanceof AVMLuceneIndexer) - { - AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer) indexer; - avmIndexer.deleteIndex(storeRef); - } - else - { - if(searchApplicationContextFactory.getCurrentSourceBeanName().equals("solr")) - { - throw new AlfrescoRuntimeException("No AVM Indexer available (AVM is not supported with SOLR"); - } - //else nothing to do - } - } -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java deleted file mode 100644 index 4d882050c6..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search.impl.lucene; - -import java.util.List; - -import org.alfresco.repo.search.BackgroundIndexerAware; -import org.alfresco.repo.search.IndexMode; -import org.alfresco.service.cmr.avm.VersionDescriptor; - -/** - * AVM specific indxer support - * - * @author andyh - * - */ -public interface AVMLuceneIndexer extends LuceneIndexer, BackgroundIndexerAware -{ - /** - * Index a specified change to a store between two snapshots - * - * @param store - the name of the store - * @param srcVersion - the id of the snapshot before the changeset - * @param dstVersion - the id of the snapshot created by the change set - * @param mode - */ - public void index(String store, int srcVersion, int dstVersion, IndexMode mode); - - /** - * Delete the index for the specified store. - * - * @param store - * @param mode - */ - public void deleteIndex(String store, IndexMode mode); - - /** - * Create an index for the specified store. - * This makes sure that the root node for the store is indexed correctly. - * - * @param store - * @param mode - */ - public void createIndex(String store, IndexMode mode); - - /** - * Is the snapshot applied to the index? - * - * Is there an entry for any node that was added OR have all the nodes in the transaction been deleted as expected? - * - * @param store - * @param id - * @return - true if applied, false if not - */ - public boolean isSnapshotIndexed(String store, int id); - - /** - * Is snapshot searchable - * @param store - * @param id - * @return - true if snapshot has been fully indexed, false if pending or unindexed. - */ - public boolean isSnapshotSearchable(String store, int id); - - /** - * Has the index been ceated - * - * @param store - * @return - */ - public boolean hasIndexBeenCreated(String store); - - /** - * Get the number of docs this indexer has indexed so far - * @return - */ - public long getIndexedDocCount(); - - /** - * Get the last snapshot in the index - this does not mean that all snapshots before it have been indexed. - * - * @param store - * @return - */ - public int getLastIndexedSnapshot(String store); -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerAndSearcherFactory.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerAndSearcherFactory.java deleted file mode 100644 index 13536cc506..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerAndSearcherFactory.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search.impl.lucene; - -import java.util.ArrayList; -import java.util.List; - -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.content.ContentStore; -import org.alfresco.repo.content.transform.TransformerDebug; -import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor; -import org.alfresco.repo.search.IndexMode; -import org.alfresco.repo.search.SearcherException; -import org.alfresco.repo.search.SupportsBackgroundIndexing; -import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avmsync.AVMSyncService; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.transaction.TransactionService; - -/** - * Factory for AVM indexers and searchers - * - * @author andyh - * - */ -public class AVMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAndSearcherFactory implements SupportsBackgroundIndexing -{ - private DictionaryService dictionaryService; - private NamespaceService nameSpaceService; - private ContentService contentService; - protected TransactionService transactionService; - - private AVMService avmService; - private AVMSyncService avmSyncService; - private NodeService nodeService; - private ContentStore contentStore; - - private TransformerDebug transformerDebug; - private FullTextSearchIndexer fullTextSearchIndexer; - private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor; - - public AVMLuceneIndexerAndSearcherFactory() - { - //s_logger.error("Creating AVMLuceneIndexerAndSearcherFactory"); - } - - /** - * Set the dictionary service - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * Set the name space service - */ - public void setNameSpaceService(NamespaceService nameSpaceService) - { - this.nameSpaceService = nameSpaceService; - } - - /** - * Set the content service - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - public void setTransactionService(TransactionService transactionService) - { - this.transactionService = transactionService; - } - - /** - * Set the AVM service - */ - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - /** - * Set the AVM sync service - */ - public void setAvmSyncService(AVMSyncService avmSyncService) - { - this.avmSyncService = avmSyncService; - } - - /** - * Set the node service - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * Set the content service - */ - public void setContentStore(ContentStore contentStore) - { - this.contentStore = contentStore; - } - - /** - * Sets the transformer debug. - * @param transformerDebug - */ - public void setTransformerDebug(TransformerDebug transformerDebug) - { - this.transformerDebug = transformerDebug; - } - - /** - * @param avmSnapShotTriggeredIndexingMethodInterceptor the avmSnapShotTriggeredIndexingMethodInterceptor to set - */ - public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor) - { - this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor; - } - - @Override - protected LuceneIndexer createIndexer(StoreRef storeRef, String deltaId) - { - AVMLuceneIndexerImpl indexer = AVMLuceneIndexerImpl.getUpdateIndexer(storeRef, deltaId, this); - indexer.setDictionaryService(dictionaryService); - indexer.setContentService(contentService); - indexer.setTransactionService(transactionService); - indexer.setMaxAtomicTransformationTime(getMaxTransformationTime()); - indexer.setAvmService(avmService); - indexer.setAvmSyncService(avmSyncService); - indexer.setContentStore(contentStore); - indexer.setTransformerDebug(transformerDebug); - indexer.setFullTextSearchIndexer(fullTextSearchIndexer); - return indexer; - } - - @Override - protected List getAllStores() - { - List stores = avmService.getStores(); - List storeRefs = new ArrayList(stores.size()); - for(AVMStoreDescriptor storeDesc : stores) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(storeDesc.getName()); - if (avmSnapShotTriggeredIndexingMethodInterceptor.getIndexMode(storeRef.getIdentifier()) == IndexMode.UNINDEXED) - { - // ALF-5722 fix - continue; - } - storeRefs.add(storeRef); - } - return storeRefs; - } - - @Override - protected LuceneSearcher getSearcher(StoreRef storeRef, LuceneIndexer indexer) throws SearcherException - { - //TODO: Store overlays - ADMLuceneSearcherImpl searcher = ADMLuceneSearcherImpl.getSearcher(storeRef, indexer, this); - searcher.setNamespacePrefixResolver(nameSpaceService); - // searcher.setLuceneIndexLock(luceneIndexLock); - searcher.setNodeService(nodeService); - searcher.setTenantService(tenantService); - searcher.setDictionaryService(dictionaryService); - searcher.setQueryRegister(getQueryRegister()); - searcher.setDictionaryService(dictionaryService); - searcher.setQueryLanguages(getQueryLanguages()); - return searcher; - } - - @Override - protected SearchService getNodeSearcher() throws SearcherException - { - throw new UnsupportedOperationException(); - } - - /** - * Register the full text searcher (done by the seracher bean to break cyclic bean defs) - * - */ - public void setFullTextSearchIndexer(FullTextSearchIndexer fullTextSearchIndexer) - { - this.fullTextSearchIndexer = fullTextSearchIndexer; - } - -} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java deleted file mode 100644 index baa0b06dbd..0000000000 --- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java +++ /dev/null @@ -1,2521 +0,0 @@ -/** - * Copyright (C) 2005-2013 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.search.impl.lucene; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.Serializable; -import java.io.StringReader; -import java.io.UnsupportedEncodingException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMModel; -import org.alfresco.repo.avm.AVMDAOs; -import org.alfresco.repo.avm.AVMNode; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.util.SimplePath; -import org.alfresco.repo.content.ContentStore; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.content.transform.ContentTransformer; -import org.alfresco.repo.content.transform.TransformerDebug; -import org.alfresco.repo.dictionary.IndexTokenisationMode; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.search.IndexMode; -import org.alfresco.repo.search.MLAnalysisMode; -import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser; -import org.alfresco.repo.search.impl.lucene.analysis.MLTokenDuplicator; -import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser; -import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware; -import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avmsync.AVMDifference; -import org.alfresco.service.cmr.avmsync.AVMSyncException; -import org.alfresco.service.cmr.avmsync.AVMSyncService; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentIOException; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; -import org.alfresco.service.cmr.repository.MLText; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.TransformationOptions; -import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; -import org.alfresco.service.cmr.repository.datatype.TypeConversionException; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.CachingDateFormat; -import org.alfresco.util.EqualsHelper; -import org.alfresco.util.GUID; -import org.alfresco.util.ISO9075; -import org.alfresco.util.Pair; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.analysis.Token; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.Term; -import org.apache.lucene.index.TermDocs; -import org.apache.lucene.index.TermEnum; -import org.apache.lucene.search.Hits; -import org.apache.lucene.search.PrefixQuery; -import org.apache.lucene.search.Searcher; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Update the index after a snap shot to an AVM store. (Revert is dealt with as a new snap shot is created) - * - * @author andyh - */ -public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl implements AVMLuceneIndexer -{ - private enum IndexChannel - { - MAIN, DELTA; - } - - protected enum IndexDeleteMode {REINDEX, DELETE}; - - private static String SNAP_SHOT_ID = "SnapShot"; - - static Log s_logger = LogFactory.getLog(AVMLuceneIndexerImpl.class); - - private AVMService avmService; - - private AVMSyncService avmSyncService; - - @SuppressWarnings("unused") - private ContentStore contentStore; - - private ContentService contentService; - - private TransformerDebug transformerDebug; - - private FTSIndexerAware callBack; - - private FullTextSearchIndexer fullTextSearchIndexer; - - private int remainingCount; - - private int startVersion = -1; - - private int endVersion = -1; - - /** - * A list of deletions associated with the changes to nodes in the current flush - */ - protected Set deletionsSinceFlush = new HashSet(); - - private long indexedDocCount = 0; - - /** - * Set the AVM Service - * - * @param avmService - */ - public void setAvmService(AVMService avmService) - { - this.avmService = avmService; - } - - /** - * Set the AVM sync service - * - * @param avmSyncService - */ - public void setAvmSyncService(AVMSyncService avmSyncService) - { - this.avmSyncService = avmSyncService; - } - - /** - * Set the content service - * - * @param contentStore - */ - public void setContentStore(ContentStore contentStore) - { - this.contentStore = contentStore; - } - - /** - * @param contentService - */ - public void setContentService(ContentService contentService) - { - this.contentService = contentService; - } - - /** - * Helper setter of the transformer debug. - * @param transformerDebug - */ - public void setTransformerDebug(TransformerDebug transformerDebug) - { - this.transformerDebug = transformerDebug; - } - - /** - * Are we deleting leaves only (not meta data) - * - * @return - deleting only nodes. - */ - public boolean getDeleteOnlyNodes() - { - return indexUpdateStatus == IndexUpdateStatus.ASYNCHRONOUS; - } - - /** - * Generate an indexer - * - * @param storeRef - * @param deltaId - * @param config - * @return - the indexer instance - * @throws LuceneIndexException - */ - public static AVMLuceneIndexerImpl getUpdateIndexer(StoreRef storeRef, String deltaId, LuceneConfig config) throws LuceneIndexException - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Creating indexer"); - } - AVMLuceneIndexerImpl indexer = new AVMLuceneIndexerImpl(); - indexer.setLuceneConfig(config); - indexer.initialise(storeRef, deltaId); - return indexer; - } - - /** - * Index a specified change to a store - * - * @param store - * @param srcVersion - * @param dstVersion - */ - public void index(String store, int srcVersion, int dstVersion, IndexMode mode) - { - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - switch (mode) - { - case ASYNCHRONOUS: - asynchronousIndex(store, srcVersion, dstVersion); - break; - case SYNCHRONOUS: - synchronousIndex(store, srcVersion, dstVersion); - break; - case UNINDEXED: - // nothing to do - break; - } - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("snapshot index failed", e); - } - } - - private void asynchronousIndex(String store, int srcVersion, int dstVersion) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Async index for " + store + " from " + srcVersion + " to " + dstVersion); - } - index("\u0000BG:STORE:" + store + ":" + srcVersion + ":" + dstVersion + ":" + GUID.generate()); - fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store)); - } - - private void synchronousIndex(String store, int srcVersion, int dstVersion) - { - if (startVersion == -1) - { - startVersion = srcVersion; - } - - endVersion = dstVersion; - - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Sync index for " + store + " from " + srcVersion + " to " + dstVersion); - } - String path = store + ":/"; - List changeList = null; - try - { - changeList = avmSyncService.compare(srcVersion, path, dstVersion, path, null); - } - catch (AVMSyncException e) - { - s_logger.warn("\n" - + "Unable to generate change list for synchronous indexing: \n" + " Store: " + store + "\n" + " Start version: " + srcVersion + "\n" - + " End version: " + endVersion); - return; - } - for (AVMDifference difference : changeList) - { - switch (difference.getDifferenceCode()) - { - case AVMDifference.CONFLICT: - case AVMDifference.NEWER: - case AVMDifference.OLDER: - AVMNodeDescriptor srcDesc = avmService.lookup(difference.getSourceVersion(), difference.getSourcePath(), true); - AVMNodeDescriptor dstDesc = avmService.lookup(difference.getDestinationVersion(), difference.getDestinationPath(), true); - // New - if (srcDesc == null) - { - if (dstDesc == null) - { - // Nothing to do for this case - both are deleted/not there - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Skipped - src & dst deleted / not there: "+difference); - } - } - else - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("new: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath()); - } - // ALF-786 - reindex(difference.getDestinationPath(), dstDesc.isDirectory()); - if (dstDesc.isDirectory()) - { - indexDirectory(dstDesc); - } - reindexAllAncestors(difference.getDestinationPath()); - } - } - // Existing delete - else if (srcDesc.isDeleted()) - { - if ((dstDesc == null) || dstDesc.isDeleted()) - { - // Nothing to do for this case - both are deleted/not there - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Skipped - src & dst deleted / not there: "+difference); - } - } - else - { - // We are back from the dead ...the node used to be deleted - // Treat as new - // ALF-786 - if (s_logger.isDebugEnabled()) - { - s_logger.debug("back: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath()); - } - reindex(difference.getDestinationPath(), dstDesc.isDirectory()); - if (dstDesc.isDirectory()) - { - indexDirectory(dstDesc); - } - reindexAllAncestors(difference.getDestinationPath()); - } - } - // Anything else then we have a delete or reindex - else - { - // Unknown end state ... - if(dstDesc == null) - { - // we do not know what has happened - whatever it is does not apply to this snapshot - if (s_logger.isDebugEnabled()) - { - s_logger.debug("unknown: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath()); - } - } - // Delete - else if (dstDesc.isDeleted()) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("delete: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath()); - } - delete(difference.getSourcePath()); - reindexAllAncestors(difference.getSourcePath()); - delete(difference.getDestinationPath()); - reindexAllAncestors(difference.getDestinationPath()); - } - // move - else if (!difference.getSourcePath().equals(difference.getDestinationPath())) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("move: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath()); - } - reindex(difference.getSourcePath(), srcDesc.isDirectory()); - reindex(difference.getDestinationPath(), dstDesc.isDirectory()); - reindexAllAncestors(difference.getSourcePath()); - reindexAllAncestors(difference.getDestinationPath()); - } - // update - else - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("update: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath()); - } - // If it is a directory, it is at the same path, - // so no cascade update is required for the bridge table data. - reindex(difference.getDestinationPath(), false); - reindexAllAncestors(difference.getDestinationPath()); - } - } - break; - case AVMDifference.DIRECTORY: - // Never seen - break; - case AVMDifference.SAME: - // No action - break; - - } - } - // record the snap shotid - reindex(SNAP_SHOT_ID + ":" + store + ":" + srcVersion + ":" + dstVersion, false); - } - - /* - * Nasty catch all fix up (as changes imply the parents may all have changed - */ - private void reindexAllAncestors(String destinationPath) - { - String[] splitPath = splitPath(destinationPath); - String store = splitPath[0]; - String pathInStore = splitPath[1]; - SimplePath simplePath = new SimplePath(pathInStore); - - StringBuilder pathBuilder = new StringBuilder(); - pathBuilder.append(store).append(":/"); - reindex(pathBuilder.toString(), false); - boolean requiresSep = false; - for (int i = 0; i < simplePath.size() - 1; i++) - { - if (requiresSep) - { - pathBuilder.append("/"); - } - else - { - requiresSep = true; - } - pathBuilder.append(simplePath.get(i)); - reindex(pathBuilder.toString(), false); - } - } - - private void indexDirectory(AVMNodeDescriptor dir) - { - Map children = avmService.getDirectoryListing(dir, false); - for (AVMNodeDescriptor child : children.values()) - { - // ALF-786 - reindex(child.getPath(), child.isDirectory()); - reindexAllAncestors(child.getPath()); - if (child.isDirectory()) - { - indexDirectory(child); - } - } - - } - - protected Set deleteImpl(String nodeRef, IndexDeleteMode mode, boolean cascade, IndexReader mainReader) - throws LuceneIndexException, IOException - { - Set leafrefs = new LinkedHashSet(); - IndexReader deltaReader = null; - - // startTimer(); - getDeltaReader(); - // outputTime("Delete "+nodeRef+" size = "+getDeltaWriter().docCount()); - Set refs = new LinkedHashSet(); - Set containerRefs = new LinkedHashSet(); - Set temp = null; - - switch(mode) - { - case REINDEX: - temp = deleteContainerAndBelow(nodeRef, getDeltaReader(), true, cascade); - closeDeltaReader(); - refs.addAll(temp); - deletions.addAll(temp); - // should not be included as a delete for optimisation in deletionsSinceFlush - // should be optimised out - // defensive against any issue with optimisation of events - // the nodes have not been deleted and would require a real delete - temp = deleteContainerAndBelow(nodeRef, mainReader, false, cascade); - refs.addAll(temp); - deletions.addAll(temp); - // should not be included as a delete for optimisation - // should be optimised out - // defensive agaainst any issue with optimisation of events - // the nodes have not been deleted and would require a real delete - break; - case DELETE: - // if already deleted don't do it again ... - if(deletionsSinceFlush.contains(nodeRef)) - { - // nothing to do - break; - } - else - { - // Delete all and reindex as they could be secondary links we have deleted and they need to be updated. - // Most will skip any indexing as they will really have gone. - temp = deleteContainerAndBelow(nodeRef, getDeltaReader(), true, cascade); - closeDeltaReader(); - containerRefs.addAll(temp); - refs.addAll(temp); - temp = deleteContainerAndBelow(nodeRef, mainReader, false, cascade); - containerRefs.addAll(temp); - - temp = deletePrimary(containerRefs, getDeltaReader(), true); - leafrefs.addAll(temp); - closeDeltaReader(); - temp = deletePrimary(containerRefs, mainReader, false); - leafrefs.addAll(temp); - - // May not have to delete references - temp = deleteReference(containerRefs, getDeltaReader(), true); - leafrefs.addAll(temp); - closeDeltaReader(); - temp = deleteReference(containerRefs, mainReader, false); - leafrefs.addAll(temp); - - refs.addAll(containerRefs); - refs.addAll(leafrefs); - deletions.addAll(refs); - // do not delete anything we have deleted before in this flush - // probably OK to cache for the TX as a whole but done per flush => See ALF-8007 - deletionsSinceFlush.addAll(refs); - - // make sure leaves are also removed from the delta before reindexing - - deltaReader = getDeltaReader(); - for(String id : leafrefs) - { - deltaReader.deleteDocuments(new Term("ID", id)); - } - closeDeltaReader(); - break; - } - } - - return refs; - - } - - protected List createDocuments(String stringNodeRef, FTSStatus ftsStatus, boolean indexAllProperties, boolean includeDirectoryDocuments) - { - List docs = new ArrayList(); - if (stringNodeRef.startsWith("\u0000")) - { - Document idoc = new Document(); - idoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - docs.add(idoc); - return docs; - } - else if (stringNodeRef.startsWith(SNAP_SHOT_ID)) - { - Document sdoc = new Document(); - sdoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - docs.add(sdoc); - return docs; - } - - AVMNodeDescriptor desc = avmService.lookup(endVersion, stringNodeRef); - if (desc == null) - { - return docs; - } - if (desc.isLayeredDirectory() || desc.isLayeredFile()) - { - incrementDocCount(); - return docs; - } - - // Naughty, Britt should come up with a fix that doesn't require this. - AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(desc.getId()); - - if (desc != null) - { - - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(endVersion, stringNodeRef); - - Document xdoc = new Document(); - xdoc.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("TX", AlfrescoTransactionSupport.getTransactionId(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - boolean isAtomic = true; - - Map properties = getIndexableProperties(desc, nodeRef, endVersion, stringNodeRef); - - if(properties.containsKey(ContentModel.PROP_IS_INDEXED)) - { - Serializable sValue = properties.get(ContentModel.PROP_IS_INDEXED); - if(sValue != null) - { - Boolean isIndexed = DefaultTypeConverter.INSTANCE.convert(Boolean.class, sValue); - if((isIndexed != null) && (isIndexed.booleanValue() == false)) - { - return docs; - } - } - } - - boolean isContentIndexedForNode = true; - if(properties.containsKey(ContentModel.PROP_IS_CONTENT_INDEXED)) - { - Serializable sValue = properties.get(ContentModel.PROP_IS_CONTENT_INDEXED); - if(sValue != null) - { - Boolean isIndexed = DefaultTypeConverter.INSTANCE.convert(Boolean.class, sValue); - if((isIndexed != null) && (isIndexed.booleanValue() == false)) - { - isContentIndexedForNode = false; - } - } - } - - for (QName propertyName : properties.keySet()) - { - Serializable value = properties.get(propertyName); - if (indexAllProperties) - { - indexProperty(nodeRef, propertyName, value, xdoc, false, properties, isContentIndexedForNode); - } - else - { - isAtomic &= indexProperty(nodeRef, propertyName, value, xdoc, true, properties,isContentIndexedForNode); - } - } - - StringBuilder qNameBuffer = new StringBuilder(64); - if (node.getIsRoot()) - { - - } - // pseudo roots? - else - { - String[] splitPath = splitPath(stringNodeRef); - String store = splitPath[0]; - String pathInStore = splitPath[1]; - SimplePath simplePath = new SimplePath(pathInStore); - - StringBuilder xpathBuilder = new StringBuilder(); - for (int i = 0; i < simplePath.size(); i++) - { - xpathBuilder.append("/{}").append(ISO9075.encode(simplePath.get(i))); - } - String xpath = xpathBuilder.toString(); - - if (qNameBuffer.length() > 0) - { - qNameBuffer.append(";/"); - } - // Get the parent - - ArrayList ancestors = new ArrayList(); - - StringBuilder pathBuilder = new StringBuilder(); - pathBuilder.append(store).append(":/"); - ancestors.add(pathBuilder.toString()); - boolean requiresSep = false; - for (int i = 0; i < simplePath.size() - 1; i++) - { - if (requiresSep) - { - pathBuilder.append("/"); - } - else - { - requiresSep = true; - } - pathBuilder.append(simplePath.get(i)); - ancestors.add(pathBuilder.toString()); - } - - qNameBuffer.append(ISO9075.getXPathName(QName.createQName("", simplePath.get(simplePath.size() - 1)))); - xdoc.add(new Field("PARENT", ancestors.get(ancestors.size() - 1), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - // TODO: Categories and LINKASPECT - - if (includeDirectoryDocuments) - { - if (desc.isDirectory()) - { - // TODO: Exclude category paths - - Document directoryEntry = new Document(); - directoryEntry.add(new Field("ID", nodeRef.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - directoryEntry.add(new Field("ID", stringNodeRef, Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - directoryEntry.add(new Field("PATH", xpath, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - - // Find all parent nodes. - - for (String toAdd : ancestors) - { - directoryEntry.add(new Field("ANCESTOR", toAdd, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - } - directoryEntry.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - docs.add(directoryEntry); - - } - } - } - - if (node.getIsRoot()) - { - // TODO: Does the root element have a QName? - xdoc.add(new Field("ISCONTAINER", "T", Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("PATH", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("QNAME", "", Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ISROOT", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - docs.add(xdoc); - - } - else - // not a root node - { - xdoc.add(new Field("QNAME", qNameBuffer.toString(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO)); - - QName typeQName = getType(desc); - - xdoc.add(new Field("TYPE", ISO9075.getXPathName(typeQName), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - for (QName classRef : avmService.getAspects(desc)) - { - xdoc.add(new Field("ASPECT", ISO9075.getXPathName(classRef), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - } - - xdoc.add(new Field("ISROOT", "F", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - xdoc.add(new Field("ISNODE", "T", Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - docs.add(xdoc); - } - } - else - { - boolean root = node.getIsRoot(); - boolean deleted = desc.isDeleted(); - System.out.println("Is Root " + root); - System.out.println("Is deleted " + deleted); - } - incrementDocCount(); - return docs; - } - - protected List readDocuments(final String stringNodeRef, final FTSStatus ftsStatus, - final boolean indexAllProperties, final boolean includeDirectoryDocuments) - { - return doInReadthroughTransaction(new RetryingTransactionCallback>() - { - @Override - public List execute() throws Throwable - { - return createDocuments(stringNodeRef, ftsStatus, indexAllProperties, - includeDirectoryDocuments); - } - }); - } - - - protected void indexImpl(String nodeRef, boolean isNew) throws LuceneIndexException, IOException - { - IndexWriter writer = getDeltaWriter(); - - // avoid attempting to index nodes that don't exist - - try - { - List docs = readDocuments(nodeRef, isNew ? FTSStatus.New : FTSStatus.Dirty, false, true); - for (Document doc : docs) - { - try - { - writer.addDocument(doc); - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to add document to index", e); - } - } - } - catch (InvalidNodeRefException e) - { - // The node does not exist - return; - } - - } - - void indexImpl(Set refs, boolean isNew) throws LuceneIndexException, IOException - { - for (String ref : refs) - { - indexImpl(ref, isNew); - } - } - - /** - * @throws LuceneIndexException - */ - public void flushPending() throws LuceneIndexException - { - IndexReader mainReader = null; - try - { - saveDelta(); - - // Make sure the in flush deletion list is clear at the start - deletionsSinceFlush.clear(); - if (commandList.isEmpty()) - { - return; - } - - mainReader = getReader(); - Set forIndex = new LinkedHashSet(); - - for (Command command : commandList) - { - if (command.action == Action.INDEX) - { - // Indexing just requires the node to be added to the list - forIndex.add(command.ref.toString()); - } - else if (command.action == Action.REINDEX) - { - // Reindex is a delete and then and index - Set set = deleteImpl(command.ref.toString(), IndexDeleteMode.REINDEX, false, mainReader); - - // Deleting any pending index actions - // - make sure we only do at most one index - forIndex.removeAll(set); - // Add the nodes for index - forIndex.addAll(set); - } - else if (command.action == Action.CASCADEREINDEX) - { - // Reindex is a delete and then and index - Set set = deleteImpl(command.ref.toString(), IndexDeleteMode.REINDEX, true, mainReader); - - // Deleting any pending index actions - // - make sure we only do at most one index - forIndex.removeAll(set); - // Add the nodes for index - forIndex.addAll(set); - } - else if (command.action == Action.DELETE) - { - // Delete the nodes - Set set = deleteImpl(command.ref.toString(), IndexDeleteMode.DELETE, true, mainReader); - // Remove any pending indexes - forIndex.removeAll(set); - // Add the leaf nodes for reindex - forIndex.addAll(set); - } - } - commandList.clear(); - indexImpl(forIndex, false); - docs = getDeltaWriter().docCount(); - deletionsSinceFlush.clear(); - } - catch (IOException e) - { - // If anything goes wrong we try and do a roll back - throw new LuceneIndexException("Failed to flush index", e); - } - finally - { - if (mainReader != null) - { - try - { - mainReader.close(); - } - catch (IOException e) - { - throw new LuceneIndexException("Filed to close main reader", e); - } - } - // Make sure deletes are sent - try - { - closeDeltaReader(); - } - catch (IOException e) - { - - } - // Make sure writes and updates are sent. - try - { - closeDeltaWriter(); - } - catch (IOException e) - { - - } - } - } - - private String[] splitPath(String path) - { - String[] pathParts = path.split(":"); - if (pathParts.length != 2) - { - throw new AVMException("Invalid path: " + path); - } - return pathParts; - } - - private QName getType(AVMNodeDescriptor desc) - { - if (desc.isPlainDirectory()) - { - return WCMModel.TYPE_AVM_PLAIN_FOLDER; - } - else if (desc.isPlainFile()) - { - return WCMModel.TYPE_AVM_PLAIN_CONTENT; - } - else if (desc.isLayeredDirectory()) - { - return WCMModel.TYPE_AVM_LAYERED_FOLDER; - } - else - { - return WCMModel.TYPE_AVM_LAYERED_CONTENT; - } - } - - private Map getIndexableProperties(AVMNodeDescriptor desc, NodeRef nodeRef, Integer version, String path) - { - Map properties = avmService.getNodeProperties(desc); - - Map result = new HashMap(); - for (QName qName : properties.keySet()) - { - PropertyValue value = properties.get(qName); - PropertyDefinition def = getDictionaryService().getProperty(qName); - result.put(qName, makeSerializableValue(def, value)); - } - // Now spoof properties that are built in. - result.put(ContentModel.PROP_CREATED, new Date(desc.getCreateDate())); - result.put(ContentModel.PROP_CREATOR, desc.getCreator()); - result.put(ContentModel.PROP_MODIFIED, new Date(desc.getModDate())); - result.put(ContentModel.PROP_MODIFIER, desc.getLastModifier()); - result.put(ContentModel.PROP_OWNER, desc.getOwner()); - result.put(ContentModel.PROP_NAME, desc.getName()); - result.put(ContentModel.PROP_NODE_UUID, "UNKNOWN"); - result.put(ContentModel.PROP_NODE_DBID, new Long(desc.getId())); - result.put(ContentModel.PROP_STORE_PROTOCOL, "avm"); - result.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier()); - if (desc.isLayeredDirectory()) - { - result.put(WCMModel.PROP_AVM_DIR_INDIRECTION, AVMNodeConverter.ToNodeRef(endVersion, desc.getIndirection())); - } - if (desc.isLayeredFile()) - { - result.put(WCMModel.PROP_AVM_FILE_INDIRECTION, AVMNodeConverter.ToNodeRef(endVersion, desc.getIndirection())); - } - if (desc.isFile()) - { - try - { - ContentData contentData = null; - if (desc.isPlainFile()) - { - contentData = avmService.getContentDataForRead(desc); - } - else - { - contentData = avmService.getContentDataForRead(endVersion, path); - } - result.put(ContentModel.PROP_CONTENT, contentData); - } - catch (AVMException e) - { - // TODO For now ignore. - } - } - return result; - - } - - protected Serializable makeSerializableValue(PropertyDefinition propertyDef, PropertyValue propertyValue) - { - if (propertyValue == null) - { - return null; - } - // get property attributes - QName propertyTypeQName = null; - if (propertyDef == null) - { - // allow this for now - propertyTypeQName = DataTypeDefinition.ANY; - } - else - { - propertyTypeQName = propertyDef.getDataType().getName(); - } - try - { - Serializable value = propertyValue.getValue(propertyTypeQName); - // done - return value; - } - catch (TypeConversionException e) - { - throw new TypeConversionException("The property value is not compatible with the type defined for the property: \n" - + " property: " + (propertyDef == null ? "unknown" : propertyDef) + "\n" + " property value: " + propertyValue, e); - } - } - - protected boolean indexProperty(NodeRef banana, QName propertyName, Serializable value, Document doc, boolean indexAtomicPropertiesOnly, Map properties, boolean isContentIndexedForNode) - { - String attributeName = "@" + QName.createQName(propertyName.getNamespaceURI(), ISO9075.encode(propertyName.getLocalName())); - - boolean store = true; - boolean index = true; - IndexTokenisationMode tokenise = IndexTokenisationMode.TRUE; - @SuppressWarnings("unused") - boolean atomic = true; - boolean isContent = false; - boolean isMultiLingual = false; - boolean isText = false; - boolean isDateTime = false; - - PropertyDefinition propertyDef = getDictionaryService().getProperty(propertyName); - if (propertyDef != null) - { - index = propertyDef.isIndexed(); - store = propertyDef.isStoredInIndex(); - tokenise = propertyDef.getIndexTokenisationMode(); - atomic = propertyDef.isIndexedAtomically(); - isContent = propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT); - isMultiLingual = propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT); - isText = propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT); - if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME)) - { - String analyserClassName = propertyDef.resolveAnalyserClassName(); - isDateTime = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()); - } - } - if (value == null) - { - // the value is null - return true; - } - // else if (indexAtomicPropertiesOnly && !atomic) - // { - // we are only doing atomic properties and the property is definitely non-atomic - // return false; - // } - - if (!indexAtomicPropertiesOnly) - { - doc.removeFields(propertyName.toString()); - } - // boolean wereAllAtomic = true; - // convert value to String - for (Serializable serializableValue : DefaultTypeConverter.INSTANCE.getCollection(Serializable.class, value)) - { - String strValue = null; - try - { - strValue = DefaultTypeConverter.INSTANCE.convert(String.class, serializableValue); - } - catch (TypeConversionException e) - { - doc.add(new Field(attributeName, NOT_INDEXED_NO_TYPE_CONVERSION, Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - continue; - } - if (strValue == null) - { - // nothing to index - continue; - } - - if (isContent) - { - // Content is always tokenised - - ContentData contentData = DefaultTypeConverter.INSTANCE.convert(ContentData.class, serializableValue); - if (!index || contentData == null || contentData.getMimetype() == null) - { - // no content, mimetype or property not indexed - continue; - } - // store mimetype in index - even if content does not index it is useful - // Added szie and locale - size needs to be tokenised correctly - doc.add(new Field(attributeName + ".mimetype", contentData.getMimetype(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - doc.add(new Field(attributeName + ".size", Long.toString(contentData.getSize()), Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); - - // TODO: Use the node locale in preferanced to the system locale - Locale locale = contentData.getLocale(); - // No default locale in AVM - if (locale == null) - { - locale = I18NUtil.getLocale(); - } - doc.add(new Field(attributeName + ".locale", locale.toString().toLowerCase(), Field.Store.NO, Field.Index.UN_TOKENIZED, Field.TermVector.NO)); - - - if(isContentIndexedForNode) - { - ContentReader reader = null; - try - { - reader = contentService.getRawReader(contentData.getContentUrl()); - reader.setEncoding(contentData.getEncoding()); - reader.setLocale(contentData.getLocale()); - reader.setMimetype(contentData.getMimetype()); - } - catch (Exception e) - { - reader = null; - } - // ContentReader reader = contentService.getReader(banana, propertyName); - if (reader != null && reader.exists()) - { - boolean readerReady = true; - // transform if necessary (it is not a UTF-8 text document) - if (!EqualsHelper.nullSafeEquals(reader.getMimetype(), MimetypeMap.MIMETYPE_TEXT_PLAIN) || !EqualsHelper.nullSafeEquals(reader.getEncoding(), "UTF-8")) - { - try - { - // get the transformer - TransformationOptions options = new TransformationOptions(); - options.setUse("index"); - options.setSourceNodeRef(banana); // TODO check it is OK to use this noderef - transformerDebug.pushAvailable(reader.getContentUrl(), reader.getMimetype(), MimetypeMap.MIMETYPE_TEXT_PLAIN, options); - long sourceSize = reader.getSize(); - List transformers = contentService.getActiveTransformers(reader.getMimetype(), sourceSize, MimetypeMap.MIMETYPE_TEXT_PLAIN, options); - transformerDebug.availableTransformers(transformers, sourceSize, options, "AVMLuceneIndexer"); - - if (transformers.isEmpty()) - { - // log it - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Not indexed: No transformation: \n" + " source: " + reader + "\n" + " target: " + MimetypeMap.MIMETYPE_TEXT_PLAIN); - } - // don't index from the reader - readerReady = false; - // not indexed: no transformation - // doc.add(new Field("TEXT", NOT_INDEXED_NO_TRANSFORMATION, Field.Store.NO, - // Field.Index.TOKENIZED, Field.TermVector.NO)); - doc.add(new Field(attributeName, NOT_INDEXED_NO_TRANSFORMATION, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); - } - // is this transformer good enough? - // else if (indexAtomicPropertiesOnly - // && transformers.get(0).getTransformationTime() > maxAtomicTransformationTime) - // { - // only indexing atomic properties - // indexing will take too long, so push it to the background - // wereAllAtomic = false; - // } - else - { - // We have a transformer that is fast enough - ContentTransformer transformer = transformers.get(0); - ContentWriter writer = contentService.getTempWriter(); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - // this is what the analyzers expect on the stream - writer.setEncoding("UTF-8"); - try - { - transformer.transform(reader, writer, options); - // point the reader to the new-written content - reader = writer.getReader(); - // Check that the reader is a view onto something concrete - if (!reader.exists()) - { - throw new ContentIOException("The transformation did not write any content, yet: \n" - + " transformer: " + transformer + "\n" + " temp writer: " + writer); - } - } - catch (ContentIOException e) - { - // log it - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Not indexed: Transformation failed", e); - } - // don't index from the reader - readerReady = false; - // not indexed: transformation - // failed - // doc.add(new Field("TEXT", NOT_INDEXED_TRANSFORMATION_FAILED, Field.Store.NO, - // Field.Index.TOKENIZED, Field.TermVector.NO)); - doc.add(new Field(attributeName, NOT_INDEXED_TRANSFORMATION_FAILED, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); - } - } - } - finally - { - transformerDebug.popAvailable(); - } - } - // add the text field using the stream from the - // reader, but only if the reader is valid - if (readerReady) - { - InputStreamReader isr = null; - InputStream ris = reader.getReader().getContentInputStream(); - try - { - isr = new InputStreamReader(ris, "UTF-8"); - } - catch (UnsupportedEncodingException e) - { - isr = new InputStreamReader(ris); - } - StringBuilder builder = new StringBuilder(); - builder.append("\u0000").append(locale.toString()).append("\u0000"); - StringReader prefix = new StringReader(builder.toString()); - Reader multiReader = new MultiReader(prefix, isr); - doc.add(new Field(attributeName, multiReader, Field.TermVector.NO)); - } - } - else - // URL not present (null reader) or no content at the URL (file missing) - { - // log it - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Not indexed: Content Missing \n" - + " node: " + banana + "\n" + " reader: " + reader + "\n" + " content exists: " - + (reader == null ? " --- " : Boolean.toString(reader.exists()))); - } - // not indexed: content missing - doc.add(new Field(attributeName, NOT_INDEXED_CONTENT_MISSING, Field.Store.NO, Field.Index.TOKENIZED, Field.TermVector.NO)); - } - } - else - { - return true; - } - } - else - { - Field.Store fieldStore = store ? Field.Store.YES : Field.Store.NO; - Field.Index fieldIndex; - - if (index) - { - switch (tokenise) { - case TRUE: - case BOTH: - default: - fieldIndex = Field.Index.TOKENIZED; - break; - case FALSE: - fieldIndex = Field.Index.UN_TOKENIZED; - break; - - } - } else { - fieldIndex = Field.Index.NO; - } - - if ((fieldIndex != Field.Index.NO) || (fieldStore != Field.Store.NO)) - { - if (isMultiLingual) - { - MLText mlText = DefaultTypeConverter.INSTANCE.convert(MLText.class, serializableValue); - for (Locale locale : mlText.getLocales()) - { - String localeString = mlText.getValue(locale); - StringBuilder builder; - MLAnalysisMode analysisMode; - VerbatimAnalyser vba; - MLTokenDuplicator duplicator; - Token t; - switch (tokenise) - { - case TRUE: - builder = new StringBuilder(); - builder.append("\u0000").append(locale.toString()).append("\u0000").append(localeString); - doc.add(new Field(attributeName, builder.toString(), fieldStore, fieldIndex, Field.TermVector.NO)); - break; - case FALSE: - // analyse ml text - analysisMode = getLuceneConfig().getDefaultMLIndexAnalysisMode(); - // Do the analysis here - vba = new VerbatimAnalyser(false); - duplicator = new MLTokenDuplicator(vba.tokenStream(attributeName, new StringReader(localeString)), locale, null, analysisMode); - try - { - while ((t = duplicator.next()) != null) - { - String localeText = ""; - if (t.termText().indexOf('{') == 0) - { - int end = t.termText().indexOf('}', 1); - if (end != -1) - { - localeText = t.termText().substring(1, end); - } - } - if (localeText.length() > 0) - { - doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - - doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - - } - } - catch (IOException e) - { - // TODO ?? - } - - break; - case BOTH: - builder = new StringBuilder(); - builder.append("\u0000").append(locale.toString()).append("\u0000").append(localeString); - doc.add(new Field(attributeName, builder.toString(), fieldStore, fieldIndex, Field.TermVector.NO)); - - // analyse ml text - analysisMode = getLuceneConfig().getDefaultMLIndexAnalysisMode(); - // Do the analysis here - vba = new VerbatimAnalyser(false); - duplicator = new MLTokenDuplicator(vba.tokenStream(attributeName, new StringReader(localeString)), locale, null, analysisMode); - try - { - while ((t = duplicator.next()) != null) - { - String localeText = ""; - if (t.termText().indexOf('{') == 0) - { - int end = t.termText().indexOf('}', 1); - if (end != -1) - { - localeText = t.termText().substring(1, end); - } - } - if (localeText.length() > 0) - { - doc.add(new Field(attributeName + "." + localeText + ".sort", t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - } - } - catch (IOException e) - { - // TODO ?? - } - - break; - } - } - } - else if (isText) - { - // Temporary special case for uids and gids - if (propertyName.equals(ContentModel.PROP_USER_USERNAME) - || propertyName.equals(ContentModel.PROP_USERNAME) || propertyName.equals(ContentModel.PROP_AUTHORITY_NAME)) - { - doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); - } - - // TODO: Use the node locale in preferanced to the system locale - Locale locale = null; - - Serializable localeProperty = properties.get(ContentModel.PROP_LOCALE); - if (localeProperty != null) - { - locale = DefaultTypeConverter.INSTANCE.convert(Locale.class, localeProperty); - } - - if (locale == null) - { - locale = I18NUtil.getLocale(); - } - - StringBuilder builder; - MLAnalysisMode analysisMode; - VerbatimAnalyser vba; - MLTokenDuplicator duplicator; - Token t; - switch (tokenise) - { - default: - case TRUE: - builder = new StringBuilder(); - builder.append("\u0000").append(locale.toString()).append("\u0000").append(strValue); - doc.add(new Field(attributeName, builder.toString(), fieldStore, fieldIndex, Field.TermVector.NO)); - break; - case FALSE: - analysisMode = getLuceneConfig().getDefaultMLIndexAnalysisMode(); - // Do the analysis here - vba = new VerbatimAnalyser(false); - duplicator = new MLTokenDuplicator(vba.tokenStream(attributeName, new StringReader(strValue)), locale, null, analysisMode); - try - { - while ((t = duplicator.next()) != null) - { - String localeText = ""; - if (t.termText().indexOf('{') == 0) - { - int end = t.termText().indexOf('}', 1); - if (end != -1) - { - localeText = t.termText().substring(1, end); - } - } - if (localeText.length() > 0) - { - doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - - doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - } - catch (IOException e) - { - // TODO ?? - } - - break; - case BOTH: - builder = new StringBuilder(); - builder.append("\u0000").append(locale.toString()).append("\u0000").append(strValue); - doc.add(new Field(attributeName, builder.toString(), fieldStore, fieldIndex, Field.TermVector.NO)); - - analysisMode = getLuceneConfig().getDefaultMLIndexAnalysisMode(); - // Do the analysis here - vba = new VerbatimAnalyser(false); - duplicator = new MLTokenDuplicator(vba.tokenStream(attributeName, new StringReader(strValue)), locale, null, analysisMode); - try - { - while ((t = duplicator.next()) != null) - { - String localeText = ""; - if (t.termText().indexOf('{') == 0) - { - int end = t.termText().indexOf('}', 1); - if (end != -1) - { - localeText = t.termText().substring(1, end); - } - } - if (localeText.length() > 0) - { - doc.add(new Field(attributeName + "." + localeText + ".sort", t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - } - } - catch (IOException e) - { - // TODO ?? - } - break; - } - } - else if (isDateTime) - { - SimpleDateFormat df; - Date date; - switch (tokenise) - { - default: - case TRUE: - doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); - break; - case FALSE: - df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); - try - { - date = df.parse(strValue); - doc.add(new Field(attributeName, df.format(date), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - catch (ParseException e) - { - // ignore for ordering - } - break; - case BOTH: - doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); - - df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); - try - { - date = df.parse(strValue); - doc.add(new Field(attributeName + ".sort", df.format(date), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); - } - catch (ParseException e) - { - // ignore for ordering - } - break; - } - } - else - { - doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); - } - } - } - } - - // return wereAllAtomic; - return true; - } - - @Override - protected void doPrepare() throws IOException - { - AuthenticationUtil.runAs(new RunAsWork() - { - public String doWork() throws Exception - { - flushPending(); - return null; - } - }, AuthenticationUtil.getSystemUserName()); - } - - @Override - protected void doCommit() throws IOException - { - if (indexUpdateStatus == IndexUpdateStatus.ASYNCHRONOUS) - { - setInfo(docs, getDeletions(), getContainerDeletions(), false); - // FTS does not trigger indexing request - } - else - { - setInfo(docs, getDeletions(), getContainerDeletions(), false); - // TODO: only register if required - fullTextSearchIndexer.requiresIndex(store); - } - if (callBack != null) - { - callBack.indexCompleted(store, remainingCount, null); - } - - setInfo(docs, deletions, containerDeletions, false); - } - - @Override - protected void doRollBack() throws IOException - { - if (callBack != null) - { - callBack.indexCompleted(store, 0, null); - } - } - - @Override - protected void doSetRollbackOnly() throws IOException - { - - } - - // The standard indexer API - although implemented it is not likely to be used at the moment - // Batch indexing makes more sense for AVM at snaphot time - - public void createNode(ChildAssociationRef relationshipRef) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Create node " + relationshipRef.getChildRef()); - } - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - NodeRef childRef = relationshipRef.getChildRef(); - Pair versionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - index(versionPath.getSecond()); - // TODO: Deal with a create on the root node deleting the index. - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Create node failed", e); - } - } - - @Override - public void detectNodeChanges(NodeRef nodeRef, SearchService searcher, - Collection addedParents, Collection deletedParents, - Collection createdNodes, Collection updatedNodes) - { - updatedNodes.add(nodeRef); - } - - public void updateNode(NodeRef nodeRef) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Update node " + nodeRef); - } - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - Pair versionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - reindex(versionPath.getSecond(), false); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Update node failed", e); - } - } - - public void deleteNode(ChildAssociationRef relationshipRef) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Delete node " + relationshipRef.getChildRef()); - } - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - NodeRef childRef = relationshipRef.getChildRef(); - Pair versionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - reindex(versionPath.getSecond(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Delete node failed", e); - } - } - - public void createChildRelationship(ChildAssociationRef relationshipRef) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Create child " + relationshipRef); - } - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - NodeRef childRef = relationshipRef.getChildRef(); - Pair versionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - reindex(versionPath.getSecond(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed to create child relationship", e); - } - } - - public void updateChildRelationship(ChildAssociationRef relationshipBeforeRef, ChildAssociationRef relationshipAfterRef) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Update child " + relationshipBeforeRef + " to " + relationshipAfterRef); - } - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - NodeRef childRef = relationshipBeforeRef.getChildRef(); - Pair versionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - reindex(versionPath.getSecond(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed to update child relationship", e); - } - } - - public void deleteChildRelationship(ChildAssociationRef relationshipRef) - { - - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Delete child " + relationshipRef); - } - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - NodeRef childRef = relationshipRef.getChildRef(); - Pair versionPath = AVMNodeConverter.ToAVMVersionPath(childRef); - reindex(versionPath.getSecond(), true); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed to delete child relationship", e); - } - - } - - public void deleteIndex(String store, IndexMode mode) - { - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - switch (mode) - { - case ASYNCHRONOUS: - asyncronousDeleteIndex(store); - break; - case SYNCHRONOUS: - syncronousDeleteIndex(store); - break; - case UNINDEXED: - // nothing to do - break; - } - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Delete index failed", e); - } - } - - /** - * Sync delete of this index - * - * @param store - */ - public void syncronousDeleteIndex(String store) - { - - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Sync delete for " + store); - } - deleteAll(); - } - - /** - * Support to delete all entries frmo the idnex in the background - * - * @param store - */ - public void asyncronousDeleteIndex(String store) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Async delete for " + store); - } - index("\u0000BG:DELETE:" + store + ":" + GUID.generate()); - fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store)); - } - - public void createIndex(String store, IndexMode mode) - { - checkAbleToDoWork(IndexUpdateStatus.SYNCRONOUS); - try - { - switch (mode) - { - case ASYNCHRONOUS: - asyncronousCreateIndex(store); - break; - case SYNCHRONOUS: - syncronousCreateIndex(store); - break; - case UNINDEXED: - // nothing to do - break; - } - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Create index failed", e); - } - } - - /** - * Sync create index - * - * @param store - */ - public void syncronousCreateIndex(String store) - { - - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Sync create for " + store); - } - @SuppressWarnings("unused") - AVMNodeDescriptor rootDesc = avmService.getStoreRoot(-1, store); - index(store + ":/"); - - } - - /** - * Asyn create index - * - * @param store - */ - public void asyncronousCreateIndex(String store) - { - if (s_logger.isDebugEnabled()) - { - s_logger.debug("Async create for " + store); - } - index("\u0000BG:CREATE:" + store + ":" + GUID.generate()); - fullTextSearchIndexer.requiresIndex(AVMNodeConverter.ToStoreRef(store)); - } - - public void registerCallBack(FTSIndexerAware callBack) - { - this.callBack = callBack; - } - - public int updateFullTextSearch(int size) - { - checkAbleToDoWork(IndexUpdateStatus.ASYNCHRONOUS); - - try - { - PrefixQuery query = new PrefixQuery(new Term("ID", "\u0000BG:")); - - String action = null; - - Searcher searcher = null; - try - { - searcher = getSearcher(null); - // commit on another thread - appears like there is no index ...try later - if (searcher == null) - { - remainingCount = size; - return 0; - } - Hits hits; - try - { - hits = searcher.search(query); - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to execute query to find content which needs updating in the index", e); - } - - if (hits.length() > 0) - { - Document doc = hits.doc(0); - action = doc.getField("ID").stringValue(); - String[] split = action.split(":"); - if (split[1].equals("DELETE")) - { - deleteAll("\u0000BG:"); - } - else if (split[1].equals("CREATE")) - { - syncronousCreateIndex(split[2]); - } - else if (split[1].equals("STORE")) - { - synchronousIndex(split[2], Integer.parseInt(split[3]), Integer.parseInt(split[4])); - } - deletions.add(action); - remainingCount = hits.length() - 1; - return 1; - } - else - { - remainingCount = 0; - return 0; - } - - } - finally - { - if (searcher != null) - { - try - { - searcher.close(); - } - catch (IOException e) - { - throw new LuceneIndexException("Failed to close searcher", e); - } - } - } - } - catch (IOException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed FTS update", e); - } - catch (LuceneIndexException e) - { - setRollbackOnly(); - throw new LuceneIndexException("Failed FTS update", e); - } - } - - public void setFullTextSearchIndexer(FullTextSearchIndexer fullTextSearchIndexer) - { - this.fullTextSearchIndexer = fullTextSearchIndexer; - } - - - public boolean isSnapshotIndexed(String store, int id) - { - if (id == 0) - { - return hasIndexBeenCreated(store); - } - else - { - return isSynchronousSnapshotPresent(store, id) || isAsynchronousSnapshotPresent(store, id); - } - } - - private boolean isSynchronousSnapshotPresent(String store, int id) - { - return isSynchronousSnapshotPresent(store, IndexChannel.MAIN, id) || isSynchronousSnapshotPresent(store, IndexChannel.DELTA, id) ; - } - - private boolean isAsynchronousSnapshotPresent(String store, int id) - { - return isAsynchronousSnapshotPresent(store, IndexChannel.MAIN, id) || isAsynchronousSnapshotPresent(store, IndexChannel.DELTA, id) ; - } - - public boolean isSnapshotSearchable(String store, int id) - { - if (id == 0) - { - return hasIndexBeenCreated(store); - } - else - { - return isSynchronousSnapshotPresent(store, id); - } - } - - - private boolean isSynchronousSnapshotPresent(String store, IndexChannel channel, int snapshot) - { - String prefix = SNAP_SHOT_ID + ":" + store + ":"; - IndexReader reader = null; - try - { - if (channel == IndexChannel.DELTA) - { - flushPending(); - reader = getDeltaReader(); - } - else - { - reader = getReader(); - } - - TermEnum terms = null; - try - { - terms = reader.terms(new Term("ID", prefix)); - if (terms.term() != null) - { - do - { - Term term = terms.term(); - if (term.text().startsWith(prefix)) - { - TermDocs docs = null; - try - { - docs = reader.termDocs(term); - if (docs.next()) - { - String[] split = term.text().split(":"); - int test = Integer.parseInt(split[3]); - if (test == snapshot) - { - return true; - } - } - } - finally - { - if (docs != null) - { - docs.close(); - } - } - } - else - { - break; - } - } - while (terms.next()); - } - } - finally - { - if (terms != null) - { - terms.close(); - } - } - return false; - } - catch (IOException e) - { - throw new AlfrescoRuntimeException("IO error", e); - } - finally - { - try - { - if (reader != null) - { - if (channel == IndexChannel.DELTA) - { - closeDeltaReader(); - } - else - { - reader.close(); - } - } - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - } - - private boolean isAsynchronousSnapshotPresent(String store, IndexChannel channel, int snapshot) - { - String prefix = "\u0000BG:STORE:" + store + ":"; - IndexReader reader = null; - try - { - if (channel == IndexChannel.DELTA) - { - flushPending(); - reader = getDeltaReader(); - } - else - { - reader = getReader(); - } - TermEnum terms = null; - try - { - terms = reader.terms(new Term("ID", prefix)); - if (terms.term() != null) - { - do - { - Term term = terms.term(); - if (term.text().startsWith(prefix)) - { - TermDocs docs = null; - try - { - docs = reader.termDocs(term); - if (docs.next()) - { - String[] split = term.text().split(":"); - int test = Integer.parseInt(split[4]); - if (test == snapshot) - { - return true; - } - } - } - finally - { - if (docs != null) - { - docs.close(); - } - } - - } - else - { - break; - } - } - while (terms.next()); - } - } - finally - { - if (terms != null) - { - terms.close(); - } - } - return false; - } - catch (IOException e) - { - throw new AlfrescoRuntimeException("IO error", e); - } - finally - { - try - { - if (reader != null) - { - if (channel == IndexChannel.DELTA) - { - closeDeltaReader(); - } - else - { - reader.close(); - } - } - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - } - - - public boolean hasIndexBeenCreated(String store) - { - return hasIndexBeenCreatedimpl(store, IndexChannel.MAIN) || hasIndexBeenCreatedimpl(store, IndexChannel.DELTA); - } - - public boolean hasIndexBeenCreatedimpl(String store, IndexChannel channel) - { - IndexReader reader = null; - try - { - if (channel == IndexChannel.DELTA) - { - flushPending(); - reader = getDeltaReader(); - } - else - { - reader = getReader(); - } - TermDocs termDocs = null; - try - { - termDocs = reader.termDocs(new Term("ISROOT", "T")); - return termDocs.next(); - } - finally - { - if (termDocs != null) - { - termDocs.close(); - } - } - } - catch (IOException e) - { - throw new AlfrescoRuntimeException("IO error", e); - } - finally - { - try - { - - if (reader != null) - { - if (channel == IndexChannel.DELTA) - { - closeDeltaReader(); - } - else - { - reader.close(); - } - } - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - - } - - public synchronized long getIndexedDocCount() - { - return indexedDocCount; - } - - private synchronized void incrementDocCount() - { - indexedDocCount++; - } - - public int getLastIndexedSnapshot(String store) - { - int last = getLastAsynchronousSnapshot(store); - if (last > 0) - { - return last; - } - last = getLastSynchronousSnapshot(store); - if (last > 0) - { - return last; - } - return hasIndexBeenCreated(store) ? 0 : -1; - } - - private int getLastSynchronousSnapshot(String store) - { - int answer = getLastSynchronousSnapshot(store, IndexChannel.DELTA); - if (answer >= 0) - { - return answer; - } - answer = getLastSynchronousSnapshot(store, IndexChannel.MAIN); - if (answer >= 0) - { - return answer; - } - return -1; - } - - private int getLastSynchronousSnapshot(String store, IndexChannel channel) - { - String prefix = SNAP_SHOT_ID + ":" + store + ":"; - IndexReader reader = null; - int end = -1; - try - { - if (channel == IndexChannel.DELTA) - { - flushPending(); - reader = getDeltaReader(); - } - else - { - reader = getReader(); - } - - TermEnum terms = null; - try - { - terms = reader.terms(new Term("ID", prefix)); - if (terms.term() != null) - { - do - { - Term term = terms.term(); - if (term.text().startsWith(prefix)) - { - TermDocs docs = null; - try - { - docs = reader.termDocs(term); - if (docs.next()) - { - String[] split = term.text().split(":"); - int test = Integer.parseInt(split[3]); - if (test > end) - { - end = test; - } - } - } - finally - { - if (docs != null) - { - docs.close(); - } - } - } - else - { - break; - } - } - while (terms.next()); - } - } - finally - { - if (terms != null) - { - terms.close(); - } - } - return end; - } - catch (IOException e) - { - throw new AlfrescoRuntimeException("IO error", e); - } - finally - { - try - { - if (reader != null) - { - if (channel == IndexChannel.DELTA) - { - closeDeltaReader(); - } - else - { - reader.close(); - } - } - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - } - - private int getLastAsynchronousSnapshot(String store) - { - int answer = getLastAsynchronousSnapshot(store, IndexChannel.DELTA); - if (answer >= 0) - { - return answer; - } - answer = getLastAsynchronousSnapshot(store, IndexChannel.MAIN); - if (answer >= 0) - { - return answer; - } - return -1; - } - - private int getLastAsynchronousSnapshot(String store, IndexChannel channel) - { - String prefix = "\u0000BG:STORE:" + store + ":"; - IndexReader reader = null; - int end = -1; - try - { - if (channel == IndexChannel.DELTA) - { - flushPending(); - reader = getDeltaReader(); - } - else - { - reader = getReader(); - } - TermEnum terms = null; - try - { - terms = reader.terms(new Term("ID", prefix)); - if (terms.term() != null) - { - do - { - Term term = terms.term(); - if (term.text().startsWith(prefix)) - { - TermDocs docs = null; - try - { - docs = reader.termDocs(term); - if (docs.next()) - { - String[] split = term.text().split(":"); - int test = Integer.parseInt(split[4]); - if (test > end) - { - end = test; - } - } - } - finally - { - if (docs != null) - { - docs.close(); - } - } - - } - else - { - break; - } - } - while (terms.next()); - } - } - finally - { - if (terms != null) - { - terms.close(); - } - } - return end; - } - catch (IOException e) - { - throw new AlfrescoRuntimeException("IO error", e); - } - finally - { - try - { - if (reader != null) - { - if (channel == IndexChannel.DELTA) - { - closeDeltaReader(); - } - else - { - reader.close(); - } - } - } - catch (IOException e) - { - s_logger.warn("Failed to close main reader", e); - } - } - } - - /* (non-Javadoc) - * @see org.alfresco.repo.search.Indexer#deleteIndex(org.alfresco.service.cmr.repository.StoreRef) - */ - public void deleteIndex(StoreRef storeRef) - { - deleteIndex(); - - } - - /** - * Delete all entries from the index. - */ - public void deleteAll() - { - deleteAll(null); - } - - /** - * Delete all index entries which do not start with the given prefix - * - * @param prefix - */ - public void deleteAll(String prefix) - { - IndexReader mainReader = null; - try - { - mainReader = getReader(); - for (int doc = 0; doc < mainReader.maxDoc(); doc++) - { - if (!mainReader.isDeleted(doc)) - { - Document document = mainReader.document(doc); - String[] ids = document.getValues("ID"); - if ((prefix == null) || nonStartwWith(ids, prefix)) - { - deletions.add(ids[ids.length - 1]); - // should be included in the deletion cache if we move back to caching at the TX level and not the flush level - // Entries here will currently be ignored as the list is cleared at the start and end of a flush. - deletionsSinceFlush.add(ids[ids.length - 1]); - } - } - } - - } - catch (IOException e) - { - // If anything goes wrong we try and do a roll back - throw new LuceneIndexException("Failed to delete all entries from the index", e); - } - finally - { - if (mainReader != null) - { - try - { - mainReader.close(); - } - catch (IOException e) - { - throw new LuceneIndexException("Filed to close main reader", e); - } - } - } - } - - private boolean nonStartwWith(String[] values, String prefix) - { - for (String value : values) - { - if (value.startsWith(prefix)) - { - return false; - } - } - return true; - } - -} diff --git a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java index b73b008402..905f9e7b98 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java @@ -32,7 +32,7 @@ import net.sf.acegisecurity.providers.dao.User; import org.alfresco.model.ContentModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.AVMRepository; +//import org.alfresco.repo.avm.AVMRepository; import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.domain.permissions.AclDAO; import org.alfresco.repo.policy.JavaBehaviour; @@ -613,12 +613,15 @@ public class PermissionServiceImpl extends AbstractLifecycleBean implements Perm private AccessStatus doAvmCan(NodeRef nodeRef, PermissionReference permission) { + /* Sparta: remove WCM/AVM org.alfresco.util.Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); int version = avmVersionPath.getFirst(); String path = avmVersionPath.getSecond(); boolean result = AVMRepository.GetInstance().can(nodeRef.getStoreRef().getIdentifier(), version, path, permission.getName()); AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; return status; + */ + return AccessStatus.DENIED; } /* diff --git a/source/test-java/org/alfresco/repo/node/index/FullIndexRecoveryComponentTest.java b/source/test-java/org/alfresco/repo/node/index/FullIndexRecoveryComponentTest.java index 088d5c8298..fe85596850 100644 --- a/source/test-java/org/alfresco/repo/node/index/FullIndexRecoveryComponentTest.java +++ b/source/test-java/org/alfresco/repo/node/index/FullIndexRecoveryComponentTest.java @@ -51,7 +51,6 @@ public class FullIndexRecoveryComponentTest extends TestCase private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); private FullIndexRecoveryComponent indexRecoverer; - private AVMFullIndexRecoveryComponent avmIndexRecoveryComponent; private NodeService nodeService; private NodeRef rootNodeRef; private TransactionService transactionService; @@ -63,7 +62,6 @@ public class FullIndexRecoveryComponentTest extends TestCase { ChildApplicationContextFactory luceneSubSystem = (ChildApplicationContextFactory) ctx.getBean("lucene"); indexRecoverer = (FullIndexRecoveryComponent) luceneSubSystem.getApplicationContext().getBean("search.indexRecoveryComponent"); - avmIndexRecoveryComponent = (AVMFullIndexRecoveryComponent) luceneSubSystem.getApplicationContext().getBean("search.avmIndexRecoveryComponent"); nodeService = (NodeService) ctx.getBean("nodeService"); transactionService = (TransactionService) ctx.getBean("transactionComponent"); authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); @@ -151,7 +149,6 @@ public class FullIndexRecoveryComponentTest extends TestCase public synchronized void testReindexing() throws Exception { indexRecoverer.setRecoveryMode(FullIndexRecoveryComponent.RecoveryMode.FULL.name()); - avmIndexRecoveryComponent.setRecoveryMode(FullIndexRecoveryComponent.RecoveryMode.FULL.name()); // reindex Thread reindexThread = new Thread() { @@ -160,27 +157,16 @@ public class FullIndexRecoveryComponentTest extends TestCase indexRecoverer.reindex(); } }; - Thread avmReindexThread = new Thread() - { - public void run() - { - avmIndexRecoveryComponent.reindex(); - } - }; //reindexThread.setDaemon(true); - //avmReindexThread.setDaemon(true); reindexThread.start(); - avmReindexThread.start(); // must allow the rebuild to complete or the test after this one will fail to validate their indexes // - as they now will be deleted. reindexThread.join(); - avmReindexThread.join(); // wait a bit and then terminate wait(20000); indexRecoverer.setShutdown(true); - avmIndexRecoveryComponent.setShutdown(true); wait(20000); } }