001 /* 002 Copyright (C) 2001 Renaud Pawlak <renaud@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.wrappers; 019 020 import org.aopalliance.intercept.ConstructorInvocation; 021 import org.aopalliance.intercept.MethodInvocation; 022 import org.objectweb.jac.core.AspectComponent; 023 import org.objectweb.jac.core.Interaction; 024 import org.objectweb.jac.core.Wrapper; 025 026 /** 027 * <code>LimiterWrapper</code> implements a wrapper that tests a 028 * counter value before calling the wrappee object. If the counter is 029 * not with the max and min limits, it raises the 030 * <code>LimiterException</code> 031 * 032 * <p>Use this wrapper as follows: 033 * 034 * <ul><pre> 035 * LimiterWrapper lw = new LimiterWrapper(0, 100); 036 * a_stack.wrap(lw, "inc", "push"); 037 * a_stack.wrap(lw, "dec", "pop"); 038 * a_stack.wrap(lw, "testMax", "push"); 039 * a_stack.wrap(lw, "testMin", "pop"); 040 * </pre></ul> 041 * 042 * <p>Where <code>a_stack</code> is an instance of a class 043 * <code>Stack</code>. When wrapping the stack, it will raise a 044 * <code>LimiterException</code> if a push is done and that the 045 * counter is greater or equal to 100 or if a pop is done and that the 046 * counter is lower or equal to 0. 047 * 048 * <p> NOTE: this class cannot be used alone. Its instances must 049 * wrap some instances of other objects (possibly other 050 * wrappers). 051 * 052 * @see org.objectweb.jac.core.Wrappee 053 * @see org.objectweb.jac.core.Wrapping#wrap(Wrappee,Wrapper,AbstractMethodItem) 054 * @see org.objectweb.jac.wrappers.LimiterException */ 055 056 public class LimiterWrapper extends Wrapper { 057 058 /** Store the maximum bound of the limiter. */ 059 protected int max; 060 /** Store the minimum bound of the limiter. */ 061 protected int min; 062 /** Store the counter of the limiter. */ 063 protected int counter = 0; 064 065 /** 066 * Construct a new limiter and initialize the bounds. 067 * 068 * @param min the minimum counter value. 069 * @param max the maximum counter value. 070 */ 071 public LimiterWrapper(AspectComponent ac, int min, int max) { 072 super(ac); 073 this.min = min; 074 this.max = max; 075 } 076 077 /** 078 * Return the max bound of the limiter. 079 * 080 * @return the max bound 081 */ 082 public int getMax() { 083 return max; 084 } 085 086 /** 087 * Set the max bound of the limiter. 088 * 089 * @param max the new max bound 090 */ 091 public void setMax(int max) { 092 this.max = max; 093 } 094 095 /** 096 * Return the current counter of the limiter. 097 * 098 * @return the counter 099 */ 100 public int getCounter() { 101 return counter; 102 } 103 104 /** 105 * This wrapping method increments the limiter counter and calls 106 * the wrappee method. 107 * 108 * <p>For instance, <code>inc</code> could wrap the 109 * <code>push</code> method of a stack so that the counter is 110 * incremented when a new element is placed on the top of the 111 * stack. 112 * 113 * <p>NOTE: this method do not test the bounds. Use 114 * <code>testMax</code> to do this. 115 * 116 * @see LimiterWrapper#testMax(Interaction) 117 * 118 * @return the original method return value 119 */ 120 121 public Object inc(Interaction interaction) { 122 counter++; 123 return proceed(interaction); 124 } 125 126 /** 127 * This wrapping method decrements the limiter counter and calls 128 * the wrappee method. 129 * 130 * <p>For instance, <code>dec</code> could wrap the 131 * <code>pop</code> method of a stack so that the counter is 132 * incremented when an element is removed from it. 133 * 134 * <p>NOTE: this method do not test the bounds. Use 135 * <code>testMin</code> to do this. 136 * 137 * @see LimiterWrapper#testMin(Interaction) 138 * 139 * @return the original method return value 140 */ 141 142 public Object dec(Interaction interaction) { 143 counter--; 144 return proceed(interaction); 145 } 146 147 /** 148 * This wrapping method tests the counter of the limiter and 149 * raises the <code>LimiterExeption</code> when when it is over 150 * the maximum value. 151 * 152 * <p>NOTE: this method must be used with the <code>inc</code> and 153 * <code>dec</code> wrapping methods that mofify the counter 154 * value. 155 * 156 * @see LimiterWrapper#inc(Interaction) 157 * @see LimiterWrapper#dec(Interaction) 158 * 159 * @return the original method return value or raise an exception 160 */ 161 162 public Object testMax(Interaction interaction) 163 throws LimiterException { 164 if(counter >= max) { 165 throw new LimiterException("counter reached its maximum count"); 166 } 167 return proceed(interaction); 168 } 169 170 /** 171 * This wrapping method tests the counter of the limiter and 172 * raises the <code>LimiterExeption</code> when when it is below 173 * the minimum value. 174 * 175 * <p>NOTE: this method must be used with the <code>inc</code> and 176 * <code>dec</code> wrapping methods that mofify the counter 177 * value. 178 * 179 * @see LimiterWrapper#inc(Interaction) 180 * @see LimiterWrapper#dec(Interaction) 181 * 182 * @return the original method return value or raise an exception 183 */ 184 185 public Object testMin(Interaction interaction) 186 throws LimiterException { 187 if(counter <= min) { 188 throw new LimiterException("counter reached its minimum count"); 189 } 190 return proceed(interaction); 191 } 192 193 /* (non-Javadoc) 194 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) 195 */ 196 public Object invoke(MethodInvocation invocation) throws Throwable { 197 // TODO Auto-generated method stub 198 return null; 199 } 200 201 /* (non-Javadoc) 202 * @see org.aopalliance.intercept.ConstructorInterceptor#construct(org.aopalliance.intercept.ConstructorInvocation) 203 */ 204 public Object construct(ConstructorInvocation invocation) throws Throwable { 205 // TODO Auto-generated method stub 206 return null; 207 } 208 209 }