Java tutorial
/* * Copyright 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.amazonaws.services.simpleworkflow.flow.aspectj; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import com.amazonaws.services.simpleworkflow.flow.annotations.Asynchronous; import com.amazonaws.services.simpleworkflow.flow.annotations.NoWait; import com.amazonaws.services.simpleworkflow.flow.annotations.Wait; import com.amazonaws.services.simpleworkflow.flow.core.AndPromise; import com.amazonaws.services.simpleworkflow.flow.core.Promise; @Aspect public class AsynchronousAspect { @SuppressWarnings({ "rawtypes", "unchecked" }) @Around("call(@com.amazonaws.services.simpleworkflow.flow.annotations.Asynchronous * *(..)) && @annotation(asynchronousAnnotation)") public Object makeAsynchronous(ProceedingJoinPoint pjp, Asynchronous asynchronousAnnotation) throws Throwable { final Signature signature = pjp.getStaticPart().getSignature(); if (signature instanceof MethodSignature) { final MethodSignature methodSignature = (MethodSignature) signature; int i = 0; Object[] methodArguments = pjp.getArgs(); Annotation[][] parameterAnnotations = methodSignature.getMethod().getParameterAnnotations(); List<Promise> valueParams = new ArrayList<Promise>(); for (final Class<?> parameterType : methodSignature.getParameterTypes()) { if ((isPromise(parameterType) || isPromiseArray(parameterType) || (isCollection(parameterType) && hasWaitAnnotation(parameterAnnotations[i]))) && !hasNoWaitAnnotation(parameterAnnotations[i])) { Object param = methodArguments[i]; if (isPromise(parameterType)) { valueParams.add((Promise) param); } else if (isCollection(parameterType)) { valueParams.add(new AndPromise((Collection) param)); } else { valueParams.add(new AndPromise((Promise[]) param)); } } else { valueParams.add(null); } i++; } Promise[] values = valueParams.toArray(new Promise[0]); Boolean daemon = asynchronousAnnotation.daemon() ? true : null; AsynchronousAspectTask task = new AsynchronousAspectTask(daemon, pjp, values); return task.getReturnValue(); } return pjp.proceed(); } private static boolean isPromise(Class<?> clazz) { return Promise.class.isAssignableFrom(clazz); } private static boolean isCollection(Class<?> clazz) { return Collection.class.isAssignableFrom(clazz); } private static boolean isPromiseArray(Class<?> clazz) { if (!clazz.isArray()) { return false; } Class<?> elementType = clazz.getComponentType(); return isPromise(elementType); } private static boolean hasWaitAnnotation(Annotation[] annotations) { for (Annotation annotation : annotations) { if (annotation.annotationType().equals(Wait.class)) { return true; } } return false; } private static boolean hasNoWaitAnnotation(Annotation[] annotations) { for (Annotation annotation : annotations) { if (annotation.annotationType().equals(NoWait.class)) { return true; } } return false; } }