    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    }