View Javadoc
1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2014 Sebastian
3    * Thomschke.
4    *
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    *
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.guard;
14  
15  import java.lang.reflect.Constructor;
16  import java.lang.reflect.Method;
17  
18  import net.sf.oval.internal.Log;
19  import net.sf.oval.internal.util.Invocable;
20  
21  import org.aspectj.lang.ProceedingJoinPoint;
22  import org.aspectj.lang.annotation.Around;
23  import org.aspectj.lang.annotation.Aspect;
24  import org.aspectj.lang.annotation.DeclareParents;
25  import org.aspectj.lang.annotation.SuppressAjWarnings;
26  import org.aspectj.lang.reflect.ConstructorSignature;
27  import org.aspectj.lang.reflect.MethodSignature;
28  
29  /**
30   * This is an annotations based version of the GuardAspect aspect.
31   *
32   * In contrast to GuardAspect no custom scopes are supported yet,
33   * so only guarding based on the @Guarded annotation is possible right now.
34   *
35   * To workaround an AspectJ bug use the -XnoInline weave option, in case you are getting errors like:
36   * java.lang.VerifyError: (class: net/sf/oval/guard/GuardAspect2, method: ajc$inlineAccessMethod$net_sf_oval_guard_GuardAspect2$net_sf_oval_guard_Guard$guardMethodPost signature: (Lnet/sf/oval/guard/Guard;Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Ljava/lang/Object;)V) Illegal use of nonvirtual function call
37   *
38   * @author Sebastian Thomschke
39   */
40  @Aspect
41  public abstract class GuardAspect2 extends ApiUsageAuditor2
42  {
43  	private static final class ProceedInvocable implements Invocable
44  	{
45  		final ProceedingJoinPoint thisJoinPoint;
46  
47  		protected ProceedInvocable(final ProceedingJoinPoint thisJoinPoint)
48  		{
49  			this.thisJoinPoint = thisJoinPoint;
50  		}
51  
52  		/**
53  		 * {@inheritDoc}
54  		 */
55  		public Object invoke() throws Throwable
56  		{
57  			return thisJoinPoint.proceed();
58  		}
59  	}
60  
61  	private static final Log LOG = Log.getLog(GuardAspect2.class);
62  
63  	// add the IsGuarded marker interface to all classes annotated with @Guarded
64  	@DeclareParents("(@net.sf.oval.guard.Guarded *)")
65  	private IsGuarded implementedInterface;
66  
67  	private Guard guard;
68  
69  	/**
70  	 * Constructor instantiating a new Guard object.
71  	 */
72  	public GuardAspect2()
73  	{
74  		this(new Guard());
75  		getGuard().setParameterNameResolver(new ParameterNameResolverAspectJImpl());
76  	}
77  
78  	/**
79  	 * Constructor using the given Guard object
80  	 * @param guard the guard to use
81  	 */
82  	public GuardAspect2(final Guard guard)
83  	{
84  		LOG.info("Instantiated");
85  
86  		setGuard(guard);
87  	}
88  
89  	@Around("execution((@net.sf.oval.guard.Guarded *).new(..))")
90  	public Object allConstructors(final ProceedingJoinPoint thisJoinPoint) throws Throwable
91  	{
92  		final ConstructorSignature signature = (ConstructorSignature) thisJoinPoint.getSignature();
93  
94  		LOG.debug("aroundConstructor() {1}", signature);
95  
96  		final Constructor< ? > ctor = signature.getConstructor();
97  		final Object[] args = thisJoinPoint.getArgs();
98  		final Object target = thisJoinPoint.getTarget();
99  
100 		// pre conditions
101 		{
102 			guard.guardConstructorPre(target, ctor, args);
103 		}
104 
105 		final Object result = thisJoinPoint.proceed();
106 
107 		// post conditions
108 		{
109 			guard.guardConstructorPost(target, ctor, args);
110 		}
111 
112 		return result;
113 	}
114 
115 	@SuppressAjWarnings("adviceDidNotMatch")
116 	@Around("execution(* (@net.sf.oval.guard.Guarded *).*(..))")
117 	public Object allMethods(final ProceedingJoinPoint thisJoinPoint) throws Throwable
118 	{
119 		final MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
120 
121 		LOG.debug("aroundMethod() {1}", signature);
122 
123 		final Method method = signature.getMethod();
124 		final Object[] args = thisJoinPoint.getArgs();
125 		final Object target = thisJoinPoint.getTarget();
126 
127 		return guard.guardMethod(target, method, args, new ProceedInvocable(thisJoinPoint));
128 	}
129 
130 	/**
131 	 * @return the guard
132 	 */
133 	public Guard getGuard()
134 	{
135 		return guard;
136 	}
137 
138 	public final void setGuard(final Guard guard)
139 	{
140 		this.guard = guard;
141 	}
142 }