1
16
17 import org.as2lib.core.BasicClass;
18 import org.as2lib.util.StringUtil;
19 import org.as2lib.env.except.IllegalArgumentException;
20 import org.as2lib.data.holder.Map;
21 import org.as2lib.data.holder.map.HashMap;
22 import org.as2lib.aop.AopConfig;
23 import org.as2lib.aop.Pointcut;
24 import org.as2lib.aop.pointcut.OrPointcut;
25 import org.as2lib.aop.pointcut.AndPointcut;
26 import org.as2lib.aop.pointcut.NotPointcut;
27 import org.as2lib.aop.pointcut.KindedPointcut;
28 import org.as2lib.aop.pointcut.WithinPointcut;
29 import org.as2lib.aop.pointcut.PointcutFactory;
30 import org.as2lib.aop.pointcut.PointcutRule;
31 import org.as2lib.aop.joinpoint.AbstractJoinPoint;
32
33
56 class org.as2lib.aop.pointcut.DynamicPointcutFactory extends BasicClass implements PointcutFactory {
57
58
59 private var factoryMap:Map;
60
61
64 public function DynamicPointcutFactory(Void) {
65 factoryMap = new HashMap();
66 bindOrPointcut();
67 bindAndPointcut();
68 bindNotPointcut();
69 bindExecutionPointcut();
70 bindSetPropertyPointcut();
71 bindGetPropertyPointcut();
72 bindWithinPointcut();
73 }
74
75
80 private function getBlankPointcutRule(Void):PointcutRule {
81 var result = new Object();
82 result.__proto__ = PointcutRule["prototype"];
83 result.__constructor__ = PointcutRule;
84 return result;
85 }
86
87
92 private function getBlankPointcutFactory(Void):PointcutFactory {
93 var result = new Object();
94 result.__proto__ = PointcutFactory["prototype"];
95 result.__constructor__ = PointcutFactory;
96 return result;
97 }
98
99
102 private function bindOrPointcut(Void):Void {
103 var rule:PointcutRule = getBlankPointcutRule();
104 rule.execute = function(pattern:String):Boolean {
105 return (pattern.indexOf("||") != -1);
106 };
107 var factory:PointcutFactory = getBlankPointcutFactory();
108 factory.getPointcut = function(pattern:String):Pointcut {
109 return (new OrPointcut(pattern));
110 };
111 bindPointcutFactory(rule, factory);
112 }
113
114
117 private function bindAndPointcut(Void):Void {
118 var rule:PointcutRule = getBlankPointcutRule();
119 rule.execute = function(pattern:String):Boolean {
120 return (pattern.indexOf("&&") != -1);
121 };
122 var factory:PointcutFactory = getBlankPointcutFactory();
123 factory.getPointcut = function(pattern:String):Pointcut {
124 return (new AndPointcut(pattern));
125 };
126 bindPointcutFactory(rule, factory);
127 }
128
129
132 private function bindNotPointcut(Void):Void {
133 var rule:PointcutRule = getBlankPointcutRule();
134 rule.execute = function(pattern:String):Boolean {
135 return (pattern.indexOf("!") == 0);
136 };
137 var factory:PointcutFactory = getBlankPointcutFactory();
138 factory.getPointcut = function(pattern:String):Pointcut {
139 pattern = pattern.substring(1, pattern.length);
140 return (new NotPointcut(AopConfig.getPointcutFactory().getPointcut(pattern)));
141 };
142 bindPointcutFactory(rule, factory);
143 }
144
145
148 private function bindExecutionPointcut(Void):Void {
149 var rule:PointcutRule = getBlankPointcutRule();
150 rule.execute = function(pattern:String):Boolean {
151 return (pattern.indexOf("execution") == 0);
152 };
153 var factory:PointcutFactory = getBlankPointcutFactory();
154 factory.getPointcut = function(pattern:String):Pointcut {
155 if (pattern.indexOf("()") != -1) {
156 pattern = pattern.substring(10, pattern.length - 3);
157 } else {
158 pattern = pattern.substring(10, pattern.length - 1);
159 }
160 return (new KindedPointcut(pattern, AbstractJoinPoint.METHOD | AbstractJoinPoint.CONSTRUCTOR));
161 };
162 bindPointcutFactory(rule, factory);
163 }
164
165
168 private function bindSetPropertyPointcut(Void):Void {
169 var rule:PointcutRule = getBlankPointcutRule();
170 rule.execute = function(pattern:String):Boolean {
171 return (pattern.indexOf("set") == 0);
172 };
173 var factory:PointcutFactory = getBlankPointcutFactory();
174 factory.getPointcut = function(pattern:String):Pointcut {
175 pattern = pattern.substring(4, pattern.length - 1);
176 return (new KindedPointcut(pattern, AbstractJoinPoint.SET_PROPERTY));
177 };
178 bindPointcutFactory(rule, factory);
179 }
180
181
184 private function bindGetPropertyPointcut(Void):Void {
185 var rule:PointcutRule = getBlankPointcutRule();
186 rule.execute = function(pattern:String):Boolean {
187 return (pattern.indexOf("get") == 0);
188 };
189 var factory:PointcutFactory = getBlankPointcutFactory();
190 factory.getPointcut = function(pattern:String):Pointcut {
191 pattern = pattern.substring(4, pattern.length - 1);
192 return (new KindedPointcut(pattern, AbstractJoinPoint.GET_PROPERTY));
193 };
194 bindPointcutFactory(rule, factory);
195 }
196
197
200 private function bindWithinPointcut(Void):Void {
201 var rule:PointcutRule = getBlankPointcutRule();
202 rule.execute = function(pattern:String):Boolean {
203 return (pattern.indexOf("within") == 0);
204 };
205 var factory:PointcutFactory = getBlankPointcutFactory();
206 factory.getPointcut = function(pattern:String):Pointcut {
207 pattern = pattern.substring(7, pattern.length - 1);
208 return (new WithinPointcut(pattern));
209 };
210 bindPointcutFactory(rule, factory);
211 }
212
213
224 public function getPointcut(pattern:String):Pointcut {
225 if (!pattern) return null;
226
227 if (pattern.indexOf(" ") != -1) {
228 pattern = StringUtil.trim(pattern);
229 while (pattern.indexOf(" ") != -1) {
230 pattern = StringUtil.replace(pattern, " ", " ");
231 }
232 pattern = StringUtil.replace(pattern, "( ", "(");
233 pattern = StringUtil.replace(pattern, " )", ")");
234 pattern = StringUtil.replace(pattern, " (", "(");
235 pattern = StringUtil.replace(pattern, "! ", "!");
236 pattern = StringUtil.replace(pattern, " &&", "&&");
237 pattern = StringUtil.replace(pattern, " ||", "||");
238 pattern = StringUtil.replace(pattern, "&& ", "&&");
239 pattern = StringUtil.replace(pattern, "|| ", "||");
240 }
241 var rules:Array = factoryMap.getKeys();
242 var factories:Array = factoryMap.getValues();
243 for (var i:Number = 0; i < rules.length; i++) {
244 var rule:PointcutRule = rules[i];
245 if (rule.execute(pattern)) {
246 return PointcutFactory(factories[i]).getPointcut(pattern);
247 }
248 }
249 return null;
250 }
251
252
261 public function bindPointcutFactory(rule:PointcutRule, factory:PointcutFactory):Void {
262 if (!rule || !factory) throw new IllegalArgumentException("Neither argument 'rule' nor argument 'factory' must be {@code null} nor {@code undefined}.", this, arguments);
263 factoryMap.put(rule, factory);
264 }
265
266 }