1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.mozilla.org/MPL/MPL-1.1.html 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.as2lib.core.BasicClass; 18 import org.as2lib.aop.advice.AdviceFactory; 19 import org.as2lib.env.overload.Overload; 20 import org.as2lib.app.exec.Call; 21 import org.as2lib.aop.Advice; 22 import org.as2lib.aop.Pointcut; 23 import org.as2lib.env.except.IllegalArgumentException; 24 import org.as2lib.util.ClassUtil; 25 26 /** 27 * {@code SimpleAdviceFactory} creates advices dynamically based on an advice class. 28 * 29 * @author Simon Wacker 30 */ 31 class org.as2lib.aop.advice.SimpleAdviceFactory extends BasicClass implements AdviceFactory { 32 33 /** The advice class. */ 34 private var adviceClass:Function; 35 36 /** 37 * Constructs a new {@code SimpleAdviceFactory} instance. 38 * 39 * <p>The {@code adviceClass} is suspected to have a constructor that takes two 40 * arguments. The first argument is either a pointcut pattern or a {@link Pointcut} 41 * instance and the second argument is a callback of instance {@link Call}. 42 * 43 * @param advice the advice class to return instances of 44 * @throws IllegalArgumentException if argument {@code adviceClass} is {@code null} 45 * or {@code undefined} 46 * @throws IllegalArgumentException if the passed-in {@code adviceClass} is not an 47 * implementation of the {@link Advice} interface 48 */ 49 public function SimpleAdviceFactory(adviceClass:Function) { 50 if (!adviceClass) throw new IllegalArgumentException("Argument 'adviceClass' must not be 'null' nor 'undefined'.", this, arguments); 51 if (!ClassUtil.isImplementationOf(adviceClass, Advice)) { 52 throw new IllegalArgumentException("Argument 'adviceClass' is not an implementation of interface 'Advice'.", this, arguments); 53 } 54 this.adviceClass = adviceClass; 55 } 56 57 /** 58 * @overload #getAdviceByStringAndCall 59 * @overload #getAdviceByPointcutAndCall 60 */ 61 public function getAdvice():Advice { 62 var o:Overload = new Overload(this); 63 o.addHandler([String, Call], getAdviceByStringAndCall); 64 o.addHandler([Pointcut, Call], getAdviceByPointcutAndCall); 65 return o.forward(arguments); 66 } 67 68 /** 69 * Returns an advice configured for the given {@code pointcut} string and 70 * {@code callback}. 71 * 72 * @param pointcut the string representation of a pointcut used by the returned advice 73 * @param callback the callback that is executed if you invoke the {@code execute} 74 * method on the returned advice 75 * @return an advice that is configured with the given {@code pointcut} and 76 * {@code callback} 77 */ 78 public function getAdviceByStringAndCall(pointcut:String, callback:Call):Advice { 79 return Advice(new adviceClass(pointcut, callback)); 80 } 81 82 /** 83 * Returns an advice configured for the given {@code pointcut} and {@code callback}. 84 * 85 * @param pointcut the pointcut used by the returned advice 86 * @param callback the callback that is executed if you invoke the {@code execute} 87 * method on the returned advice 88 * @return an advice that is configured with the given {@code pointcut} and 89 * {@code callback} 90 */ 91 public function getAdviceByPointcutAndCall(pointcut:Pointcut, callback:Call):Advice { 92 return Advice(new adviceClass(pointcut, callback)); 93 } 94 95 }