001    /*****************************************************************************
002     * Copyright (c) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *                                                                           *
008     * Idea by Rachel Davies, Original code by various                           *
009     *****************************************************************************/
010    package org.nanocontainer.aop.dynaop;
011    
012    import dynaop.Pointcuts;
013    import org.apache.oro.text.regex.MalformedPatternException;
014    import org.nanocontainer.aop.ClassPointcut;
015    import org.nanocontainer.aop.MalformedRegularExpressionException;
016    import org.nanocontainer.aop.MethodPointcut;
017    import org.nanocontainer.aop.defaults.AbstractPointcutsFactory;
018    
019    import java.lang.reflect.Method;
020    
021    /**
022     * Implements the <code>org.nanocontainer.aop.PointcutsFactory</code>
023     * interface using dynaop.
024     *
025     * @author Stephen Molitor
026     * @version $Revision: 3144 $
027     */
028    public class DynaopPointcutsFactory extends AbstractPointcutsFactory {
029    
030        public ClassPointcut allClasses() {
031            return new DynaopClassPointcut(Pointcuts.ALL_CLASSES);
032        }
033    
034        public ClassPointcut instancesOf(Class type) {
035            return new DynaopClassPointcut(Pointcuts.instancesOf(type));
036        }
037    
038        public ClassPointcut className(String regex) {
039            try {
040                return new DynaopClassPointcut(Pointcuts.className(regex));
041            } catch (MalformedPatternException e) {
042                throw new MalformedRegularExpressionException("malformed class name regular expression", e);
043            }
044        }
045    
046        public ClassPointcut oneClass(Class clazz) {
047            return new DynaopClassPointcut(Pointcuts.singleton(clazz));
048        }
049    
050        public ClassPointcut packageName(String packageName) {
051            return new DynaopClassPointcut(Pointcuts.packageName(packageName));
052        }
053    
054        public ClassPointcut intersection(ClassPointcut a, ClassPointcut b) {
055            return new DynaopClassPointcut(Pointcuts.intersection(toDynaopClassCut(a), toDynaopClassCut(b)));
056        }
057    
058        public ClassPointcut union(ClassPointcut a, ClassPointcut b) {
059            return new DynaopClassPointcut(Pointcuts.union(toDynaopClassCut(a), toDynaopClassCut(b)));
060        }
061    
062        public ClassPointcut not(ClassPointcut classPointcut) {
063            return new DynaopClassPointcut(Pointcuts.not(toDynaopClassCut(classPointcut)));
064        }
065    
066        public MethodPointcut allMethods() {
067            return new DynaopMethodPointcut(Pointcuts.ALL_METHODS);
068        }
069    
070        public MethodPointcut getMethods() {
071            return new DynaopMethodPointcut(Pointcuts.GET_METHODS);
072        }
073    
074        public MethodPointcut isMethods() {
075            return new DynaopMethodPointcut(Pointcuts.IS_METHODS);
076        }
077    
078        public MethodPointcut setMethods() {
079            return new DynaopMethodPointcut(Pointcuts.SET_METHODS);
080        }
081    
082        public MethodPointcut objectMethods() {
083            return new DynaopMethodPointcut(Pointcuts.OBJECT_METHODS);
084        }
085    
086        public MethodPointcut returnType(ClassPointcut classPointcut) {
087            return new DynaopMethodPointcut(Pointcuts.returnType(toDynaopClassCut(classPointcut)));
088        }
089    
090        public MethodPointcut signature(String regexp) {
091            try {
092                return new DynaopMethodPointcut(Pointcuts.signature(regexp));
093            } catch (MalformedPatternException e) {
094                throw new MalformedRegularExpressionException("malformed method signature regular expression", e);
095            }
096        }
097    
098        public MethodPointcut oneMethod(Method method) {
099            return new DynaopMethodPointcut(Pointcuts.singleton(method));
100        }
101    
102        public MethodPointcut declaringClass(ClassPointcut classPointcut) {
103            return new DynaopMethodPointcut(Pointcuts.declaringClass(toDynaopClassCut(classPointcut)));
104        }
105    
106        public MethodPointcut membersOf(Class clazz) {
107            return new DynaopMethodPointcut(Pointcuts.membersOf(clazz));
108        }
109    
110        public MethodPointcut intersection(MethodPointcut a, MethodPointcut b) {
111            return new DynaopMethodPointcut(Pointcuts.intersection(toDynaopMethodCut(a), toDynaopMethodCut(b)));
112        }
113    
114        public MethodPointcut union(MethodPointcut a, MethodPointcut b) {
115            return new DynaopMethodPointcut(Pointcuts.union(toDynaopMethodCut(a), toDynaopMethodCut(b)));
116        }
117    
118        public MethodPointcut not(MethodPointcut methodPointcut) {
119            return new DynaopMethodPointcut(Pointcuts.not(toDynaopMethodCut(methodPointcut)));
120        }
121    
122        private static dynaop.ClassPointcut toDynaopClassCut(final ClassPointcut nanoCut) {
123            // The purpose of the anonymous inner class adapter below is to allow
124            // users to use union, intersection and not with custom pointcuts (not
125            // instances of dynaop.ClassPointcut). Now we could just wrap nanoCut
126            // with the adapter every time, even if it is already a
127            // dynaop.ClassPointcut. But the extra level of indirection gets a
128            // little
129            // confusing when debugging. Thus the instanceof check.
130            if (nanoCut instanceof dynaop.ClassPointcut) {
131                return (dynaop.ClassPointcut) nanoCut;
132            } else {
133                return new dynaop.ClassPointcut() {
134                    public boolean picks(Class clazz) {
135                        return nanoCut.picks(clazz);
136                    }
137                };
138            }
139        }
140    
141        private static dynaop.MethodPointcut toDynaopMethodCut(final MethodPointcut nanoCut) {
142            // see comment in toDynaopClassCut, above
143            if (nanoCut instanceof dynaop.MethodPointcut) {
144                return (dynaop.MethodPointcut) nanoCut;
145            } else {
146                return new dynaop.MethodPointcut() {
147                    public boolean picks(Method method) {
148                        return nanoCut.picks(method);
149                    }
150                };
151            }
152        }
153    
154    }