001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.guard; 014 015 import java.lang.reflect.Constructor; 016 import java.lang.reflect.Method; 017 018 import net.sf.oval.internal.Log; 019 import net.sf.oval.internal.util.Invocable; 020 021 import org.aspectj.lang.ProceedingJoinPoint; 022 import org.aspectj.lang.annotation.Around; 023 import org.aspectj.lang.annotation.Aspect; 024 import org.aspectj.lang.annotation.DeclareParents; 025 import org.aspectj.lang.annotation.SuppressAjWarnings; 026 import org.aspectj.lang.reflect.ConstructorSignature; 027 import org.aspectj.lang.reflect.MethodSignature; 028 029 /** 030 * This is an annotations based version of the GuardAspect aspect. 031 * 032 * In contrast to GuardAspect no custom scopes are supported yet, 033 * so only guarding based on the @Guarded annotation is possible right now. 034 * 035 * To workaround an AspectJ bug use the -XnoInline weave option, in case you are getting errors like: 036 * 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 037 * 038 * @author Sebastian Thomschke 039 */ 040 @Aspect 041 public abstract class GuardAspect2 extends ApiUsageAuditor2 042 { 043 private static final class ProceedInvocable implements Invocable 044 { 045 final ProceedingJoinPoint thisJoinPoint; 046 047 protected ProceedInvocable(final ProceedingJoinPoint thisJoinPoint) 048 { 049 this.thisJoinPoint = thisJoinPoint; 050 } 051 052 /** 053 * {@inheritDoc} 054 */ 055 public Object invoke() throws Throwable 056 { 057 return thisJoinPoint.proceed(); 058 } 059 } 060 061 private static final Log LOG = Log.getLog(GuardAspect2.class); 062 063 @SuppressWarnings("unused") 064 // add the IsGuarded marker interface to all classes annotated with @Guarded 065 @DeclareParents("(@net.sf.oval.guard.Guarded *)") 066 private IsGuarded implementedInterface; 067 068 private Guard guard; 069 070 /** 071 * Constructor instantiating a new Guard object. 072 */ 073 public GuardAspect2() 074 { 075 this(new Guard()); 076 getGuard().setParameterNameResolver(new ParameterNameResolverAspectJImpl()); 077 } 078 079 /** 080 * Constructor using the given Guard object 081 * @param guard the guard to use 082 */ 083 public GuardAspect2(final Guard guard) 084 { 085 LOG.info("Instantiated"); 086 087 setGuard(guard); 088 } 089 090 @Around("execution((@net.sf.oval.guard.Guarded *).new(..))") 091 public Object allConstructors(final ProceedingJoinPoint thisJoinPoint) throws Throwable 092 { 093 final ConstructorSignature signature = (ConstructorSignature) thisJoinPoint.getSignature(); 094 095 LOG.debug("aroundConstructor() {1}", signature); 096 097 final Constructor< ? > ctor = signature.getConstructor(); 098 final Object[] args = thisJoinPoint.getArgs(); 099 final Object target = thisJoinPoint.getTarget(); 100 101 // pre conditions 102 { 103 guard.guardConstructorPre(target, ctor, args); 104 } 105 106 final Object result = thisJoinPoint.proceed(); 107 108 // post conditions 109 { 110 guard.guardConstructorPost(target, ctor, args); 111 } 112 113 return result; 114 } 115 116 @SuppressAjWarnings("adviceDidNotMatch") 117 @Around("execution(* (@net.sf.oval.guard.Guarded *).*(..))") 118 public Object allMethods(final ProceedingJoinPoint thisJoinPoint) throws Throwable 119 { 120 final MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature(); 121 122 LOG.debug("aroundMethod() {1}", signature); 123 124 final Method method = signature.getMethod(); 125 final Object[] args = thisJoinPoint.getArgs(); 126 final Object target = thisJoinPoint.getTarget(); 127 128 return guard.guardMethod(target, method, args, new ProceedInvocable(thisJoinPoint)); 129 } 130 131 /** 132 * @return the guard 133 */ 134 public Guard getGuard() 135 { 136 return guard; 137 } 138 139 public final void setGuard(final Guard guard) 140 { 141 this.guard = guard; 142 } 143 }