split aspectj management; refactored
This commit is contained in:
parent
85ff365031
commit
5728b2a92b
15
pom.xml
15
pom.xml
@ -36,6 +36,8 @@
|
||||
|
||||
<alfresco.sdk.version>4.2.0</alfresco.sdk.version>
|
||||
<alfresco.platform.version>6.2.0-ga</alfresco.platform.version>
|
||||
<aspectj.version>1.9.4</aspectj.version>
|
||||
<acs-platform.tomcat.opts>-javaagent:/var/lib/tomcat/dev/lib/aspectjweaver-${aspectj.version}.jar</acs-platform.tomcat.opts>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -58,6 +60,11 @@
|
||||
<artifactId>alfresco-repository</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.inteligr8.alfresco</groupId>
|
||||
<artifactId>aspectj-platform-module</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -65,16 +72,16 @@
|
||||
<plugin>
|
||||
<groupId>io.repaint.maven</groupId>
|
||||
<artifactId>tiles-maven-plugin</artifactId>
|
||||
<version>2.26</version>
|
||||
<version>2.33</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<tiles>
|
||||
<!-- Documentation: https://bitbucket.org/inteligr8/ootbee-beedk/src/stable/beedk-acs-platform-self-rad-tile -->
|
||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-self-rad-tile:[1.0.0,2.0.0)</tile>
|
||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-self-rad-tile:[1.0.0,1.1.0)</tile>
|
||||
<!-- Documentation: https://bitbucket.org/inteligr8/ootbee-beedk/src/stable/beedk-acs-platform-module-tile -->
|
||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-module-tile:[1.0.0,2.0.0)</tile>
|
||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-module-tile:[1.0.0,1.1.0)</tile>
|
||||
<!-- Documentation: https://bitbucket.org/inteligr8/ootbee-beedk/src/stable/beedk-acs-platform-self-it-tile -->
|
||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-self-it-tile:[1.0.0,2.0.0)</tile>
|
||||
<tile>com.inteligr8.ootbee:beedk-acs-platform-self-it-tile:[1.0.0,1.1.0)</tile>
|
||||
</tiles>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
6
rad.sh
6
rad.sh
@ -6,17 +6,17 @@ discoverArtifactId() {
|
||||
|
||||
rebuild() {
|
||||
echo "Rebuilding project ..."
|
||||
mvn process-classes
|
||||
mvn process-test-classes
|
||||
}
|
||||
|
||||
start() {
|
||||
echo "Rebuilding project and starting Docker containers to support rapid application development ..."
|
||||
mvn -Drad process-classes
|
||||
mvn -Drad process-test-classes
|
||||
}
|
||||
|
||||
start_log() {
|
||||
echo "Rebuilding project and starting Docker containers to support rapid application development ..."
|
||||
mvn -Drad -Ddocker.showLogs process-classes
|
||||
mvn -Drad -Ddocker.showLogs process-test-classes
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
||||
ElementType.METHOD,
|
||||
ElementType.PARAMETER
|
||||
})
|
||||
public @interface IfAspect {
|
||||
public @interface IfNodeHasAspect {
|
||||
|
||||
String aspect() default "";
|
||||
|
@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
||||
ElementType.METHOD,
|
||||
ElementType.PARAMETER
|
||||
})
|
||||
public @interface IfNodeType {
|
||||
public @interface IfNodeOfType {
|
||||
|
||||
String type() default "";
|
||||
|
@ -11,7 +11,7 @@ import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
|
||||
public interface AspectConstrainable extends BeanNameAware {
|
||||
public interface NodeAspectConstrainable extends BeanNameAware {
|
||||
|
||||
String getBeanName();
|
||||
|
@ -4,15 +4,14 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.service.AsyncService;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class AsyncAspect {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@ -20,18 +19,23 @@ public class AsyncAspect {
|
||||
@Autowired
|
||||
private AsyncService asyncService;
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Asynchronous)")
|
||||
public void asyncMethod() {
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Asynchronous) && execution(* *(..))")
|
||||
public void isAsyncAnnotated() {
|
||||
}
|
||||
|
||||
@Around("asyncMethod()")
|
||||
public void async(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
@Around("isAsyncAnnotated()")
|
||||
public Object async(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
if (this.asyncService.isCurrentThreadAsynchronous()) {
|
||||
this.logger.trace("Intercepted an @Async method call while already asynchronous; executing synchronously");
|
||||
joinPoint.proceed();
|
||||
return joinPoint.proceed();
|
||||
} else {
|
||||
this.logger.trace("Intercepted an @Async method call; redirecting to Async service");
|
||||
this.asyncService.push(joinPoint);
|
||||
|
||||
MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
|
||||
if (!Void.class.equals(methodSig.getReturnType()))
|
||||
this.logger.warn("An @Asynchronous method returns a value, which is not expected/allowed: {}", methodSig.getMethod());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,35 +14,38 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.Authorizable;
|
||||
import com.inteligr8.alfresco.annotations.Authorized;
|
||||
import com.inteligr8.alfresco.annotations.AuthorizedAsSystem;
|
||||
import com.inteligr8.alfresco.annotations.Authorizable;
|
||||
|
||||
@Aspect
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + Short.MAX_VALUE)
|
||||
@Component
|
||||
public class AuthorizedAspect {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Authorized || com.inteligr8.alfresco.annotations.AuthorizedAsSystem)")
|
||||
public void runAsableMethod() {
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Authorized) && execution(* *(..))")
|
||||
public void isAuthorizedAnnotated() {
|
||||
}
|
||||
|
||||
@Around("runAsableMethod()")
|
||||
public void runAs(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.AuthorizedAsSystem) && execution(* *(..))")
|
||||
public void isAuthorizedAsSystemAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isAuthorizedAnnotated() || isAuthorizedAsSystemAnnotated()")
|
||||
public Object runAs(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.logger.trace("runAs({})", joinPoint);
|
||||
|
||||
String runAsUser = this.getRunAsUser(joinPoint);
|
||||
|
||||
String currentRunAsUser = AuthenticationUtil.getRunAsUser();
|
||||
if (currentRunAsUser != null && currentRunAsUser.equals(runAsUser)) {
|
||||
this.logger.trace("The current context is already running as the specified user: {}", currentRunAsUser);
|
||||
joinPoint.proceed();
|
||||
return joinPoint.proceed();
|
||||
} else {
|
||||
this.logger.debug("Changing runAs context: {} => {}", currentRunAsUser, runAsUser);
|
||||
|
||||
this.runAs(joinPoint, runAsUser);
|
||||
return this.runAs(joinPoint, runAsUser);
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,28 +57,31 @@ public class AuthorizedAspect {
|
||||
Method method = methodSig.getMethod();
|
||||
if (method.getAnnotation(AuthorizedAsSystem.class) != null) {
|
||||
String runAs = AuthenticationUtil.getSystemUserName();
|
||||
this.logger.trace("The @AuthorizedAsSystem method {}#{} will run as: {}", joinPoint.getThis().getClass(), method, runAs);
|
||||
this.logger.trace("The @AuthorizedAsSystem method '{}' will run as: {}", method, runAs);
|
||||
return runAs;
|
||||
}
|
||||
|
||||
if (joinPoint.getThis() instanceof Authorizable) {
|
||||
String runAs = StringUtils.trimToNull(((Authorizable) joinPoint.getThis()).authorizeAsUser());
|
||||
this.logger.trace("The @Authorized method {}#{} is Authorizable: {}", joinPoint.getThis().getClass(), method, runAs);
|
||||
if (runAs == null)
|
||||
throw new IllegalArgumentException("A 'null' value is allowed from authorizeAsUser()");
|
||||
|
||||
this.logger.trace("The @Authorized method '{}' is Authorizable: {}", method, runAs);
|
||||
return runAs;
|
||||
}
|
||||
|
||||
Authorized runAsAnnotation = method.getAnnotation(Authorized.class);
|
||||
String runAs = StringUtils.trimToNull(runAsAnnotation.value());
|
||||
if (runAs != null) {
|
||||
this.logger.trace("The @Authorized method {}#{} must run as: {}", joinPoint.getThis().getClass(), method, runAs);
|
||||
this.logger.trace("The @Authorized method '{}' must run as: {}", method, runAs);
|
||||
return runAs;
|
||||
}
|
||||
|
||||
this.logger.trace("The @Authorized method {}#{} must run as system", joinPoint.getThis().getClass(), method);
|
||||
this.logger.trace("The @Authorized method '{}' must run as system", method);
|
||||
return AuthenticationUtil.getSystemUserName();
|
||||
}
|
||||
|
||||
private void runAs(final ProceedingJoinPoint joinPoint, String runAsUser) throws Throwable {
|
||||
private Object runAs(final ProceedingJoinPoint joinPoint, String runAsUser) throws Throwable {
|
||||
RunAsWork<Object> work = new RunAsWork<Object>() {
|
||||
public Object doWork() throws Exception {
|
||||
try {
|
||||
@ -89,7 +95,7 @@ public class AuthorizedAspect {
|
||||
};
|
||||
|
||||
try {
|
||||
AuthenticationUtil.runAs(work, runAsUser);
|
||||
return AuthenticationUtil.runAs(work, runAsUser);
|
||||
} catch (RuntimeException re) {
|
||||
// attempt to unwrap the exception
|
||||
if (re.getMessage() != null && re.getMessage().equals("Error during run as.")) {
|
||||
|
@ -11,13 +11,11 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary;
|
||||
|
||||
@Aspect
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 100) // ordering before transaction/authorized
|
||||
@Component
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + Byte.MAX_VALUE) // ordering before transaction/authorized
|
||||
public class ChildIsPrimaryAspect extends MethodOrParameterAspect<IfChildAssociationIsPrimary> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@ -27,13 +25,19 @@ public class ChildIsPrimaryAspect extends MethodOrParameterAspect<IfChildAssocia
|
||||
return IfChildAssociationIsPrimary.class;
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary)")
|
||||
public void isChildAssocPrimaryMethod() {
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary) && execution(* *(..))")
|
||||
public void isIfChildAssociationIsPrimaryMethodAnnotated() {
|
||||
}
|
||||
|
||||
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary (*), ..))")
|
||||
public void isIfChildAssociationIsPrimaryParamAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isChildAssocPrimaryMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary (*), ..))")
|
||||
public void isChildAssocPrimary(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.checkParameters(joinPoint, new ApplicableParameterCallback<IfChildAssociationIsPrimary>() {
|
||||
@Around("isIfChildAssociationIsPrimaryMethodAnnotated() || isIfChildAssociationIsPrimaryParamAnnotated()")
|
||||
public Object isChildAssocPrimary(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.logger.trace("isChildAssocPrimary({})", joinPoint);
|
||||
|
||||
return this.checkParameters(joinPoint, new ApplicableParameterCallback<IfChildAssociationIsPrimary>() {
|
||||
@Override
|
||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfChildAssociationIsPrimary annotation, int parameterIndex) {
|
||||
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||
|
@ -14,7 +14,7 @@ public abstract class MethodOrParameterAspect<T extends Annotation> {
|
||||
|
||||
public abstract Class<T> getAnnotationClass();
|
||||
|
||||
public void checkParameters(ProceedingJoinPoint joinPoint, ApplicableParameterCallback<T> callback) throws Throwable {
|
||||
public Object checkParameters(ProceedingJoinPoint joinPoint, ApplicableParameterCallback<T> callback) throws Throwable {
|
||||
MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = methodSig.getMethod();
|
||||
T methodAnnotation = method.getAnnotation(this.getAnnotationClass());
|
||||
@ -26,12 +26,12 @@ public abstract class MethodOrParameterAspect<T extends Annotation> {
|
||||
if (annotation != null) {
|
||||
if (!callback.checkParameter(joinPoint, method, annotation, p)) {
|
||||
this.logger.debug("The parameter '{}' condition is false; skipping method: {}", method.getParameters()[p].getName(), method);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
joinPoint.proceed();
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,14 +23,12 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.AspectConstrainable;
|
||||
import com.inteligr8.alfresco.annotations.IfAspect;
|
||||
import com.inteligr8.alfresco.annotations.NodeAspectConstrainable;
|
||||
import com.inteligr8.alfresco.annotations.IfNodeHasAspect;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
||||
public class NodeAspectAspect extends QNameBasedAspect<IfNodeHasAspect> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@ -40,7 +38,7 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
||||
@Autowired
|
||||
private NodeService nodeService;
|
||||
|
||||
@Value("${inteligr8.cache.aspectConstrainable.maxBeans}")
|
||||
@Value("${inteligr8.cache.nodeAspectConstrainable.maxBeans}")
|
||||
private int maxBeans;
|
||||
|
||||
@Override
|
||||
@ -49,43 +47,49 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<IfAspect> getAnnotationClass() {
|
||||
return IfAspect.class;
|
||||
public Class<IfNodeHasAspect> getAnnotationClass() {
|
||||
return IfNodeHasAspect.class;
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfAspect)")
|
||||
public void isAspectMethod() {
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeHasAspect) && execution(* *(..))")
|
||||
public void isIfAspectAnnotated() {
|
||||
}
|
||||
|
||||
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfNodeHasAspect (*), ..))")
|
||||
public void isIfAspectParamAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isAspectMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfAspect (*), ..))")
|
||||
public void isAspect(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.checkParameters(joinPoint, new ApplicableParameterCallback<IfAspect>() {
|
||||
@Around("isIfAspectAnnotated() || isIfAspectParamAnnotated()")
|
||||
public Object isNodeAspect(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.logger.trace("isNodeAspect({})", joinPoint);
|
||||
|
||||
return this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeHasAspect>() {
|
||||
@Override
|
||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfAspect annotation, int parameterIndex) {
|
||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfNodeHasAspect annotation, int parameterIndex) {
|
||||
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
||||
if (nodeRefs == null)
|
||||
return true;
|
||||
|
||||
QNameBasedCallback<IfAspect> callback = new QNameBasedCallback<IfAspect>() {
|
||||
QNameBasedCallback<IfNodeHasAspect> callback = new QNameBasedCallback<IfNodeHasAspect>() {
|
||||
@Override
|
||||
public boolean isConstrained() {
|
||||
return joinPoint.getThis() instanceof AspectConstrainable;
|
||||
return joinPoint.getThis() instanceof NodeAspectConstrainable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstrainableClassSimpleName() {
|
||||
return AspectConstrainable.class.getSimpleName();
|
||||
return NodeAspectConstrainable.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBeanName() {
|
||||
return ((AspectConstrainable) joinPoint.getThis()).getBeanName();
|
||||
return ((NodeAspectConstrainable) joinPoint.getThis()).getBeanName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends QNamePattern> constrainedQNames() {
|
||||
return ((AspectConstrainable) joinPoint.getThis()).constrainedAspects();
|
||||
return ((NodeAspectConstrainable) joinPoint.getThis()).constrainedAspects();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -103,7 +107,7 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnnotationValue(IfAspect annotation) {
|
||||
public String getAnnotationValue(IfNodeHasAspect annotation) {
|
||||
return annotation.aspect();
|
||||
}
|
||||
};
|
||||
@ -134,8 +138,19 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
||||
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
||||
} else if (obj instanceof Collection<?>) {
|
||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||
for (Object o : ((Collection<?>) obj))
|
||||
nodeRefs.addAll(this.extractNodeRefs(o));
|
||||
for (Object o : ((Collection<?>) obj)) {
|
||||
Collection<NodeRef> subNodeRefs = this.extractNodeRefs(o);
|
||||
if (subNodeRefs != null)
|
||||
nodeRefs.addAll(subNodeRefs);
|
||||
}
|
||||
return nodeRefs;
|
||||
} else if (obj instanceof Object[]) {
|
||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||
for (Object o : ((Object[]) obj)) {
|
||||
Collection<NodeRef> subNodeRefs = this.extractNodeRefs(o);
|
||||
if (subNodeRefs != null)
|
||||
nodeRefs.addAll(subNodeRefs);
|
||||
}
|
||||
return nodeRefs;
|
||||
} else {
|
||||
return null;
|
@ -23,14 +23,12 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.IfNodeType;
|
||||
import com.inteligr8.alfresco.annotations.IfNodeOfType;
|
||||
import com.inteligr8.alfresco.annotations.NodeTypeConstrainable;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
||||
public class NodeTypeAspect extends QNameBasedAspect<IfNodeOfType> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@ -49,28 +47,34 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<IfNodeType> getAnnotationClass() {
|
||||
return IfNodeType.class;
|
||||
public Class<IfNodeOfType> getAnnotationClass() {
|
||||
return IfNodeOfType.class;
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeType)")
|
||||
public void isNodeTypeMethod() {
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeOfType) && execution(* *(..))")
|
||||
public void isIfNodeTypeAnnotated() {
|
||||
}
|
||||
|
||||
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfNodeOfType (*), ..))")
|
||||
public void isIfNodeTypeParamAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isNodeTypeMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfNodeType (*), ..))")
|
||||
public void isNodeType(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeType>() {
|
||||
@Around("isIfNodeTypeAnnotated() || isIfNodeTypeParamAnnotated()")
|
||||
public Object isNodeType(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.logger.trace("isNodeType({})", joinPoint);
|
||||
|
||||
return this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeOfType>() {
|
||||
@Override
|
||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfNodeType annotation, int parameterIndex) {
|
||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfNodeOfType annotation, int parameterIndex) {
|
||||
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
||||
if (nodeRefs == null)
|
||||
return true;
|
||||
|
||||
QNameBasedCallback<IfNodeType> callback = new QNameBasedCallback<IfNodeType>() {
|
||||
QNameBasedCallback<IfNodeOfType> callback = new QNameBasedCallback<IfNodeOfType>() {
|
||||
@Override
|
||||
public boolean isConstrained() {
|
||||
return joinPoint.getThis() instanceof NodeTypeConstrainable;
|
||||
return joinPoint.getTarget() instanceof NodeTypeConstrainable;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -80,12 +84,12 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
||||
|
||||
@Override
|
||||
public String getBeanName() {
|
||||
return ((NodeTypeConstrainable) joinPoint.getThis()).getBeanName();
|
||||
return ((NodeTypeConstrainable) joinPoint.getTarget()).getBeanName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends QNamePattern> constrainedQNames() {
|
||||
return ((NodeTypeConstrainable) joinPoint.getThis()).constrainedNodeTypes();
|
||||
return ((NodeTypeConstrainable) joinPoint.getTarget()).constrainedNodeTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -103,7 +107,7 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnnotationValue(IfNodeType annotation) {
|
||||
public String getAnnotationValue(IfNodeOfType annotation) {
|
||||
return annotation.type();
|
||||
}
|
||||
};
|
||||
@ -134,8 +138,19 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
||||
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
||||
} else if (obj instanceof Collection<?>) {
|
||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||
for (Object o : ((Collection<?>) obj))
|
||||
nodeRefs.addAll(this.extractNodeRefs(o));
|
||||
for (Object o : ((Collection<?>) obj)) {
|
||||
Collection<NodeRef> subNodeRefs = this.extractNodeRefs(o);
|
||||
if (subNodeRefs != null)
|
||||
nodeRefs.addAll(subNodeRefs);
|
||||
}
|
||||
return nodeRefs;
|
||||
} else if (obj instanceof Object[]) {
|
||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||
for (Object o : ((Object[]) obj)) {
|
||||
Collection<NodeRef> subNodeRefs = this.extractNodeRefs(o);
|
||||
if (subNodeRefs != null)
|
||||
nodeRefs.addAll(subNodeRefs);
|
||||
}
|
||||
return nodeRefs;
|
||||
} else {
|
||||
return null;
|
||||
|
@ -0,0 +1,42 @@
|
||||
package com.inteligr8.alfresco.annotations.aspect;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
@Aspect
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 64)
|
||||
public class NotNullAspect {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Pointcut("execution(* *(@javax.annotation.Nonnull (*), ..))")
|
||||
public void isNonnullAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isNonnullAnnotated()")
|
||||
public Object isNotNull(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = methodSig.getMethod();
|
||||
|
||||
for (int p = 0; p < method.getParameterCount(); p++) {
|
||||
if (joinPoint.getArgs()[p] == null && method.getParameters()[p].isAnnotationPresent(Nonnull.class)) {
|
||||
this.logger.debug("A @Nonnull parameter is `null`; skipping method: {}", method);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
|
||||
}
|
@ -18,12 +18,10 @@ import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.IfNodeExists;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@ -36,19 +34,25 @@ public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
||||
return IfNodeExists.class;
|
||||
}
|
||||
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeExists)")
|
||||
public void isNodeOperableMethod() {
|
||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeExists) && execution(* *(..))")
|
||||
public void isIfNodeExistsAnnotated() {
|
||||
}
|
||||
|
||||
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfNodeExists (*), ..))")
|
||||
public void isIfNodeExistsParamAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isNodeOperableMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfNodeExists (*), ..))")
|
||||
public void isNodeOperable(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeExists>() {
|
||||
@Around("isIfNodeExistsAnnotated() || isIfNodeExistsParamAnnotated()")
|
||||
public Object isNodeOperable(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
return this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeExists>() {
|
||||
@Override
|
||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfNodeExists annotation, int parameterIndex) {
|
||||
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
||||
if (nodeRefs == null)
|
||||
return true;
|
||||
|
||||
logger.trace("Checking if nodes are operable: {}", nodeRefs);
|
||||
|
||||
for (NodeRef nodeRef : nodeRefs) {
|
||||
if (!isOperableNode(nodeRef)) {
|
||||
@ -74,8 +78,19 @@ public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
||||
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
||||
} else if (obj instanceof Collection<?>) {
|
||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||
for (Object o : ((Collection<?>) obj))
|
||||
nodeRefs.addAll(this.extractNodeRefs(o));
|
||||
for (Object o : ((Collection<?>) obj)) {
|
||||
Collection<NodeRef> subNodeRefs = this.extractNodeRefs(o);
|
||||
if (subNodeRefs != null)
|
||||
nodeRefs.addAll(subNodeRefs);
|
||||
}
|
||||
return nodeRefs;
|
||||
} else if (obj instanceof Object[]) {
|
||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||
for (Object o : ((Object[]) obj)) {
|
||||
Collection<NodeRef> subNodeRefs = this.extractNodeRefs(o);
|
||||
if (subNodeRefs != null)
|
||||
nodeRefs.addAll(subNodeRefs);
|
||||
}
|
||||
return nodeRefs;
|
||||
} else {
|
||||
return null;
|
||||
|
@ -61,7 +61,7 @@ public abstract class QNameBasedAspect<T extends Annotation> extends MethodOrPar
|
||||
} else if (callback.getAnnotationValue(annotation).length() > 0) {
|
||||
Set<QName> qnames = this.qnameCache.get(joinPoint.getThis().getClass().getName());
|
||||
if (qnames != null) {
|
||||
this.logger.trace("Using cache of qnames for bean: {}", callback.getBeanName());
|
||||
this.logger.trace("Using cache of qnames for bean: {}", joinPoint.getThis().getClass());
|
||||
return qnames;
|
||||
}
|
||||
|
||||
|
@ -1,40 +1,52 @@
|
||||
package com.inteligr8.alfresco.annotations.aspect;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.IllegalTransactionStateException;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.inteligr8.alfresco.annotations.TransactionalRetryable;
|
||||
|
||||
@Aspect
|
||||
@Order(Ordered.LOWEST_PRECEDENCE - Short.MAX_VALUE)
|
||||
@Component
|
||||
//@Component
|
||||
public class RetryingTransactionAspect {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
|
||||
public void transactionalMethod() {
|
||||
private final Set<String> warned = new HashSet<>();
|
||||
|
||||
@Autowired
|
||||
private TransactionService txService;
|
||||
|
||||
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional) && execution(* *(..))")
|
||||
public void isTransactionalAnnotated() {
|
||||
}
|
||||
|
||||
@Around("transactionalMethod()")
|
||||
public void retryingTransactional(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.logger.trace("tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||
@Pointcut("@annotation(org.springframework.transaction.annotation.TransactionalRetryable) && execution(* *(..))")
|
||||
public void isTransactionalRetryableAnnotated() {
|
||||
}
|
||||
|
||||
@Around("isTransactionalAnnotated()")
|
||||
public Object retryingTransactional(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
this.logger.trace("retryingTransactional({})", joinPoint);
|
||||
|
||||
Method method = this.getMethod(joinPoint);
|
||||
Transactional txl = method.getAnnotation(Transactional.class);
|
||||
@ -43,10 +55,18 @@ public class RetryingTransactionAspect {
|
||||
TransactionalRetryable txtry = method.getAnnotation(TransactionalRetryable.class);
|
||||
|
||||
this.logger.debug("Changing TX context: {} => [ro: {}, new: {}]", AlfrescoTransactionSupport.getTransactionReadState(), txl.readOnly(), txl.propagation());
|
||||
this.execute(joinPoint, txl, txtry);
|
||||
return this.execute(joinPoint, txl, txtry);
|
||||
} else {
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
@Before("isTransactionalRetryableAnnotated() && !isTransactionalAnnotated()")
|
||||
public void warn(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
if (this.warned.add(joinPoint.toLongString()))
|
||||
this.logger.warn("A @TransactionalRetryable annotation was found without a @Transactional annotation; it will be ignored: {}", joinPoint);
|
||||
}
|
||||
|
||||
private Method getMethod(ProceedingJoinPoint joinPoint) {
|
||||
if (!(joinPoint.getSignature() instanceof MethodSignature))
|
||||
throw new IllegalStateException("The @Transactional or @TransactionalRetryable annotations must be on methods");
|
||||
@ -56,16 +76,18 @@ public class RetryingTransactionAspect {
|
||||
}
|
||||
|
||||
private boolean isReadStateChange(Transactional txl) {
|
||||
switch (txl.propagation()) {
|
||||
case NEVER:
|
||||
case NOT_SUPPORTED:
|
||||
case SUPPORTS:
|
||||
// do not force because of a read-state change
|
||||
return false;
|
||||
default:
|
||||
}
|
||||
|
||||
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
||||
case TXN_NONE:
|
||||
switch (txl.propagation()) {
|
||||
case NEVER:
|
||||
case NOT_SUPPORTED:
|
||||
case SUPPORTS:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
case TXN_READ_ONLY:
|
||||
return !txl.readOnly();
|
||||
case TXN_READ_WRITE:
|
||||
@ -88,10 +110,15 @@ public class RetryingTransactionAspect {
|
||||
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
||||
case TXN_NONE:
|
||||
throw new IllegalTransactionStateException("A transaction does not exist where one is mandatory");
|
||||
default:
|
||||
return false;
|
||||
case TXN_READ_ONLY:
|
||||
if (!txl.readOnly())
|
||||
throw new IllegalTransactionStateException("A read-only transaction exists where a read/write one is mandatory");
|
||||
case TXN_READ_WRITE:
|
||||
if (txl.readOnly())
|
||||
throw new IllegalTransactionStateException("A read/write transaction exists where a read-only one is mandatory");
|
||||
}
|
||||
case SUPPORTS:
|
||||
//case NOT_SUPPORTED: not supported; we would have to create another thread to simulate
|
||||
return false;
|
||||
case REQUIRED:
|
||||
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
||||
@ -103,15 +130,15 @@ public class RetryingTransactionAspect {
|
||||
case REQUIRES_NEW:
|
||||
return true;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
throw new IllegalTransactionStateException("The transactional propagation is not supported: " + txl.propagation());
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(final ProceedingJoinPoint joinPoint, Transactional txl, TransactionalRetryable txtry) throws Throwable {
|
||||
private Object execute(final ProceedingJoinPoint joinPoint, Transactional txl, TransactionalRetryable txtry) throws Throwable {
|
||||
RetryingTransactionCallback<Object> rtcallback = new RetryingTransactionCallback<Object>() {
|
||||
@Override
|
||||
public Object execute() throws Throwable {
|
||||
logger.trace("tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||
logger.debug("entering tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
@ -119,24 +146,30 @@ public class RetryingTransactionAspect {
|
||||
throw e;
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("This should never happen", t);
|
||||
} finally {
|
||||
logger.trace("leaving tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
RetryingTransactionHelper rthelper = new RetryingTransactionHelper();
|
||||
if (txtry.maxRetries() > 0)
|
||||
rthelper.setMaxRetries(txtry.maxRetries());
|
||||
if (txtry.minRetryWaitInMillis() > 0)
|
||||
rthelper.setMinRetryWaitMs(txtry.minRetryWaitInMillis());
|
||||
if (txtry.maxRetryWaitInMillis() > 0)
|
||||
rthelper.setMaxRetryWaitMs(txtry.maxRetryWaitInMillis());
|
||||
if (txtry.incRetryWaitInMillis() > 0)
|
||||
rthelper.setRetryWaitIncrementMs(txtry.incRetryWaitInMillis());
|
||||
rthelper.setTransactionService(this.txService);
|
||||
if (txtry != null) {
|
||||
if (txtry.maxRetries() > 0)
|
||||
rthelper.setMaxRetries(txtry.maxRetries());
|
||||
if (txtry.minRetryWaitInMillis() > 0)
|
||||
rthelper.setMinRetryWaitMs(txtry.minRetryWaitInMillis());
|
||||
if (txtry.maxRetryWaitInMillis() > 0)
|
||||
rthelper.setMaxRetryWaitMs(txtry.maxRetryWaitInMillis());
|
||||
if (txtry.incRetryWaitInMillis() > 0)
|
||||
rthelper.setRetryWaitIncrementMs(txtry.incRetryWaitInMillis());
|
||||
}
|
||||
if (txl.timeout() > 0)
|
||||
rthelper.setMaxExecutionMs(txl.timeout() * 1000L);
|
||||
|
||||
try {
|
||||
rthelper.doInTransaction(rtcallback, txl.readOnly(), txl.propagation().equals(Propagation.REQUIRES_NEW));
|
||||
this.logger.trace("source tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||
return rthelper.doInTransaction(rtcallback, txl.readOnly(), true);
|
||||
} catch (RuntimeException re) {
|
||||
// attempt to unwrap the exception
|
||||
if (re.getMessage() == null) {
|
||||
@ -148,6 +181,8 @@ public class RetryingTransactionAspect {
|
||||
} else {
|
||||
throw re;
|
||||
}
|
||||
} finally {
|
||||
this.logger.debug("returned to tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import javax.transaction.TransactionManager;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.dictionary.M2Model;
|
||||
import org.alfresco.repo.search.transaction.SimpleTransactionManager;
|
||||
import org.alfresco.repo.version.common.VersionImpl;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
@ -126,9 +127,6 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic
|
||||
@Autowired
|
||||
protected TransactionService txService;
|
||||
|
||||
@Autowired
|
||||
protected TransactionManager txManager;
|
||||
|
||||
private XaPooledConnectionFactory factory;
|
||||
|
||||
private SimpleCache<Pair<Class<?>, String>, Method> methodCache;
|
||||
@ -150,7 +148,7 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic
|
||||
XaPooledConnectionFactory pool = new XaPooledConnectionFactory();
|
||||
pool.setConnectionFactory(factory);
|
||||
pool.setMaxConnections(this.maxConnections);
|
||||
pool.setTransactionManager(this.txManager);
|
||||
pool.setTransactionManager(SimpleTransactionManager.getInstance());
|
||||
pool.start();
|
||||
|
||||
this.factory = pool;
|
||||
@ -174,7 +172,8 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
this.factory.stop();
|
||||
if (this.factory != null)
|
||||
this.factory.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
14
src/main/resources/META-INF/aop.xml
Normal file
14
src/main/resources/META-INF/aop.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<aspectj>
|
||||
<aspects>
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.NotNullAspect" />
|
||||
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.AsyncAspect" />
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.AuthorizedAspect" />
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.RetryingTransactionAspect" />
|
||||
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.OperableNodeAspect" />
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.NodeTypeAspect" />
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.NodeAspectAspect" />
|
||||
<aspect name="com.inteligr8.alfresco.annotations.aspect.ChildIsPrimaryAspect" />
|
||||
</aspects>
|
||||
</aspectj>
|
@ -1,4 +1,6 @@
|
||||
|
||||
inteligr8.annotations.aspectj.scanPackages=com.inteligr8.alfresco.annotations
|
||||
|
||||
inteligr8.async.mq.enabled=false
|
||||
inteligr8.async.mq.url=${messaging.broker.url}
|
||||
inteligr8.async.mq.username=${messaging.broker.username}
|
||||
@ -7,4 +9,5 @@ inteligr8.async.mq.queuePrefix=inteligr8.acs.
|
||||
inteligr8.async.mq.clientId=acs
|
||||
inteligr8.async.mq.pool.max=5
|
||||
|
||||
inteligr8.cache.nodeTypeConstrainable.maxBeans=32
|
||||
inteligr8.cache.nodeTypeConstrainable.maxBeans=16
|
||||
inteligr8.cache.nodeAspectConstrainable.maxBeans=16
|
||||
|
@ -4,7 +4,9 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<!-- Enable Spring annotation scanning for classes in package -->
|
||||
|
@ -0,0 +1,52 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class AuthorizableTest extends AbstractLifecycleBean implements Authorizable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
Assert.isNull(AuthenticationUtil.getRunAsUser(), "An unexpected authorization: " + AuthenticationUtil.getRunAsUser());
|
||||
this.tryAuthorized();
|
||||
this.tryAuthorizedAsSystem();
|
||||
this.tryDoubleAuthorized();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String authorizeAsUser() {
|
||||
return "admin";
|
||||
}
|
||||
|
||||
@Authorized
|
||||
private void tryAuthorized() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue("admin".equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: admin != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@AuthorizedAsSystem
|
||||
private void tryAuthorizedAsSystem() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + AuthenticationUtil.getSystemUserName() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@Authorized
|
||||
private void tryDoubleAuthorized() {
|
||||
this.tryAuthorizedAsSystem();
|
||||
Assert.isTrue("admin".equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: admin != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class AuthorizedTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
Assert.isNull(AuthenticationUtil.getRunAsUser(), "An unexpected authorization: " + AuthenticationUtil.getRunAsUser());
|
||||
this.tryAuthorized();
|
||||
this.tryAdminAuthorized();
|
||||
this.tryAuthorizedAsSystem();
|
||||
this.tryDoubleAuthorized();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Authorized
|
||||
private void tryAuthorized() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + AuthenticationUtil.getSystemUserName() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@Authorized("admin")
|
||||
private void tryAdminAuthorized() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue("admin".equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: admin != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@AuthorizedAsSystem
|
||||
private void tryAuthorizedAsSystem() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + AuthenticationUtil.getSystemUserName() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@Authorized("admin")
|
||||
private void tryDoubleAuthorized() {
|
||||
this.tryAuthorizedAsSystem();
|
||||
Assert.isTrue("admin".equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: admin != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
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.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class IfChildAssocIsPrimaryTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
NodeRef mockNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, UUID.randomUUID().toString());
|
||||
QName mockName = QName.createQNameWithValidLocalName(NamespaceService.ALFRESCO_URI, "test");
|
||||
ChildAssociationRef mockPrimaryAssoc = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, mockNodeRef, mockName, mockNodeRef, true, 0);
|
||||
ChildAssociationRef mockSecondaryAssoc = new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, mockNodeRef, mockName, mockNodeRef, false, 0);
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryMethodNoParam();
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryMethodNoMatchingParam("test");
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.tryMethodWithOnePrimaryParam(mockPrimaryAssoc);
|
||||
this.tryMethodWithOneNullParam(null);
|
||||
this.tryMethodWithOneNonPrimaryParam(mockSecondaryAssoc);
|
||||
|
||||
this.tryMethodWithTwoPrimaryParams(mockPrimaryAssoc, "test", mockPrimaryAssoc);
|
||||
this.tryMethodWithTwoNullPrimaryParams(null, "test", mockPrimaryAssoc);
|
||||
this.tryMethodWithTwoNullPrimaryParams(mockPrimaryAssoc, "test", null);
|
||||
this.tryMethodWithTwoMixedParams(mockPrimaryAssoc, "test", mockSecondaryAssoc);
|
||||
this.tryMethodWithTwoMixedParams(mockSecondaryAssoc, "test", mockSecondaryAssoc);
|
||||
|
||||
this.tryParamWithPrimaryParam(mockPrimaryAssoc, mockPrimaryAssoc);
|
||||
this.tryParamWithPrimaryParam(mockPrimaryAssoc, mockSecondaryAssoc);
|
||||
this.tryParamWithPrimaryParam(mockSecondaryAssoc, mockPrimaryAssoc);
|
||||
this.tryParamWithNullParam(null, mockPrimaryAssoc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodNoParam() {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodNoMatchingParam(String test) {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodWithOnePrimaryParam(ChildAssociationRef childAssocRef) {
|
||||
Assert.isTrue(childAssocRef.isPrimary(), "Unexpected non-primary child association");
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodWithOneNullParam(ChildAssociationRef childAssocRef) {
|
||||
Assert.isTrue(childAssocRef == null, "Unexpected child association");
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodWithOneNonPrimaryParam(ChildAssociationRef childAssocRef) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodWithTwoPrimaryParams(ChildAssociationRef childAssocRef1, String test, ChildAssociationRef childAssocRef2) {
|
||||
Assert.isTrue(childAssocRef1.isPrimary() && childAssocRef2.isPrimary(), "Unexpected non-primary child association");
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodWithTwoNullPrimaryParams(ChildAssociationRef childAssocRef1, String test, ChildAssociationRef childAssocRef2) {
|
||||
Assert.isTrue(childAssocRef1 == null || childAssocRef1.isPrimary(), "Unexpected non-primary child association");
|
||||
Assert.isTrue(childAssocRef2 == null || childAssocRef2.isPrimary(), "Unexpected non-primary child association");
|
||||
}
|
||||
|
||||
@IfChildAssociationIsPrimary
|
||||
private void tryMethodWithTwoMixedParams(ChildAssociationRef childAssocRef1, String test, ChildAssociationRef childAssocRef2) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void tryParamWithPrimaryParam(@IfChildAssociationIsPrimary ChildAssociationRef childAssocRef1, ChildAssociationRef childAssocRef2) {
|
||||
Assert.isTrue(childAssocRef1.isPrimary(), "Unexpected non-primary child association");
|
||||
}
|
||||
|
||||
private void tryParamWithNullParam(@IfChildAssociationIsPrimary ChildAssociationRef childAssocRef1, ChildAssociationRef childAssocRef2) {
|
||||
Assert.isTrue(childAssocRef1 == null, "Unexpected child association");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.nodelocator.CompanyHomeNodeLocator;
|
||||
import org.alfresco.repo.nodelocator.NodeLocatorService;
|
||||
import org.alfresco.repo.nodelocator.SharedHomeNodeLocator;
|
||||
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.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class IfNodeAspectConstrainableTest extends AbstractLifecycleBean implements NodeAspectConstrainable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
@Autowired
|
||||
private NodeService nodeService;
|
||||
|
||||
@Autowired
|
||||
private NodeLocatorService nodeLocatorService;
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
private String beanName;
|
||||
|
||||
@AuthorizedAsSystem
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
NodeRef rootNodeRef = this.nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
NodeRef chNodeRef = this.nodeLocatorService.getNode(CompanyHomeNodeLocator.NAME, null, null);
|
||||
NodeRef sharedNodeRef = this.nodeLocatorService.getNode(SharedHomeNodeLocator.NAME, null, null);
|
||||
|
||||
this.tryNodes(chNodeRef, sharedNodeRef);
|
||||
this.tryNode(sharedNodeRef);
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryNull(null);
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalStateException();
|
||||
|
||||
this.tryNotNode(rootNodeRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBeanName() {
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceService getNamespaceService() {
|
||||
return this.namespaceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends QNamePattern> constrainedAspects() {
|
||||
return Arrays.asList(ContentModel.ASPECT_AUDITABLE);
|
||||
}
|
||||
|
||||
@IfNodeHasAspect
|
||||
private void tryNodes(NodeRef... nodeRefs) {
|
||||
for (NodeRef nodeRef : nodeRefs) {
|
||||
Assert.isTrue(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE), "Missing 'cm:auditable' aspect: " + nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryNode(@IfNodeHasAspect NodeRef nodeRef) {
|
||||
Assert.isTrue(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE), "Missing 'cm:auditable' aspect: " + nodeRef);
|
||||
}
|
||||
|
||||
@IfNodeHasAspect
|
||||
private void tryNotNodes(NodeRef... nodeRefs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@IfNodeHasAspect
|
||||
private void tryNull(NodeRef nodeRef) {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
private void tryNotNode(@IfNodeHasAspect NodeRef nodeRef) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.nodelocator.NodeLocatorService;
|
||||
import org.alfresco.repo.nodelocator.SharedHomeNodeLocator;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class IfNodeAspectTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private NodeService nodeService;
|
||||
|
||||
@Autowired
|
||||
private NodeLocatorService nodeLocatorService;
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
@AuthorizedAsSystem
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
NodeRef rootNodeRef = this.nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
NodeRef sharedNodeRef = this.nodeLocatorService.getNode(SharedHomeNodeLocator.NAME, null, null);
|
||||
ChildAssociationRef sharedParentRef = this.nodeService.getPrimaryParent(sharedNodeRef);
|
||||
|
||||
this.tryAuditables(sharedNodeRef);
|
||||
this.tryAuditable(sharedNodeRef);
|
||||
this.tryAuditable(sharedParentRef);
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryNull(null);
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalStateException();
|
||||
|
||||
this.tryNotAuditable(rootNodeRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@IfNodeHasAspect(aspect = "cm:auditable")
|
||||
private void tryAuditables(NodeRef... nodeRefs) {
|
||||
for (NodeRef nodeRef : nodeRefs) {
|
||||
Assert.isTrue(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE), "Missing 'cm:auditable' aspect: " + nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryAuditable(@IfNodeHasAspect(aspect = "cm:auditable") NodeRef nodeRef) {
|
||||
Assert.isTrue(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE), "Missing 'cm:auditable' aspect: " + nodeRef);
|
||||
}
|
||||
|
||||
private void tryAuditable(@IfNodeHasAspect(aspect = "cm:auditable") ChildAssociationRef childAssocRef) {
|
||||
NodeRef nodeRef = childAssocRef.getChildRef();
|
||||
Assert.isTrue(this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE), "Missing 'cm:auditable' aspect: " + nodeRef);
|
||||
}
|
||||
|
||||
@IfNodeHasAspect(aspect = "cm:auditable")
|
||||
private void tryNotAuditables(NodeRef... nodeRefs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@IfNodeHasAspect(aspect = "cm:auditable")
|
||||
private void tryNull(NodeRef nodeRef) {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
private void tryNotAuditable(@IfNodeOfType(type = "cm:auditable") NodeRef nodeRef) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.alfresco.repo.nodelocator.CompanyHomeNodeLocator;
|
||||
import org.alfresco.repo.nodelocator.NodeLocatorService;
|
||||
import org.alfresco.repo.nodelocator.SharedHomeNodeLocator;
|
||||
import org.alfresco.repo.nodelocator.SitesHomeNodeLocator;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class IfNodeExistsTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private NodeService nodeService;
|
||||
|
||||
@Autowired
|
||||
private NodeLocatorService nodeLocatorService;
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
@AuthorizedAsSystem
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
NodeRef mockNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, UUID.randomUUID().toString());
|
||||
NodeRef rootNodeRef = this.nodeLocatorService.getNode(CompanyHomeNodeLocator.NAME, null, null);
|
||||
NodeRef sharedNodeRef = this.nodeLocatorService.getNode(SharedHomeNodeLocator.NAME, null, null);
|
||||
NodeRef sitesNodeRef = this.nodeLocatorService.getNode(SitesHomeNodeLocator.NAME, null, null);
|
||||
|
||||
this.tryNodesExist(rootNodeRef, sharedNodeRef, sitesNodeRef);
|
||||
this.tryNodeExists(sharedNodeRef);
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryNull(null);
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalStateException();
|
||||
|
||||
this.tryNodesNotExist(mockNodeRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@IfNodeExists
|
||||
private void tryNodesExist(NodeRef... nodeRefs) {
|
||||
for (NodeRef nodeRef : nodeRefs) {
|
||||
Assert.isTrue(nodeRef != null, "Expected node reference: " + nodeRef);
|
||||
Assert.isTrue(this.nodeService.exists(nodeRef) && !this.nodeService.getNodeStatus(nodeRef).isDeleted(), "Expected node: " + nodeRef);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryNodeExists(@IfNodeExists NodeRef nodeRef) {
|
||||
Assert.isTrue(nodeRef != null, "Expected node reference: " + nodeRef);
|
||||
Assert.isTrue(this.nodeService.exists(nodeRef) && !this.nodeService.getNodeStatus(nodeRef).isDeleted(), "Expected node: " + nodeRef);
|
||||
}
|
||||
|
||||
@IfNodeExists
|
||||
private void tryNull(NodeRef nodeRef) {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
@IfNodeExists
|
||||
private void tryNodesNotExist(NodeRef... nodeRefs) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.nodelocator.CompanyHomeNodeLocator;
|
||||
import org.alfresco.repo.nodelocator.NodeLocatorService;
|
||||
import org.alfresco.repo.nodelocator.SharedHomeNodeLocator;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
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.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class IfNodeTypeConstrainableTest extends AbstractLifecycleBean implements NodeTypeConstrainable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
@Autowired
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
@Autowired
|
||||
private NodeService nodeService;
|
||||
|
||||
@Autowired
|
||||
private NodeLocatorService nodeLocatorService;
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
private String beanName;
|
||||
|
||||
@AuthorizedAsSystem
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
NodeRef rootNodeRef = this.nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
NodeRef chNodeRef = this.nodeLocatorService.getNode(CompanyHomeNodeLocator.NAME, null, null);
|
||||
NodeRef sharedNodeRef = this.nodeLocatorService.getNode(SharedHomeNodeLocator.NAME, null, null);
|
||||
|
||||
this.tryNodes(chNodeRef, sharedNodeRef);
|
||||
this.tryNode(sharedNodeRef);
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryNull(null);
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalStateException();
|
||||
|
||||
this.tryNotNode(rootNodeRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBeanName() {
|
||||
return this.beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceService getNamespaceService() {
|
||||
return this.namespaceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends QNamePattern> constrainedNodeTypes() {
|
||||
return Arrays.asList(ContentModel.TYPE_FOLDER);
|
||||
}
|
||||
|
||||
@IfNodeOfType
|
||||
private void tryNodes(NodeRef... nodeRefs) {
|
||||
for (NodeRef nodeRef : nodeRefs) {
|
||||
QName nodeType = this.nodeService.getType(nodeRef);
|
||||
Assert.isTrue(this.dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER), "Unexpected node type: " + nodeType);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryNode(@IfNodeOfType NodeRef nodeRef) {
|
||||
QName nodeType = this.nodeService.getType(nodeRef);
|
||||
Assert.isTrue(this.dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER), "Unexpected node type: " + nodeType);
|
||||
}
|
||||
|
||||
@IfNodeOfType
|
||||
private void tryNotNodes(NodeRef... nodeRefs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@IfNodeOfType
|
||||
private void tryNull(NodeRef nodeRef) {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
private void tryNotNode(@IfNodeOfType NodeRef nodeRef) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.nodelocator.CompanyHomeNodeLocator;
|
||||
import org.alfresco.repo.nodelocator.NodeLocatorService;
|
||||
import org.alfresco.repo.nodelocator.SharedHomeNodeLocator;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
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.namespace.QName;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class IfNodeTypeTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
@Autowired
|
||||
private NodeService nodeService;
|
||||
|
||||
@Autowired
|
||||
private NodeLocatorService nodeLocatorService;
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
@AuthorizedAsSystem
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
NodeRef rootNodeRef = this.nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
NodeRef chNodeRef = this.nodeLocatorService.getNode(CompanyHomeNodeLocator.NAME, null, null);
|
||||
NodeRef sharedNodeRef = this.nodeLocatorService.getNode(SharedHomeNodeLocator.NAME, null, null);
|
||||
ChildAssociationRef sharedParentRef = this.nodeService.getPrimaryParent(sharedNodeRef);
|
||||
|
||||
this.tryFolders(chNodeRef, sharedNodeRef);
|
||||
this.tryFolder(sharedNodeRef);
|
||||
this.tryFolder(sharedParentRef);
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryNull(null);
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalStateException();
|
||||
|
||||
this.tryNotFolder(rootNodeRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@IfNodeOfType(type = "cm:folder")
|
||||
private void tryFolders(NodeRef... nodeRefs) {
|
||||
for (NodeRef nodeRef : nodeRefs) {
|
||||
QName nodeType = this.nodeService.getType(nodeRef);
|
||||
Assert.isTrue(this.dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER), "Unexpected node type: " + nodeType);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryFolder(@IfNodeOfType(type = "cm:folder") NodeRef nodeRef) {
|
||||
QName nodeType = this.nodeService.getType(nodeRef);
|
||||
Assert.isTrue(this.dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER), "Unexpected node type: " + nodeType);
|
||||
}
|
||||
|
||||
private void tryFolder(@IfNodeOfType(type = "cm:folder") ChildAssociationRef childAssocRef) {
|
||||
QName nodeType = this.nodeService.getType(childAssocRef.getChildRef());
|
||||
Assert.isTrue(this.dictionaryService.isSubClass(nodeType, ContentModel.TYPE_FOLDER), "Unexpected node type: " + nodeType);
|
||||
}
|
||||
|
||||
@IfNodeOfType(type = "cm:folder")
|
||||
private void tryNotFolders(NodeRef... nodeRefs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@IfNodeOfType
|
||||
private void tryNull(NodeRef nodeRef) {
|
||||
this.executed.setTrue();
|
||||
}
|
||||
|
||||
private void tryNotFolder(@IfNodeOfType(type = "cm:folder") NodeRef nodeRef) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class IfNotNullTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final MutableBoolean executed = new MutableBoolean();
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
|
||||
this.executed.setFalse();
|
||||
this.tryNotNull("test");
|
||||
if (this.executed.isFalse())
|
||||
throw new IllegalStateException();
|
||||
|
||||
this.tryNull(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
private void tryNotNull(@Nonnull String str) {
|
||||
executed.setTrue();
|
||||
}
|
||||
|
||||
private void tryNull(@Nonnull String str) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class InvalidAuthorizableTest extends AbstractLifecycleBean implements Authorizable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
Assert.isNull(AuthenticationUtil.getRunAsUser(), "An unexpected authorization: " + AuthenticationUtil.getRunAsUser());
|
||||
|
||||
this.tryAuthorized();
|
||||
this.tryAuthorizedAsSystem();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String authorizeAsUser() {
|
||||
return "!@#lkjw 1432";
|
||||
}
|
||||
|
||||
@Authorized
|
||||
private void tryAuthorized() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(this.authorizeAsUser().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + this.authorizeAsUser() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@AuthorizedAsSystem
|
||||
private void tryAuthorizedAsSystem() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + AuthenticationUtil.getSystemUserName() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class NoExistAuthorizableTest extends AbstractLifecycleBean implements Authorizable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
Assert.isNull(AuthenticationUtil.getRunAsUser(), "An unexpected authorization: " + AuthenticationUtil.getRunAsUser());
|
||||
|
||||
this.tryAuthorized();
|
||||
this.tryAuthorizedAsSystem();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String authorizeAsUser() {
|
||||
return "doesnotexist";
|
||||
}
|
||||
|
||||
@Authorized
|
||||
private void tryAuthorized() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(this.authorizeAsUser().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + this.authorizeAsUser() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
@AuthorizedAsSystem
|
||||
private void tryAuthorizedAsSystem() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + AuthenticationUtil.getSystemUserName() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class NullAuthorizableTest extends AbstractLifecycleBean implements Authorizable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
Assert.isNull(AuthenticationUtil.getRunAsUser(), "An unexpected authorization: " + AuthenticationUtil.getRunAsUser());
|
||||
|
||||
try {
|
||||
this.tryAuthorized();
|
||||
throw new IllegalStateException("An 'IllegalArgumentException' was expected");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// suppress
|
||||
}
|
||||
|
||||
this.tryAuthorizedAsSystem();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String authorizeAsUser() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Authorized
|
||||
private void tryAuthorized() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@AuthorizedAsSystem
|
||||
private void tryAuthorizedAsSystem() {
|
||||
Assert.hasText(AuthenticationUtil.getRunAsUser(), "An expected authorization");
|
||||
Assert.isTrue(AuthenticationUtil.getSystemUserName().equals(AuthenticationUtil.getRunAsUser()), "An unexpected authorization: " + AuthenticationUtil.getSystemUserName() + " != " + AuthenticationUtil.getRunAsUser());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,224 @@
|
||||
package com.inteligr8.alfresco.annotations;
|
||||
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.IllegalTransactionStateException;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Component
|
||||
public class TransactionalTest extends AbstractLifecycleBean {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event) {
|
||||
this.logger.info("Running test: " + this.getClass());
|
||||
Assert.isNull(AlfrescoTransactionSupport.getTransactionId(), "An unexpected transaction: " + AlfrescoTransactionSupport.getTransactionId());
|
||||
|
||||
this.tryOutsideTx();
|
||||
this.tryWithinTx();
|
||||
this.tryWithinReadonlyTx();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event) {
|
||||
}
|
||||
|
||||
private void tryOutsideTx() {
|
||||
this.logger.info("Running outside TX test");
|
||||
|
||||
this.tryDefaultTransactional(null, false);
|
||||
this.tryReadOnlyTransactional(null, false);
|
||||
this.tryRetryOnlyTransactional(null);
|
||||
this.trySupportsTransactional(null, false);
|
||||
this.tryRequiresNewTransactional(null, false);
|
||||
this.tryRequiredTransactional(null, false);
|
||||
this.tryNeverTransactional(null);
|
||||
|
||||
try {
|
||||
this.tryNoSupportsTransactional();
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException uoe) {
|
||||
// suppress
|
||||
}
|
||||
|
||||
try {
|
||||
this.tryMandatoryTransactional(null, false);
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException itse) {
|
||||
// suppress
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void tryWithinTx() {
|
||||
this.logger.info("Running inside read/write TX test");
|
||||
|
||||
String txId = AlfrescoTransactionSupport.getTransactionId();
|
||||
boolean readonly = false;
|
||||
|
||||
this.tryDefaultTransactional(txId, readonly);
|
||||
this.tryReadOnlyTransactional(txId, readonly);
|
||||
this.tryRetryOnlyTransactional(txId);
|
||||
this.trySupportsTransactional(txId, readonly);
|
||||
this.tryRequiresNewTransactional(txId, readonly);
|
||||
this.tryRequiredTransactional(txId, readonly);
|
||||
this.tryMandatoryTransactional(txId, readonly);
|
||||
|
||||
try {
|
||||
this.tryNoSupportsTransactional();
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException uoe) {
|
||||
// suppress
|
||||
}
|
||||
|
||||
try {
|
||||
this.tryNeverTransactional(txId);
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException itse) {
|
||||
// suppress
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
private void tryWithinReadonlyTx() {
|
||||
this.logger.info("Running inside read-only TX test");
|
||||
|
||||
String txId = AlfrescoTransactionSupport.getTransactionId();
|
||||
boolean readonly = true;
|
||||
|
||||
this.tryDefaultTransactional(txId, readonly);
|
||||
this.tryReadOnlyTransactional(txId, readonly);
|
||||
this.tryRetryOnlyTransactional(txId);
|
||||
this.trySupportsTransactional(txId, readonly);
|
||||
this.tryRequiresNewTransactional(txId, readonly);
|
||||
this.tryRequiredTransactional(txId, readonly);
|
||||
|
||||
try {
|
||||
this.tryNoSupportsTransactional();
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException uoe) {
|
||||
// suppress
|
||||
}
|
||||
|
||||
try {
|
||||
this.tryMandatoryTransactional(txId, readonly);
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException itse) {
|
||||
// suppress
|
||||
}
|
||||
|
||||
try {
|
||||
this.tryNeverTransactional(txId);
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalTransactionStateException itse) {
|
||||
// suppress
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void tryDefaultTransactional(String originTxId, boolean originReadonly) {
|
||||
Assert.hasText(AlfrescoTransactionSupport.getTransactionId(), "Expected a transaction");
|
||||
Assert.isTrue(TxnReadState.TXN_READ_WRITE.equals(AlfrescoTransactionSupport.getTransactionReadState()), "Expected a read/write transaction");
|
||||
if (originTxId != null) {
|
||||
if (originReadonly) {
|
||||
// changed from readonly to read/write; need new TX
|
||||
Assert.isTrue(!AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected a different transaction: " + AlfrescoTransactionSupport.getTransactionId() + " == " + originTxId);
|
||||
} else {
|
||||
// no changes; same TX
|
||||
Assert.isTrue(AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected the same transaction: " + AlfrescoTransactionSupport.getTransactionId() + " != " + originTxId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
private void tryReadOnlyTransactional(String originTxId, boolean originReadonly) {
|
||||
Assert.hasText(AlfrescoTransactionSupport.getTransactionId(), "Expected a transaction");
|
||||
Assert.isTrue(TxnReadState.TXN_READ_ONLY.equals(AlfrescoTransactionSupport.getTransactionReadState()), "Expected a readonly transaction");
|
||||
if (originTxId != null) {
|
||||
if (originReadonly) {
|
||||
// no changes; same TX
|
||||
Assert.isTrue(AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected the same transaction: " + AlfrescoTransactionSupport.getTransactionId() + " != " + originTxId);
|
||||
} else {
|
||||
// changed from read/write to readonly; need new TX
|
||||
Assert.isTrue(!AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected a different transaction: " + AlfrescoTransactionSupport.getTransactionId() + " == " + originTxId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.SUPPORTS)
|
||||
private void trySupportsTransactional(String originTxId, boolean originReadonly) {
|
||||
if (originTxId == null) {
|
||||
Assert.isNull(AlfrescoTransactionSupport.getTransactionId(), "Unexpected transaction");
|
||||
} else {
|
||||
Assert.hasText(AlfrescoTransactionSupport.getTransactionId(), "Expected a transaction");
|
||||
Assert.isTrue(originReadonly == TxnReadState.TXN_READ_ONLY.equals(AlfrescoTransactionSupport.getTransactionReadState()), "Expected the same read-state transaction");
|
||||
Assert.isTrue(AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected the same transaction: " + AlfrescoTransactionSupport.getTransactionId() + " != " + originTxId);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
private void tryRequiredTransactional(String originTxId, boolean originReadonly) {
|
||||
Assert.hasText(AlfrescoTransactionSupport.getTransactionId(), "Expected a transaction");
|
||||
Assert.isTrue(TxnReadState.TXN_READ_WRITE.equals(AlfrescoTransactionSupport.getTransactionReadState()), "Expected a read/write transaction");
|
||||
if (originTxId != null) {
|
||||
if (originReadonly) {
|
||||
// changed from readonly to read/write; need new TX
|
||||
Assert.isTrue(!AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected a different transaction: " + AlfrescoTransactionSupport.getTransactionId() + " == " + originTxId);
|
||||
} else {
|
||||
// no changes; same TX
|
||||
Assert.isTrue(AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected the same transaction: " + AlfrescoTransactionSupport.getTransactionId() + " != " + originTxId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
private void tryRequiresNewTransactional(String originTxId, boolean originReadonly) {
|
||||
Assert.hasText(AlfrescoTransactionSupport.getTransactionId(), "Expected a transaction");
|
||||
Assert.isTrue(TxnReadState.TXN_READ_WRITE.equals(AlfrescoTransactionSupport.getTransactionReadState()), "Expected a read/write transaction");
|
||||
if (originTxId != null)
|
||||
Assert.isTrue(!AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected a different transaction: " + AlfrescoTransactionSupport.getTransactionId() + " == " + originTxId);
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.MANDATORY)
|
||||
private void tryMandatoryTransactional(String originTxId, boolean originReadonly) {
|
||||
if (originTxId == null) {
|
||||
throw new IllegalStateException();
|
||||
} else {
|
||||
Assert.hasText(AlfrescoTransactionSupport.getTransactionId(), "Expected a transaction");
|
||||
Assert.isTrue(AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected the same transaction: " + AlfrescoTransactionSupport.getTransactionId() + " != " + originTxId);
|
||||
Assert.isTrue(originReadonly == TxnReadState.TXN_READ_ONLY.equals(AlfrescoTransactionSupport.getTransactionReadState()), "Expected the same read-state transaction");
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
private void tryNoSupportsTransactional() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.NEVER)
|
||||
private void tryNeverTransactional(String originTxId) {
|
||||
if (originTxId == null) {
|
||||
Assert.isNull(AlfrescoTransactionSupport.getTransactionId(), "Unexpected transaction");
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
@TransactionalRetryable
|
||||
private void tryRetryOnlyTransactional(String originTxId) {
|
||||
if (originTxId == null) {
|
||||
Assert.isNull(AlfrescoTransactionSupport.getTransactionId(), "An unexpected transaction");
|
||||
} else {
|
||||
Assert.isTrue(AlfrescoTransactionSupport.getTransactionId().equals(originTxId), "Expected the same transaction: " + AlfrescoTransactionSupport.getTransactionId() + " != " + originTxId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
# Module debugging
|
||||
log4j.logger.com.inteligr8.alfresco.foldering=trace
|
||||
log4j.logger.com.inteligr8.alfresco.annotations=trace
|
||||
|
||||
# WebScript debugging
|
||||
log4j.logger.org.springframework.extensions.webscripts.ScriptLogger=debug
|
||||
|
Loading…
x
Reference in New Issue
Block a user