001    /*
002      Copyright (C) 2002 Laurent Martelli <laurent@aopsys.com>
003    
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
017    
018    package org.objectweb.jac.aspects.user;
019    
020    import gnu.regexp.RE;
021    import gnu.regexp.REException;
022    import org.objectweb.jac.core.ACManager;
023    import org.objectweb.jac.core.rtti.MemberItem;
024    import org.objectweb.jac.core.rtti.MetaItem;
025    import org.objectweb.jac.util.Log;
026    import org.objectweb.jac.core.rtti.AbstractMethodItem;
027    
028    /**
029     * Rules for profiles : allow/deny reading, allow/deny writing, etc ...
030     *
031     * @see Profile
032     * @see UserAC
033     */
034    
035    public class Rule {
036        public static final boolean ALLOW = true;
037        public static final boolean DENY = false;
038    
039        boolean allow;
040        String resourceExpression;
041        transient RE regexp;
042    
043        /**
044         * @param allow if <code>true</code> : allowing rule, if
045         * <code>false</code> : denying rule
046         * @param resourceExpression regular expression indicating which
047         * fields or methods this rule aplies to.
048         */
049        public Rule(boolean allow, String resourceExpression) {
050            this.allow = allow;
051            this.resourceExpression = resourceExpression;
052            try {
053                this.regexp = new RE(resourceExpression);
054            } catch (REException e) {
055                throw new RuntimeException("Caught regular expression exception: "+e);
056            }
057        }
058    
059        /**
060         * Get rule mode (allow or deny).
061         *
062         * @return the rule's mode.
063         */
064        public boolean getAllow() {
065            return allow;
066        }
067    
068        /**
069         * Set rule mode (allow or deny).
070         *
071         * @param allow mode (<code>true</code> for allow,
072         * <code>false</code> for deny).
073         */
074        public void setAllow(boolean allow) {
075            this.allow = allow;
076            invalidateCache();
077        }
078    
079        /**
080         * Set regular expression indicating which fields to apply rule for.
081         *
082         * @param resourceExpression the regular expression.
083         */
084        public void setResourceExpression(String resourceExpression) {
085            this.resourceExpression = resourceExpression;
086            invalidateCache();
087        }
088    
089        public String getResourceExpression() {
090            return resourceExpression;
091        }
092    
093        /**
094         * Returns a regular expression object for the resource expression.
095         */
096        protected RE getRegexp() {
097            if (regexp==null) 
098                try { 
099                    regexp = new RE(resourceExpression==null?"":resourceExpression);
100                } catch (REException e) {
101                }
102            return regexp;
103        }
104    
105        /**
106         * Tells if a <code>MetaItem</code> matches the rule.
107         *
108         * @param item the MetaItem
109         */
110        public boolean match(MetaItem item) {
111            String resourceDescr;
112            if (item instanceof AbstractMethodItem) {         
113                AbstractMethodItem method = (AbstractMethodItem)item;
114                resourceDescr = method.getParent().getName()+
115                    "."+method.getFullName();
116            } else if (item instanceof MemberItem) {         
117                resourceDescr = ((MemberItem)item).getParent().getName()+
118                    "."+item.getName();
119            } else {
120                resourceDescr = item.toString();
121            }
122            boolean result = getRegexp().isMatch(resourceDescr);
123            if (!result && (item instanceof AbstractMethodItem)) {
124                resourceDescr = ((MemberItem)item).getParent().getName()+
125                    "."+item.getName();
126                result = getRegexp().isMatch(resourceDescr);
127            }
128            Log.trace("profile.rule",resourceExpression+
129                      (result?" matches ":" does not match ")+resourceDescr);
130            return result;
131        }
132    
133        /**
134         * Invalidates the UserAC.controlAttribute's cache.
135         *
136         * <p>It merely calls invalidateCache() on UserAC.</p>
137         *
138         * @see UserAC#controlAttribute(Object,MetaItem,String,Object)
139         * @see UserAC#invalidateCache()
140         */
141        protected void invalidateCache() {
142            UserAC ac = (UserAC)ACManager.getACM().getAC("user");
143            if (ac!=null)
144                ac.invalidateCache();
145        }
146    }