From be8b2fa355bcd06483be0bbe1d8d6da642130c8c Mon Sep 17 00:00:00 2001 From: Alan Davis Date: Sat, 14 Nov 2015 13:35:19 +0000 Subject: [PATCH] Merged HEAD (5.1) to 5.1.N (5.1.1) 117483 bhorje: CM-690 extensions git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.1.N/root@117567 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/repo/lock/LockServiceImpl.java | 42 +++++++++++++- .../lock/mem/LockableAspectInterceptor.java | 57 ++++++++++++++++--- .../traitextender/LockServiceExtension.java | 26 +++++++++ .../lock/traitextender/LockServiceTrait.java | 27 +++++++++ .../LockableAspectInterceptorExtension.java | 28 +++++++++ .../LockableAspectInterceptorTrait.java | 29 ++++++++++ 6 files changed, 200 insertions(+), 9 deletions(-) create mode 100644 source/java/org/alfresco/repo/lock/traitextender/LockServiceExtension.java create mode 100644 source/java/org/alfresco/repo/lock/traitextender/LockServiceTrait.java create mode 100644 source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorExtension.java create mode 100644 source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorTrait.java diff --git a/source/java/org/alfresco/repo/lock/LockServiceImpl.java b/source/java/org/alfresco/repo/lock/LockServiceImpl.java index 9c29f6f262..e920dd0bb0 100644 --- a/source/java/org/alfresco/repo/lock/LockServiceImpl.java +++ b/source/java/org/alfresco/repo/lock/LockServiceImpl.java @@ -38,6 +38,8 @@ import org.alfresco.repo.lock.mem.Lifetime; import org.alfresco.repo.lock.mem.LockState; import org.alfresco.repo.lock.mem.LockStore; import org.alfresco.repo.lock.mem.LockableAspectInterceptor; +import org.alfresco.repo.lock.traitextender.LockServiceExtension; +import org.alfresco.repo.lock.traitextender.LockServiceTrait; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.node.index.NodeIndexer; import org.alfresco.repo.policy.BehaviourFilter; @@ -67,6 +69,11 @@ import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.namespace.QName; +import org.alfresco.traitextender.Extend; +import org.alfresco.traitextender.ExtendedTrait; +import org.alfresco.traitextender.Extensible; +import org.alfresco.traitextender.AJProxyTrait; +import org.alfresco.traitextender.Trait; import org.alfresco.util.Pair; import org.alfresco.util.PropertyCheck; import org.springframework.util.Assert; @@ -82,7 +89,8 @@ public class LockServiceImpl implements LockService, NodeServicePolicies.BeforeDeleteNodePolicy, NodeServicePolicies.OnMoveNodePolicy, CopyServicePolicies.OnCopyNodePolicy, - VersionServicePolicies.OnCreateVersionPolicy, TransactionListener + VersionServicePolicies.OnCreateVersionPolicy, TransactionListener, + Extensible { public static final int MAX_EPHEMERAL_LOCK_SECONDS = 2 * 86400; @@ -105,6 +113,13 @@ public class LockServiceImpl implements LockService, private NodeIndexer nodeIndexer; private int ephemeralExpiryThreshold; + + private final ExtendedTrait lockServiceTrait; + + public LockServiceImpl() + { + this.lockServiceTrait=new ExtendedTrait(AJProxyTrait.create(this, LockServiceTrait.class)); + } public void setNodeService(NodeService nodeService) { @@ -270,6 +285,7 @@ public class LockServiceImpl implements LockService, /** * @see org.alfresco.service.cmr.lock.LockService#lock(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.lock.LockType) */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void lock(NodeRef nodeRef, LockType lockType) { // Lock with no expiration @@ -280,6 +296,7 @@ public class LockServiceImpl implements LockService, * @see org.alfresco.service.cmr.lock.LockService#lock(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.lock.LockType, int) */ @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void lock(NodeRef nodeRef, LockType lockType, int timeToExpire) { lock(nodeRef, lockType, timeToExpire, Lifetime.PERSISTENT); @@ -289,6 +306,7 @@ public class LockServiceImpl implements LockService, * @see org.alfresco.service.cmr.lock.LockService#lock(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.lock.LockType, int, Lifetime, String) */ @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void lock(NodeRef nodeRef, LockType lockType, int timeToExpire, Lifetime lifetime) { lock(nodeRef, lockType, timeToExpire, lifetime, null); @@ -298,6 +316,7 @@ public class LockServiceImpl implements LockService, * @see org.alfresco.service.cmr.lock.LockService#lock(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.lock.LockType, int, Lifetime, String) */ @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void lock(NodeRef nodeRef, LockType lockType, int timeToExpire, Lifetime lifetime, String additionalInfo) { invokeBeforeLock(nodeRef, lockType); @@ -416,6 +435,7 @@ public class LockServiceImpl implements LockService, /** * @see org.alfresco.service.cmr.lock.LockService#lock(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.lock.LockType, int, boolean) */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void lock(NodeRef nodeRef, LockType lockType, int timeToExpire, boolean lockChildren) throws UnableToAquireLockException { @@ -434,6 +454,7 @@ public class LockServiceImpl implements LockService, /** * @see org.alfresco.service.cmr.lock.LockService#lock(java.util.Collection, org.alfresco.service.cmr.lock.LockType, int) */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void lock(Collection nodeRefs, LockType lockType, int timeToExpire) throws UnableToAquireLockException { @@ -448,6 +469,7 @@ public class LockServiceImpl implements LockService, * @see org.alfresco.service.cmr.lock.LockService#unlock(NodeRef) */ @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void unlock(NodeRef nodeRef) throws UnableToReleaseLockException { unlock(nodeRef, false, false); @@ -457,6 +479,7 @@ public class LockServiceImpl implements LockService, * @see org.alfresco.service.cmr.lock.LockService#unlock(org.alfresco.service.cmr.repository.NodeRef, boolean) */ @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void unlock(NodeRef nodeRef, boolean lockChildren) throws UnableToReleaseLockException { unlock(nodeRef, lockChildren, false); @@ -466,6 +489,7 @@ public class LockServiceImpl implements LockService, * @see org.alfresco.service.cmr.lock.LockService#unlock(NodeRef, boolean, boolean) */ @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void unlock(NodeRef nodeRef, boolean unlockChildren, boolean allowCheckedOut) throws UnableToReleaseLockException { @@ -530,6 +554,7 @@ public class LockServiceImpl implements LockService, /** * @see org.alfresco.service.cmr.lock.LockService#unlock(Collection) */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void unlock(Collection nodeRefs) throws UnableToReleaseLockException { for (NodeRef nodeRef : nodeRefs) @@ -541,6 +566,7 @@ public class LockServiceImpl implements LockService, /** * @see org.alfresco.service.cmr.lock.LockService#getLockStatus(NodeRef) */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public LockStatus getLockStatus(NodeRef nodeRef) { nodeRef = tenantService.getName(nodeRef); @@ -555,6 +581,7 @@ public class LockServiceImpl implements LockService, * @param userName the user name * @return the lock status */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public LockStatus getLockStatus(NodeRef nodeRef, String userName) { Pair stateAndStatus = getLockStateAndStatus(nodeRef, userName); @@ -575,6 +602,7 @@ public class LockServiceImpl implements LockService, /** * @see LockService#getLockType(NodeRef) */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public LockType getLockType(NodeRef nodeRef) { LockType result = null; @@ -610,6 +638,7 @@ public class LockServiceImpl implements LockService, /** * {@inheritDoc} */ + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void checkForLock(NodeRef nodeRef) throws NodeLockedException { String userName = getUserName(); @@ -802,6 +831,7 @@ public class LockServiceImpl implements LockService, } @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void suspendLocks() { getBehaviourFilter().disableBehaviour(ContentModel.ASPECT_LOCKABLE); @@ -809,6 +839,7 @@ public class LockServiceImpl implements LockService, } @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void enableLocks() { getBehaviourFilter().enableBehaviour(ContentModel.ASPECT_LOCKABLE); @@ -816,6 +847,7 @@ public class LockServiceImpl implements LockService, } @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public String getAdditionalInfo(NodeRef nodeRef) { LockState lockState = getLockState(nodeRef); @@ -824,6 +856,7 @@ public class LockServiceImpl implements LockService, } @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public LockState getLockState(NodeRef nodeRef) { // Check in-memory for ephemeral locks first. @@ -915,6 +948,7 @@ public class LockServiceImpl implements LockService, } @Override + @Extend(traitAPI=LockServiceTrait.class,extensionAPI=LockServiceExtension.class) public void setEphemeralExpiryThreshold(int threshSecs) { ephemeralExpiryThreshold = threshSecs; @@ -924,4 +958,10 @@ public class LockServiceImpl implements LockService, { return ephemeralExpiryThreshold; } + + @Override + public ExtendedTrait getTrait(Class traitAPI) + { + return (ExtendedTrait) lockServiceTrait; + } } diff --git a/source/java/org/alfresco/repo/lock/mem/LockableAspectInterceptor.java b/source/java/org/alfresco/repo/lock/mem/LockableAspectInterceptor.java index acb4dd5f0a..769a27f0e6 100644 --- a/source/java/org/alfresco/repo/lock/mem/LockableAspectInterceptor.java +++ b/source/java/org/alfresco/repo/lock/mem/LockableAspectInterceptor.java @@ -25,11 +25,18 @@ import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; +import org.alfresco.repo.lock.traitextender.LockableAspectInterceptorExtension; +import org.alfresco.repo.lock.traitextender.LockableAspectInterceptorTrait; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.namespace.QName; +import org.alfresco.traitextender.AJExtender; +import org.alfresco.traitextender.Extend; +import org.alfresco.traitextender.ExtendedTrait; +import org.alfresco.traitextender.Extensible; +import org.alfresco.traitextender.Trait; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -44,7 +51,7 @@ import org.aopalliance.intercept.MethodInvocation; * * @author Matt Ward */ -public class LockableAspectInterceptor implements MethodInterceptor +public class LockableAspectInterceptor implements MethodInterceptor, Extensible { private LockStore lockStore; private AuthenticationService authenticationService; @@ -55,6 +62,8 @@ public class LockableAspectInterceptor implements MethodInterceptor private final ThreadLocal threadEnabled; + private final ExtendedTrait lockableAspectInterceptorTrait; + /** * Default constructor. */ @@ -69,6 +78,7 @@ public class LockableAspectInterceptor implements MethodInterceptor return Boolean.TRUE; } }; + lockableAspectInterceptorTrait=new ExtendedTrait(createTrait()); } public void init() @@ -101,9 +111,7 @@ public class LockableAspectInterceptor implements MethodInterceptor NodeRef nodeRef = (NodeRef) args[0]; QName aspectTypeQName = (QName) args[1]; - // If the hasAspect() call is checking for cm:lockable and this is an ephemeral lock, - // then spoof the aspect's existence on the node. - LockState lockState = lockStore.get(nodeRef); + LockState lockState = getLockState(nodeRef); if (ContentModel.ASPECT_LOCKABLE.equals(aspectTypeQName) && isEphemeralLock(lockState)) { return true; @@ -114,7 +122,7 @@ public class LockableAspectInterceptor implements MethodInterceptor { NodeRef nodeRef = (NodeRef) args[0]; Set aspects = (Set) invocation.proceed(); - LockState lockState = lockStore.get(nodeRef); + LockState lockState = getLockState(nodeRef); if (isEphemeralLock(lockState) && !aspects.contains(ContentModel.ASPECT_LOCKABLE)) { aspects.add(ContentModel.ASPECT_LOCKABLE); @@ -126,7 +134,7 @@ public class LockableAspectInterceptor implements MethodInterceptor NodeRef nodeRef = (NodeRef) args[0]; Map properties = (Map) invocation.proceed(); - LockState lockState = lockStore.get(nodeRef); + LockState lockState = getLockState(nodeRef); if (isEphemeralLock(lockState)) { String userName = lockState.getOwner(); @@ -153,7 +161,7 @@ public class LockableAspectInterceptor implements MethodInterceptor // Avoid locking unless it is an interesting property. if (isLockProperty(propQName)) { - LockState lockState = lockStore.get(nodeRef); + LockState lockState = getLockState(nodeRef); if (isEphemeralLock(lockState)) { if (ContentModel.PROP_LOCK_OWNER.equals(propQName)) @@ -289,7 +297,7 @@ public class LockableAspectInterceptor implements MethodInterceptor private void checkForLockIfEphemeral(NodeRef nodeRef) { - LockState lockState = lockStore.get(nodeRef); + LockState lockState = getLockState(nodeRef); if (isEphemeralLock(lockState)) { lockService.checkForLock(nodeRef); @@ -314,4 +322,37 @@ public class LockableAspectInterceptor implements MethodInterceptor public void setLockService(LockService lockService) { this.lockService = lockService; } + + @Extend(traitAPI=LockableAspectInterceptorTrait.class,extensionAPI=LockableAspectInterceptorExtension.class) + private LockState getLockState(NodeRef nodeRef) + { + LockState lockState = lockStore.get(nodeRef); + return lockState; + } + + private LockableAspectInterceptorTrait createTrait() + { + return new LockableAspectInterceptorTrait() + { + + @Override + public LockState traitImplOf_getLockState(final NodeRef nodeRef) + { + return AJExtender.run(new AJExtender.ExtensionBypass() + { + @Override + public LockState run() + { + return getLockState(nodeRef); + }; + }); + } + }; + } + + @Override + public ExtendedTrait getTrait(Class traitAPI) + { + return (ExtendedTrait) lockableAspectInterceptorTrait; + } } diff --git a/source/java/org/alfresco/repo/lock/traitextender/LockServiceExtension.java b/source/java/org/alfresco/repo/lock/traitextender/LockServiceExtension.java new file mode 100644 index 0000000000..a8c609666a --- /dev/null +++ b/source/java/org/alfresco/repo/lock/traitextender/LockServiceExtension.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2005-2015 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 http://www.gnu.org/licenses/. + */ +package org.alfresco.repo.lock.traitextender; + +import org.alfresco.service.cmr.lock.LockService; + +public interface LockServiceExtension extends LockService +{ + +} diff --git a/source/java/org/alfresco/repo/lock/traitextender/LockServiceTrait.java b/source/java/org/alfresco/repo/lock/traitextender/LockServiceTrait.java new file mode 100644 index 0000000000..8bacc314ef --- /dev/null +++ b/source/java/org/alfresco/repo/lock/traitextender/LockServiceTrait.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2005-2015 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 http://www.gnu.org/licenses/. + */ +package org.alfresco.repo.lock.traitextender; + +import org.alfresco.service.cmr.lock.LockService; +import org.alfresco.traitextender.Trait; + +public interface LockServiceTrait extends Trait,LockService +{ + +} diff --git a/source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorExtension.java b/source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorExtension.java new file mode 100644 index 0000000000..4f4b878456 --- /dev/null +++ b/source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorExtension.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005-2015 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 http://www.gnu.org/licenses/. + */ + +package org.alfresco.repo.lock.traitextender; + +import org.alfresco.repo.lock.mem.LockState; +import org.alfresco.service.cmr.repository.NodeRef; + +public interface LockableAspectInterceptorExtension +{ + LockState getLockState(NodeRef nodeRef); +} diff --git a/source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorTrait.java b/source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorTrait.java new file mode 100644 index 0000000000..6161153a52 --- /dev/null +++ b/source/java/org/alfresco/repo/lock/traitextender/LockableAspectInterceptorTrait.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005-2015 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 http://www.gnu.org/licenses/. + */ + +package org.alfresco.repo.lock.traitextender; + +import org.alfresco.repo.lock.mem.LockState; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.traitextender.Trait; + +public interface LockableAspectInterceptorTrait extends Trait +{ + LockState traitImplOf_getLockState(NodeRef nodeRef); +}