split aspectj management; refactored
This commit is contained in:
15
pom.xml
15
pom.xml
@@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
<alfresco.sdk.version>4.2.0</alfresco.sdk.version>
|
<alfresco.sdk.version>4.2.0</alfresco.sdk.version>
|
||||||
<alfresco.platform.version>6.2.0-ga</alfresco.platform.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>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -58,6 +60,11 @@
|
|||||||
<artifactId>alfresco-repository</artifactId>
|
<artifactId>alfresco-repository</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.inteligr8.alfresco</groupId>
|
||||||
|
<artifactId>aspectj-platform-module</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -65,16 +72,16 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.repaint.maven</groupId>
|
<groupId>io.repaint.maven</groupId>
|
||||||
<artifactId>tiles-maven-plugin</artifactId>
|
<artifactId>tiles-maven-plugin</artifactId>
|
||||||
<version>2.26</version>
|
<version>2.33</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<!-- Documentation: https://bitbucket.org/inteligr8/ootbee-beedk/src/stable/beedk-acs-platform-self-rad-tile -->
|
<!-- 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 -->
|
<!-- 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 -->
|
<!-- 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>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
6
rad.sh
6
rad.sh
@@ -6,17 +6,17 @@ discoverArtifactId() {
|
|||||||
|
|
||||||
rebuild() {
|
rebuild() {
|
||||||
echo "Rebuilding project ..."
|
echo "Rebuilding project ..."
|
||||||
mvn process-classes
|
mvn process-test-classes
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
echo "Rebuilding project and starting Docker containers to support rapid application development ..."
|
echo "Rebuilding project and starting Docker containers to support rapid application development ..."
|
||||||
mvn -Drad process-classes
|
mvn -Drad process-test-classes
|
||||||
}
|
}
|
||||||
|
|
||||||
start_log() {
|
start_log() {
|
||||||
echo "Rebuilding project and starting Docker containers to support rapid application development ..."
|
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() {
|
stop() {
|
||||||
|
@@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
|||||||
ElementType.METHOD,
|
ElementType.METHOD,
|
||||||
ElementType.PARAMETER
|
ElementType.PARAMETER
|
||||||
})
|
})
|
||||||
public @interface IfAspect {
|
public @interface IfNodeHasAspect {
|
||||||
|
|
||||||
String aspect() default "";
|
String aspect() default "";
|
||||||
|
|
@@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
|||||||
ElementType.METHOD,
|
ElementType.METHOD,
|
||||||
ElementType.PARAMETER
|
ElementType.PARAMETER
|
||||||
})
|
})
|
||||||
public @interface IfNodeType {
|
public @interface IfNodeOfType {
|
||||||
|
|
||||||
String type() default "";
|
String type() default "";
|
||||||
|
|
@@ -11,7 +11,7 @@ import org.alfresco.service.namespace.QNamePattern;
|
|||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.springframework.beans.factory.BeanNameAware;
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
|
|
||||||
public interface AspectConstrainable extends BeanNameAware {
|
public interface NodeAspectConstrainable extends BeanNameAware {
|
||||||
|
|
||||||
String getBeanName();
|
String getBeanName();
|
||||||
|
|
@@ -4,15 +4,14 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
|||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.inteligr8.alfresco.annotations.service.AsyncService;
|
import com.inteligr8.alfresco.annotations.service.AsyncService;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
|
||||||
public class AsyncAspect {
|
public class AsyncAspect {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
@@ -20,18 +19,23 @@ public class AsyncAspect {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AsyncService asyncService;
|
private AsyncService asyncService;
|
||||||
|
|
||||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Asynchronous)")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Asynchronous) && execution(* *(..))")
|
||||||
public void asyncMethod() {
|
public void isAsyncAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("asyncMethod()")
|
@Around("isAsyncAnnotated()")
|
||||||
public void async(ProceedingJoinPoint joinPoint) throws Throwable {
|
public Object async(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
if (this.asyncService.isCurrentThreadAsynchronous()) {
|
if (this.asyncService.isCurrentThreadAsynchronous()) {
|
||||||
this.logger.trace("Intercepted an @Async method call while already asynchronous; executing synchronously");
|
this.logger.trace("Intercepted an @Async method call while already asynchronous; executing synchronously");
|
||||||
joinPoint.proceed();
|
return joinPoint.proceed();
|
||||||
} else {
|
} else {
|
||||||
this.logger.trace("Intercepted an @Async method call; redirecting to Async service");
|
this.logger.trace("Intercepted an @Async method call; redirecting to Async service");
|
||||||
this.asyncService.push(joinPoint);
|
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.slf4j.LoggerFactory;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
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.Authorized;
|
||||||
import com.inteligr8.alfresco.annotations.AuthorizedAsSystem;
|
import com.inteligr8.alfresco.annotations.AuthorizedAsSystem;
|
||||||
import com.inteligr8.alfresco.annotations.Authorizable;
|
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE + Short.MAX_VALUE)
|
@Order(Ordered.HIGHEST_PRECEDENCE + Short.MAX_VALUE)
|
||||||
@Component
|
|
||||||
public class AuthorizedAspect {
|
public class AuthorizedAspect {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Authorized || com.inteligr8.alfresco.annotations.AuthorizedAsSystem)")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.Authorized) && execution(* *(..))")
|
||||||
public void runAsableMethod() {
|
public void isAuthorizedAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("runAsableMethod()")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.AuthorizedAsSystem) && execution(* *(..))")
|
||||||
public void runAs(ProceedingJoinPoint joinPoint) throws Throwable {
|
public void isAuthorizedAsSystemAnnotated() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Around("isAuthorizedAnnotated() || isAuthorizedAsSystemAnnotated()")
|
||||||
|
public Object runAs(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
this.logger.trace("runAs({})", joinPoint);
|
||||||
|
|
||||||
String runAsUser = this.getRunAsUser(joinPoint);
|
String runAsUser = this.getRunAsUser(joinPoint);
|
||||||
|
|
||||||
String currentRunAsUser = AuthenticationUtil.getRunAsUser();
|
String currentRunAsUser = AuthenticationUtil.getRunAsUser();
|
||||||
if (currentRunAsUser != null && currentRunAsUser.equals(runAsUser)) {
|
if (currentRunAsUser != null && currentRunAsUser.equals(runAsUser)) {
|
||||||
this.logger.trace("The current context is already running as the specified user: {}", currentRunAsUser);
|
this.logger.trace("The current context is already running as the specified user: {}", currentRunAsUser);
|
||||||
joinPoint.proceed();
|
return joinPoint.proceed();
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug("Changing runAs context: {} => {}", currentRunAsUser, runAsUser);
|
this.logger.debug("Changing runAs context: {} => {}", currentRunAsUser, runAsUser);
|
||||||
|
return this.runAs(joinPoint, runAsUser);
|
||||||
this.runAs(joinPoint, runAsUser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,28 +57,31 @@ public class AuthorizedAspect {
|
|||||||
Method method = methodSig.getMethod();
|
Method method = methodSig.getMethod();
|
||||||
if (method.getAnnotation(AuthorizedAsSystem.class) != null) {
|
if (method.getAnnotation(AuthorizedAsSystem.class) != null) {
|
||||||
String runAs = AuthenticationUtil.getSystemUserName();
|
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;
|
return runAs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (joinPoint.getThis() instanceof Authorizable) {
|
if (joinPoint.getThis() instanceof Authorizable) {
|
||||||
String runAs = StringUtils.trimToNull(((Authorizable) joinPoint.getThis()).authorizeAsUser());
|
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;
|
return runAs;
|
||||||
}
|
}
|
||||||
|
|
||||||
Authorized runAsAnnotation = method.getAnnotation(Authorized.class);
|
Authorized runAsAnnotation = method.getAnnotation(Authorized.class);
|
||||||
String runAs = StringUtils.trimToNull(runAsAnnotation.value());
|
String runAs = StringUtils.trimToNull(runAsAnnotation.value());
|
||||||
if (runAs != null) {
|
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;
|
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();
|
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>() {
|
RunAsWork<Object> work = new RunAsWork<Object>() {
|
||||||
public Object doWork() throws Exception {
|
public Object doWork() throws Exception {
|
||||||
try {
|
try {
|
||||||
@@ -89,7 +95,7 @@ public class AuthorizedAspect {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AuthenticationUtil.runAs(work, runAsUser);
|
return AuthenticationUtil.runAs(work, runAsUser);
|
||||||
} catch (RuntimeException re) {
|
} catch (RuntimeException re) {
|
||||||
// attempt to unwrap the exception
|
// attempt to unwrap the exception
|
||||||
if (re.getMessage() != null && re.getMessage().equals("Error during run as.")) {
|
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.slf4j.LoggerFactory;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary;
|
import com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE + 100) // ordering before transaction/authorized
|
@Order(Ordered.HIGHEST_PRECEDENCE + Byte.MAX_VALUE) // ordering before transaction/authorized
|
||||||
@Component
|
|
||||||
public class ChildIsPrimaryAspect extends MethodOrParameterAspect<IfChildAssociationIsPrimary> {
|
public class ChildIsPrimaryAspect extends MethodOrParameterAspect<IfChildAssociationIsPrimary> {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
@@ -27,13 +25,19 @@ public class ChildIsPrimaryAspect extends MethodOrParameterAspect<IfChildAssocia
|
|||||||
return IfChildAssociationIsPrimary.class;
|
return IfChildAssociationIsPrimary.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary)")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary) && execution(* *(..))")
|
||||||
public void isChildAssocPrimaryMethod() {
|
public void isIfChildAssociationIsPrimaryMethodAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("isChildAssocPrimaryMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary (*), ..))")
|
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfChildAssociationIsPrimary (*), ..))")
|
||||||
public void isChildAssocPrimary(ProceedingJoinPoint joinPoint) throws Throwable {
|
public void isIfChildAssociationIsPrimaryParamAnnotated() {
|
||||||
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
|
@Override
|
||||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfChildAssociationIsPrimary annotation, int parameterIndex) {
|
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfChildAssociationIsPrimary annotation, int parameterIndex) {
|
||||||
Object arg = joinPoint.getArgs()[parameterIndex];
|
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||||
|
@@ -14,7 +14,7 @@ public abstract class MethodOrParameterAspect<T extends Annotation> {
|
|||||||
|
|
||||||
public abstract Class<T> getAnnotationClass();
|
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();
|
MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
|
||||||
Method method = methodSig.getMethod();
|
Method method = methodSig.getMethod();
|
||||||
T methodAnnotation = method.getAnnotation(this.getAnnotationClass());
|
T methodAnnotation = method.getAnnotation(this.getAnnotationClass());
|
||||||
@@ -26,12 +26,12 @@ public abstract class MethodOrParameterAspect<T extends Annotation> {
|
|||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
if (!callback.checkParameter(joinPoint, method, annotation, p)) {
|
if (!callback.checkParameter(joinPoint, method, annotation, p)) {
|
||||||
this.logger.debug("The parameter '{}' condition is false; skipping method: {}", method.getParameters()[p].getName(), method);
|
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.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.inteligr8.alfresco.annotations.AspectConstrainable;
|
import com.inteligr8.alfresco.annotations.NodeAspectConstrainable;
|
||||||
import com.inteligr8.alfresco.annotations.IfAspect;
|
import com.inteligr8.alfresco.annotations.IfNodeHasAspect;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
public class NodeAspectAspect extends QNameBasedAspect<IfNodeHasAspect> {
|
||||||
public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@@ -40,7 +38,7 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
@Value("${inteligr8.cache.aspectConstrainable.maxBeans}")
|
@Value("${inteligr8.cache.nodeAspectConstrainable.maxBeans}")
|
||||||
private int maxBeans;
|
private int maxBeans;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -49,43 +47,49 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<IfAspect> getAnnotationClass() {
|
public Class<IfNodeHasAspect> getAnnotationClass() {
|
||||||
return IfAspect.class;
|
return IfNodeHasAspect.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfAspect)")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeHasAspect) && execution(* *(..))")
|
||||||
public void isAspectMethod() {
|
public void isIfAspectAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("isAspectMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfAspect (*), ..))")
|
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfNodeHasAspect (*), ..))")
|
||||||
public void isAspect(ProceedingJoinPoint joinPoint) throws Throwable {
|
public void isIfAspectParamAnnotated() {
|
||||||
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
|
@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];
|
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||||
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
||||||
if (nodeRefs == null)
|
if (nodeRefs == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
QNameBasedCallback<IfAspect> callback = new QNameBasedCallback<IfAspect>() {
|
QNameBasedCallback<IfNodeHasAspect> callback = new QNameBasedCallback<IfNodeHasAspect>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isConstrained() {
|
public boolean isConstrained() {
|
||||||
return joinPoint.getThis() instanceof AspectConstrainable;
|
return joinPoint.getThis() instanceof NodeAspectConstrainable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getConstrainableClassSimpleName() {
|
public String getConstrainableClassSimpleName() {
|
||||||
return AspectConstrainable.class.getSimpleName();
|
return NodeAspectConstrainable.class.getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getBeanName() {
|
public String getBeanName() {
|
||||||
return ((AspectConstrainable) joinPoint.getThis()).getBeanName();
|
return ((NodeAspectConstrainable) joinPoint.getThis()).getBeanName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends QNamePattern> constrainedQNames() {
|
public Collection<? extends QNamePattern> constrainedQNames() {
|
||||||
return ((AspectConstrainable) joinPoint.getThis()).constrainedAspects();
|
return ((NodeAspectConstrainable) joinPoint.getThis()).constrainedAspects();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,7 +107,7 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAnnotationValue(IfAspect annotation) {
|
public String getAnnotationValue(IfNodeHasAspect annotation) {
|
||||||
return annotation.aspect();
|
return annotation.aspect();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -134,8 +138,19 @@ public class AspectAspect extends QNameBasedAspect<IfAspect> {
|
|||||||
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
||||||
} else if (obj instanceof Collection<?>) {
|
} else if (obj instanceof Collection<?>) {
|
||||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||||
for (Object o : ((Collection<?>) obj))
|
for (Object o : ((Collection<?>) obj)) {
|
||||||
nodeRefs.addAll(this.extractNodeRefs(o));
|
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;
|
return nodeRefs;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
@@ -23,14 +23,12 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
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;
|
import com.inteligr8.alfresco.annotations.NodeTypeConstrainable;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
public class NodeTypeAspect extends QNameBasedAspect<IfNodeOfType> {
|
||||||
public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@@ -49,28 +47,34 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<IfNodeType> getAnnotationClass() {
|
public Class<IfNodeOfType> getAnnotationClass() {
|
||||||
return IfNodeType.class;
|
return IfNodeOfType.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeType)")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeOfType) && execution(* *(..))")
|
||||||
public void isNodeTypeMethod() {
|
public void isIfNodeTypeAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("isNodeTypeMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfNodeType (*), ..))")
|
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfNodeOfType (*), ..))")
|
||||||
public void isNodeType(ProceedingJoinPoint joinPoint) throws Throwable {
|
public void isIfNodeTypeParamAnnotated() {
|
||||||
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
|
@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];
|
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||||
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
Collection<NodeRef> nodeRefs = extractNodeRefs(arg);
|
||||||
if (nodeRefs == null)
|
if (nodeRefs == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
QNameBasedCallback<IfNodeType> callback = new QNameBasedCallback<IfNodeType>() {
|
QNameBasedCallback<IfNodeOfType> callback = new QNameBasedCallback<IfNodeOfType>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isConstrained() {
|
public boolean isConstrained() {
|
||||||
return joinPoint.getThis() instanceof NodeTypeConstrainable;
|
return joinPoint.getTarget() instanceof NodeTypeConstrainable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,12 +84,12 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getBeanName() {
|
public String getBeanName() {
|
||||||
return ((NodeTypeConstrainable) joinPoint.getThis()).getBeanName();
|
return ((NodeTypeConstrainable) joinPoint.getTarget()).getBeanName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends QNamePattern> constrainedQNames() {
|
public Collection<? extends QNamePattern> constrainedQNames() {
|
||||||
return ((NodeTypeConstrainable) joinPoint.getThis()).constrainedNodeTypes();
|
return ((NodeTypeConstrainable) joinPoint.getTarget()).constrainedNodeTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -103,7 +107,7 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAnnotationValue(IfNodeType annotation) {
|
public String getAnnotationValue(IfNodeOfType annotation) {
|
||||||
return annotation.type();
|
return annotation.type();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -134,8 +138,19 @@ public class NodeTypeAspect extends QNameBasedAspect<IfNodeType> {
|
|||||||
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
||||||
} else if (obj instanceof Collection<?>) {
|
} else if (obj instanceof Collection<?>) {
|
||||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||||
for (Object o : ((Collection<?>) obj))
|
for (Object o : ((Collection<?>) obj)) {
|
||||||
nodeRefs.addAll(this.extractNodeRefs(o));
|
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;
|
return nodeRefs;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
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.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.inteligr8.alfresco.annotations.IfNodeExists;
|
import com.inteligr8.alfresco.annotations.IfNodeExists;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Component
|
|
||||||
public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
@@ -36,13 +34,17 @@ public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
|||||||
return IfNodeExists.class;
|
return IfNodeExists.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeExists)")
|
@Pointcut("@annotation(com.inteligr8.alfresco.annotations.IfNodeExists) && execution(* *(..))")
|
||||||
public void isNodeOperableMethod() {
|
public void isIfNodeExistsAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("isNodeOperableMethod() or execution(* *(@com.inteligr8.alfresco.annotations.IfNodeExists (*), ..))")
|
@Pointcut("execution(* *(@com.inteligr8.alfresco.annotations.IfNodeExists (*), ..))")
|
||||||
public void isNodeOperable(ProceedingJoinPoint joinPoint) throws Throwable {
|
public void isIfNodeExistsParamAnnotated() {
|
||||||
this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeExists>() {
|
}
|
||||||
|
|
||||||
|
@Around("isIfNodeExistsAnnotated() || isIfNodeExistsParamAnnotated()")
|
||||||
|
public Object isNodeOperable(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
return this.checkParameters(joinPoint, new ApplicableParameterCallback<IfNodeExists>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfNodeExists annotation, int parameterIndex) {
|
public boolean checkParameter(ProceedingJoinPoint joinPoint, Method method, IfNodeExists annotation, int parameterIndex) {
|
||||||
Object arg = joinPoint.getArgs()[parameterIndex];
|
Object arg = joinPoint.getArgs()[parameterIndex];
|
||||||
@@ -50,6 +52,8 @@ public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
|||||||
if (nodeRefs == null)
|
if (nodeRefs == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
logger.trace("Checking if nodes are operable: {}", nodeRefs);
|
||||||
|
|
||||||
for (NodeRef nodeRef : nodeRefs) {
|
for (NodeRef nodeRef : nodeRefs) {
|
||||||
if (!isOperableNode(nodeRef)) {
|
if (!isOperableNode(nodeRef)) {
|
||||||
logger.debug("The node '{}' does not exist; skipping method: {}", nodeRef, method);
|
logger.debug("The node '{}' does not exist; skipping method: {}", nodeRef, method);
|
||||||
@@ -74,8 +78,19 @@ public class OperableNodeAspect extends MethodOrParameterAspect<IfNodeExists> {
|
|||||||
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
return Arrays.asList(assocRef.getSourceRef(), assocRef.getTargetRef());
|
||||||
} else if (obj instanceof Collection<?>) {
|
} else if (obj instanceof Collection<?>) {
|
||||||
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
Set<NodeRef> nodeRefs = new LinkedHashSet<>();
|
||||||
for (Object o : ((Collection<?>) obj))
|
for (Object o : ((Collection<?>) obj)) {
|
||||||
nodeRefs.addAll(this.extractNodeRefs(o));
|
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;
|
return nodeRefs;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -61,7 +61,7 @@ public abstract class QNameBasedAspect<T extends Annotation> extends MethodOrPar
|
|||||||
} else if (callback.getAnnotationValue(annotation).length() > 0) {
|
} else if (callback.getAnnotationValue(annotation).length() > 0) {
|
||||||
Set<QName> qnames = this.qnameCache.get(joinPoint.getThis().getClass().getName());
|
Set<QName> qnames = this.qnameCache.get(joinPoint.getThis().getClass().getName());
|
||||||
if (qnames != null) {
|
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;
|
return qnames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,40 +1,52 @@
|
|||||||
package com.inteligr8.alfresco.annotations.aspect;
|
package com.inteligr8.alfresco.annotations.aspect;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.IllegalTransactionStateException;
|
import org.springframework.transaction.IllegalTransactionStateException;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import com.inteligr8.alfresco.annotations.TransactionalRetryable;
|
import com.inteligr8.alfresco.annotations.TransactionalRetryable;
|
||||||
|
|
||||||
@Aspect
|
@Aspect
|
||||||
@Order(Ordered.LOWEST_PRECEDENCE - Short.MAX_VALUE)
|
@Order(Ordered.LOWEST_PRECEDENCE - Short.MAX_VALUE)
|
||||||
@Component
|
//@Component
|
||||||
public class RetryingTransactionAspect {
|
public class RetryingTransactionAspect {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
|
private final Set<String> warned = new HashSet<>();
|
||||||
public void transactionalMethod() {
|
|
||||||
|
@Autowired
|
||||||
|
private TransactionService txService;
|
||||||
|
|
||||||
|
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional) && execution(* *(..))")
|
||||||
|
public void isTransactionalAnnotated() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Around("transactionalMethod()")
|
@Pointcut("@annotation(org.springframework.transaction.annotation.TransactionalRetryable) && execution(* *(..))")
|
||||||
public void retryingTransactional(ProceedingJoinPoint joinPoint) throws Throwable {
|
public void isTransactionalRetryableAnnotated() {
|
||||||
this.logger.trace("tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
}
|
||||||
|
|
||||||
|
@Around("isTransactionalAnnotated()")
|
||||||
|
public Object retryingTransactional(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
this.logger.trace("retryingTransactional({})", joinPoint);
|
||||||
|
|
||||||
Method method = this.getMethod(joinPoint);
|
Method method = this.getMethod(joinPoint);
|
||||||
Transactional txl = method.getAnnotation(Transactional.class);
|
Transactional txl = method.getAnnotation(Transactional.class);
|
||||||
@@ -43,10 +55,18 @@ public class RetryingTransactionAspect {
|
|||||||
TransactionalRetryable txtry = method.getAnnotation(TransactionalRetryable.class);
|
TransactionalRetryable txtry = method.getAnnotation(TransactionalRetryable.class);
|
||||||
|
|
||||||
this.logger.debug("Changing TX context: {} => [ro: {}, new: {}]", AlfrescoTransactionSupport.getTransactionReadState(), txl.readOnly(), txl.propagation());
|
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) {
|
private Method getMethod(ProceedingJoinPoint joinPoint) {
|
||||||
if (!(joinPoint.getSignature() instanceof MethodSignature))
|
if (!(joinPoint.getSignature() instanceof MethodSignature))
|
||||||
throw new IllegalStateException("The @Transactional or @TransactionalRetryable annotations must be on methods");
|
throw new IllegalStateException("The @Transactional or @TransactionalRetryable annotations must be on methods");
|
||||||
@@ -56,16 +76,18 @@ public class RetryingTransactionAspect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isReadStateChange(Transactional txl) {
|
private boolean isReadStateChange(Transactional txl) {
|
||||||
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
|
||||||
case TXN_NONE:
|
|
||||||
switch (txl.propagation()) {
|
switch (txl.propagation()) {
|
||||||
case NEVER:
|
case NEVER:
|
||||||
case NOT_SUPPORTED:
|
case NOT_SUPPORTED:
|
||||||
case SUPPORTS:
|
case SUPPORTS:
|
||||||
|
// do not force because of a read-state change
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
||||||
|
case TXN_NONE:
|
||||||
|
return true;
|
||||||
case TXN_READ_ONLY:
|
case TXN_READ_ONLY:
|
||||||
return !txl.readOnly();
|
return !txl.readOnly();
|
||||||
case TXN_READ_WRITE:
|
case TXN_READ_WRITE:
|
||||||
@@ -88,10 +110,15 @@ public class RetryingTransactionAspect {
|
|||||||
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
||||||
case TXN_NONE:
|
case TXN_NONE:
|
||||||
throw new IllegalTransactionStateException("A transaction does not exist where one is mandatory");
|
throw new IllegalTransactionStateException("A transaction does not exist where one is mandatory");
|
||||||
default:
|
case TXN_READ_ONLY:
|
||||||
return false;
|
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 SUPPORTS:
|
||||||
|
//case NOT_SUPPORTED: not supported; we would have to create another thread to simulate
|
||||||
return false;
|
return false;
|
||||||
case REQUIRED:
|
case REQUIRED:
|
||||||
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
switch (AlfrescoTransactionSupport.getTransactionReadState()) {
|
||||||
@@ -103,15 +130,15 @@ public class RetryingTransactionAspect {
|
|||||||
case REQUIRES_NEW:
|
case REQUIRES_NEW:
|
||||||
return true;
|
return true;
|
||||||
default:
|
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>() {
|
RetryingTransactionCallback<Object> rtcallback = new RetryingTransactionCallback<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public Object execute() throws Throwable {
|
public Object execute() throws Throwable {
|
||||||
logger.trace("tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
logger.debug("entering tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return joinPoint.proceed();
|
return joinPoint.proceed();
|
||||||
@@ -119,11 +146,15 @@ public class RetryingTransactionAspect {
|
|||||||
throw e;
|
throw e;
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
throw new RuntimeException("This should never happen", t);
|
throw new RuntimeException("This should never happen", t);
|
||||||
|
} finally {
|
||||||
|
logger.trace("leaving tx: {}", AlfrescoTransactionSupport.getTransactionId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
RetryingTransactionHelper rthelper = new RetryingTransactionHelper();
|
RetryingTransactionHelper rthelper = new RetryingTransactionHelper();
|
||||||
|
rthelper.setTransactionService(this.txService);
|
||||||
|
if (txtry != null) {
|
||||||
if (txtry.maxRetries() > 0)
|
if (txtry.maxRetries() > 0)
|
||||||
rthelper.setMaxRetries(txtry.maxRetries());
|
rthelper.setMaxRetries(txtry.maxRetries());
|
||||||
if (txtry.minRetryWaitInMillis() > 0)
|
if (txtry.minRetryWaitInMillis() > 0)
|
||||||
@@ -132,11 +163,13 @@ public class RetryingTransactionAspect {
|
|||||||
rthelper.setMaxRetryWaitMs(txtry.maxRetryWaitInMillis());
|
rthelper.setMaxRetryWaitMs(txtry.maxRetryWaitInMillis());
|
||||||
if (txtry.incRetryWaitInMillis() > 0)
|
if (txtry.incRetryWaitInMillis() > 0)
|
||||||
rthelper.setRetryWaitIncrementMs(txtry.incRetryWaitInMillis());
|
rthelper.setRetryWaitIncrementMs(txtry.incRetryWaitInMillis());
|
||||||
|
}
|
||||||
if (txl.timeout() > 0)
|
if (txl.timeout() > 0)
|
||||||
rthelper.setMaxExecutionMs(txl.timeout() * 1000L);
|
rthelper.setMaxExecutionMs(txl.timeout() * 1000L);
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (RuntimeException re) {
|
||||||
// attempt to unwrap the exception
|
// attempt to unwrap the exception
|
||||||
if (re.getMessage() == null) {
|
if (re.getMessage() == null) {
|
||||||
@@ -148,6 +181,8 @@ public class RetryingTransactionAspect {
|
|||||||
} else {
|
} else {
|
||||||
throw re;
|
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.model.ContentModel;
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.repo.dictionary.M2Model;
|
import org.alfresco.repo.dictionary.M2Model;
|
||||||
|
import org.alfresco.repo.search.transaction.SimpleTransactionManager;
|
||||||
import org.alfresco.repo.version.common.VersionImpl;
|
import org.alfresco.repo.version.common.VersionImpl;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
import org.alfresco.service.cmr.action.ActionService;
|
import org.alfresco.service.cmr.action.ActionService;
|
||||||
@@ -126,9 +127,6 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected TransactionService txService;
|
protected TransactionService txService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected TransactionManager txManager;
|
|
||||||
|
|
||||||
private XaPooledConnectionFactory factory;
|
private XaPooledConnectionFactory factory;
|
||||||
|
|
||||||
private SimpleCache<Pair<Class<?>, String>, Method> methodCache;
|
private SimpleCache<Pair<Class<?>, String>, Method> methodCache;
|
||||||
@@ -150,7 +148,7 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic
|
|||||||
XaPooledConnectionFactory pool = new XaPooledConnectionFactory();
|
XaPooledConnectionFactory pool = new XaPooledConnectionFactory();
|
||||||
pool.setConnectionFactory(factory);
|
pool.setConnectionFactory(factory);
|
||||||
pool.setMaxConnections(this.maxConnections);
|
pool.setMaxConnections(this.maxConnections);
|
||||||
pool.setTransactionManager(this.txManager);
|
pool.setTransactionManager(SimpleTransactionManager.getInstance());
|
||||||
pool.start();
|
pool.start();
|
||||||
|
|
||||||
this.factory = pool;
|
this.factory = pool;
|
||||||
@@ -174,6 +172,7 @@ public class MqAsyncService extends AbstractLifecycleBean implements AsyncServic
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onShutdown(ApplicationEvent event) {
|
protected void onShutdown(ApplicationEvent event) {
|
||||||
|
if (this.factory != null)
|
||||||
this.factory.stop();
|
this.factory.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.enabled=false
|
||||||
inteligr8.async.mq.url=${messaging.broker.url}
|
inteligr8.async.mq.url=${messaging.broker.url}
|
||||||
inteligr8.async.mq.username=${messaging.broker.username}
|
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.clientId=acs
|
||||||
inteligr8.async.mq.pool.max=5
|
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"
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:context="http://www.springframework.org/schema/context"
|
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
|
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">
|
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 -->
|
<!-- 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
|
# Module debugging
|
||||||
log4j.logger.com.inteligr8.alfresco.foldering=trace
|
log4j.logger.com.inteligr8.alfresco.annotations=trace
|
||||||
|
|
||||||
# WebScript debugging
|
# WebScript debugging
|
||||||
log4j.logger.org.springframework.extensions.webscripts.ScriptLogger=debug
|
log4j.logger.org.springframework.extensions.webscripts.ScriptLogger=debug
|
||||||
|
Reference in New Issue
Block a user