001 /* 002 Copyright (C) 2001-2002 Renaud Pawlak. 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 015 License along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 017 USA */ 018 019 package org.objectweb.jac.core; 020 021 import java.util.Vector; 022 import org.aopalliance.intercept.Interceptor; 023 024 /** 025 * This special aspect component is used by the system to solve 026 * inter-aspect composition issues. 027 * 028 * <p>It is typically used to order the different wrappers at runtime 029 * (see <code>getWeaveTimeRank()</code>) or to check if two aspect 030 * components are incompatible of dependent (see 031 * <code>addIncompatibleACPairs()</code> and 032 * <code>addDependentACPair()</code>). 033 * 034 * @author <a href="mailto:pawlak@cnam.fr">Renaud Pawlak</a> 035 */ 036 037 public class CompositionAspect extends AspectComponent { 038 039 /** The name of the wrapping order property in the prop file. */ 040 //protected static String wrappingOrderProp = "org.objectweb.jac.comp.wrappingOrder"; 041 /** The name of the incompatible property in the prop file. */ 042 //protected static String incompatibleACsProp = "org.objectweb.jac.comp.imcompatibleACs"; 043 /** The name of the dependent property in the prop file. */ 044 //protected static String dependentACsProp = "org.objectweb.jac.comp.dependentACs"; 045 046 /** Store the default wrapping order. */ 047 protected Vector wrappingOrder = JacPropLoader.wrappingOrder; 048 049 /** Store the exclusive aspect component pairs. */ 050 protected Vector incompatibleACs = JacPropLoader.incompatibleACs; 051 052 /** Store the dependent aspect component pairs. */ 053 protected Vector dependentACs = JacPropLoader.dependentACs; 054 055 /** 056 * The default contructor (reads the jac.prop file to initialize 057 * the composition aspect). */ 058 059 public CompositionAspect() { 060 } 061 062 /** 063 * When a wrappee method is beeing wrapped by a wrapper, this 064 * method is upcalled by the system to get the rank of the wrapper 065 * within the wrapping chain (the set of wrappers that allready 066 * wrap the wrappee method). 067 * 068 * @param wrappingChain the set of wrapping methods that allready 069 * wraps the wrappee method 070 * @param wrapper the wrapper that is going be added to the 071 * wrapping chain 072 * 073 * @see Wrapping#wrap(Wrappee,Wrapper,AbstractMethodItem) 074 */ 075 public int getWeaveTimeRank(WrappingChain wrappingChain, Wrapper wrapper) { 076 int i = 0; 077 Interceptor[] chain = wrappingChain.chain; 078 int wrapperRank = wrappingOrder.indexOf(wrapper.getClass().getName()); 079 for (; i < chain.length; i++) { 080 if (wrapperRank 081 <= wrappingOrder.indexOf(chain[i].getClass().getName())) { 082 return i; 083 } 084 } 085 /*Log.trace("composition", 086 "getting weave time rank for "+wrapper+"."+wrappingMethod+ 087 "==>" + i + "/" + wrappingChain.size());*/ 088 return i; 089 } 090 091 /** 092 * Returns true if wrapperType1 has to be run before 093 * wrapperType2. This method is used by 094 * <code>getWeaveTimeRank()</code>. 095 * 096 * @param wrapperType1 the first type to check 097 * @param wrapperType2 the second type to check 098 * @return true if (wrapperType1 < wrapperType2 ) 099 * @see #getWeaveTimeRank(WrappingChain,Wrapper) 100 */ 101 102 public final boolean areCorrectlyOrdered( 103 String wrapperType1, 104 String wrapperType2) { 105 /* 106 Log.trace("composition","areCorrectlyOrdered("+ 107 wrapperType1+"("+i1+"),"+wrapperType2+"("+i1+"))"); 108 */ 109 return ( 110 wrappingOrder.indexOf(wrapperType1) 111 <= wrappingOrder.indexOf(wrapperType2)); 112 /* 113 Log.trace("composition","areCorrectlyOrdered("+ 114 wrapperType1+","+wrapperType2+") -> false"); 115 */ 116 } 117 118 /** 119 * The getter for the wrapping types order. 120 * 121 * @return a vector that contains the ordered wrapper classes */ 122 123 public final Vector getWrappingTypesOrder() { 124 return wrappingOrder; 125 } 126 127 /** 128 * Add a new exlusive aspect component pair. 129 * 130 * <p>If ac1 and ac2 are incompatible, then ac1 cannot be 131 * registered in the Aspect Component Manager if ac2 is already 132 * registered (and reverse). 133 * 134 * <p>NOTE: this is a reflexive relation. 135 * 136 * @param ac1 the aspect component that is incompatible with ac2 137 * @param ac2 the aspect component that is incompatible with ac1 138 * @see ACManager#register(String,Object) */ 139 140 public final void addIncompatibleACPair( 141 AspectComponent ac1, 142 AspectComponent ac2) { 143 incompatibleACs.add(ac1); 144 incompatibleACs.add(ac2); 145 } 146 147 /** 148 * Add a new dependent aspect component pair. 149 * 150 * <p>If ac1 depends on ac2, then ac1 cannot be registered in the 151 * Aspect Component Manager if ac2 is not already registered. 152 * 153 * <p>NOTE: this is a transitive relation. 154 * 155 * @param ac1 the aspect component that depends on ac2 156 * @param ac2 the aspect component on which ac1 depends 157 * @see ACManager#register(String,Object) */ 158 159 public final void addDependentACPair( 160 AspectComponent ac1, 161 AspectComponent ac2) { 162 dependentACs.add(ac1); 163 dependentACs.add(ac2); 164 } 165 166 /** 167 * Returns true if the aspect components are incompatible. 168 * 169 * <p>NOTE: <code>areIncompatible(ac1,ac2)<code> equals 170 * <code>areIncompatible(ac2,ac1)<code> 171 * 172 * @param ac1 the first aspect component to check 173 * @param ac2 the second aspect component to check 174 * @return true if ac1 is incompatible with ac2 175 * @see #addIncompatibleACPair(AspectComponent,AspectComponent) */ 176 177 public final boolean areIncompatible( 178 AspectComponent ac1, 179 AspectComponent ac2) { 180 for (int i = 0; i < incompatibleACs.size(); i += 2) { 181 if ((ac1.equals(incompatibleACs.get(i)) 182 && ac2.equals(incompatibleACs.get(i + 1))) 183 || (ac2.equals(incompatibleACs.get(i)) 184 && ac1.equals(incompatibleACs.get(i + 1)))) { 185 return true; 186 } 187 } 188 return false; 189 } 190 191 /** 192 * Returns true if the aspect components are dependent. 193 * 194 * <p>NOTE: <code>areDependent(ac1,ac2)<code> not equals 195 * <code>areDependent(ac2,ac1)<code> 196 * 197 * @param ac1 the first aspect component to check 198 * @param ac2 the second aspect component to check 199 * @return true if ac1 depends on ac2 200 * @see #addDependentACPair(AspectComponent,AspectComponent) */ 201 202 public final boolean areDependent( 203 AspectComponent ac1, 204 AspectComponent ac2) { 205 for (int i = 0; i < dependentACs.size(); i += 2) { 206 if ((ac1.equals(dependentACs.get(i)) 207 && ac2.equals(dependentACs.get(i + 1))) 208 || (ac2.equals(dependentACs.get(i)) 209 && ac1.equals(dependentACs.get(i + 1)))) { 210 return true; 211 } 212 } 213 return false; 214 } 215 216 }