package alien4cloud.tosca.context; import java.lang.reflect.Method; import java.util.Set; import org.alien4cloud.tosca.model.CSARDependency; import org.alien4cloud.tosca.model.templates.Topology; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; /** * This aspect executes for ToscaContextual methods and ensure that a ToscaContext is defined (or creates one if not). */ @Slf4j @Aspect @Component public class ToscaContextualAspect { @Around("@annotation(alien4cloud.tosca.context.ToscaContextual)") public Object ensureContext(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method m = ms.getMethod(); boolean requireNew = m.getAnnotation(ToscaContextual.class).requiresNew(); boolean initContext = false; ToscaContext.Context existingContext = ToscaContext.get(); if (requireNew || existingContext == null) { initContext = true; } try { // try to find dependencies from parameters if (initContext) { Set<CSARDependency> dependencies = findDependencies(joinPoint.getArgs()); log.debug("Initializing Tosca Context with dependencies {}", dependencies); ToscaContext.init(dependencies); } return joinPoint.proceed(); } finally { if (initContext) { log.debug("Destroying Tosca Context"); ToscaContext.destroy(); } if (existingContext != null) { log.debug("Set back the existing context"); ToscaContext.set(existingContext); } } } private Set<CSARDependency> findDependencies(Object[] args) { for (Object arg : args) { if (arg instanceof Topology) { return ((Topology) arg).getDependencies(); } if (arg instanceof Set) { Set set = (Set) arg; if (set.size() > 0 && set.iterator().next() instanceof CSARDependency) { return (Set<CSARDependency>) arg; } } } return Sets.<CSARDependency> newHashSet(); } }