001 /* 002 Copyright (C) 2001 Renaud Pawlak, Laurent Martelli, Lionel 003 Seinturier, Fabrice Legond-Aubry. 004 005 This program is free software; you can redistribute it and/or modify 006 it under the terms of the GNU Lesser General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This program is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 GNU Lesser General Public License for more details. 014 015 You should have received a copy of the GNU Lesser General Public 016 License along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 018 USA */ 019 020 package org.objectweb.jac.core; 021 022 import gnu.regexp.RE; 023 import gnu.regexp.REException; 024 import java.util.*; 025 import org.apache.log4j.Logger; 026 import org.objectweb.jac.util.Strings; 027 028 /** 029 * This class is used to load all the properties necessary to the 030 * execution of JAC. This class is called by the <code>Jac</code>, 031 * <code>JacLoader</code> and <code>JacObject</code> and 032 * <code>CompositionAspect</code> classes. 033 * 034 * @see JacLoader 035 * @see Jac 036 * @author Renaud Pawlak 037 * @author Lionel Seinturier 038 * @author Laurent Martelli */ 039 040 public abstract class JacPropLoader extends JacPropTools { 041 static Logger logger = Logger.getLogger("props"); 042 043 /************************************************************** 044 * Static members. 045 **************************************************************/ 046 047 /** The JAC property file name. */ 048 public final static String propFileName = "jac.prop"; 049 050 /** The name of the property in the the jac.prop file. */ 051 public final static String toNotAdaptProp = "jac.toNotAdapt"; 052 053 /** The name of the property in the the jac.prop file. */ 054 public final static String toAdaptProp = "jac.toAdapt"; 055 056 /** The name of the property in the the jac.prop file. */ 057 public final static String wrappableMethodsProp = "jac.wrappableMethods"; 058 059 /** property name for classes whose fields must not be translated */ 060 public final static String dontTranslateFieldsProp = "jac.dontTranslateField"; 061 062 /** The name of the property in the the jac.prop file. */ 063 public final static String toWrapProp = "jac.toWrap"; 064 065 /** The name of the property that defines the initial global 066 topology in the jac.prop file. */ 067 public final static String topologyProp = "jac.topology"; 068 069 /** 070 * The jac.prop property string to declare initially woven aspect 071 * components. */ 072 public final static String acsProp = "jac.acs"; 073 074 /** 075 * The jac.prop property string to declare when the initially woven 076 * aspect components are woven. */ 077 public final static String startWeavingPlacesProp = "jac.startWeavingPlaces"; 078 079 /** 080 * The jac.prop property string to set the composition aspect class 081 * name. */ 082 public final static String compositionAspectProp = "jac.comp.compositionAspect"; 083 084 085 /** The name of the wrapping order property in the prop file. */ 086 public final static String wrappingOrderProp = "jac.comp.wrappingOrder"; 087 088 /** The name of the incompatible property in the prop file. */ 089 public final static String incompatibleACsProp = "jac.comp.imcompatibleACs"; 090 091 /** The name of the dependent property in the prop file. */ 092 public final static String dependentACsProp = "jac.comp.dependentACs"; 093 094 /** The name of the property in the the jac.prop file. */ 095 public final static String bytecodeModifierProp = "jac.bytecodeModifier"; 096 097 /** Property key for the remote reference class. */ 098 public static final String remRefClassProp = "jac.remoteRefClass"; 099 100 /** Default remote reference class. */ 101 public static final String remRefDefaultClassName = "org.objectweb.jac.core.dist.rmi.RMIRemoteRef"; 102 103 /** Property key for the class providing a naming service. */ 104 public static final String namingClassProp = "org.objectweb.jac.core.dist.namingClass"; 105 106 /** Default class providing a naming service. */ 107 public static final String namingClassDefaultName = "org.objectweb.jac.core.dist.rmi.RMINaming"; 108 109 /** The properties loaded from the jac.prop file. */ 110 public static Properties props = new Properties(); 111 112 /** Store the packages (set of classes) translated to be 113 wrappable. */ 114 public static HashSet packagesToAdapt = new HashSet(); 115 116 /** Store the packages (set of classes) translated to be not 117 wrappable. */ 118 public static HashSet packagesToNotAdapt = new HashSet(); 119 120 /** Store the methods that are wrappable (per class) */ 121 public static Hashtable wrappableMethods = new Hashtable(); 122 123 /** Store the classes whose fields must not be translated */ 124 public static HashSet dontTranslateFields = new HashSet(); 125 126 public static HashSet packagesToWrap = new HashSet(); 127 128 public static String compositionAspect = null; 129 130 /** The name of the bytecode modifier package */ 131 public static String bytecodeModifier = null; 132 133 public static String remoteRefClassName = null; 134 135 public static String namingClassName = null; 136 137 /** Stores all the declared aspect components. */ 138 public static Hashtable declaredACs = new Hashtable(); 139 140 /** Store the default wrapping order. */ 141 public static Vector wrappingOrder = new Vector(); 142 143 /** Store the exclusive aspect component pairs. */ 144 public static Vector incompatibleACs = new Vector(); 145 146 /** Store the dependent aspect component pairs. */ 147 public static Vector dependentACs = new Vector(); 148 149 public static int acs_count=0; 150 151 static HashSet packagesToAdaptRE = new HashSet(); 152 153 static HashSet packagesToNotAdaptRE = new HashSet(); 154 155 /** 156 * Add some properties. 157 * @param ps the properties to add 158 * @return true is ps!=null, false otherwise 159 */ 160 public static boolean addProps(Properties ps) { 161 String tmp; 162 if (ps==null) 163 return false; 164 for (Enumeration e = ps.propertyNames() ; e.hasMoreElements() ;) { 165 String key=(String)e.nextElement(); 166 String value=ps.getProperty(key); 167 if (value!=null) 168 props.setProperty(key,value); 169 } 170 171 // Get list of packages that must not be adpated 172 fillSetProps(packagesToNotAdapt, ps, toNotAdaptProp, false); 173 Iterator i = packagesToNotAdapt.iterator(); 174 packagesToNotAdaptRE.clear(); 175 while (i.hasNext()) { 176 String pkg = (String)i.next(); 177 try { 178 packagesToNotAdaptRE.add(new RE("^"+Strings.replace(Strings.replace(Strings.replace(pkg,"$","\\$"),".","\\."),"*",".*")+"$")); 179 } catch(REException e) { 180 logger.warn("RE exception: "+e); 181 } 182 } 183 184 // Get list of packages that must be adpated 185 fillSetProps(packagesToAdapt, ps, toAdaptProp, false); 186 i = packagesToAdapt.iterator(); 187 packagesToAdaptRE.clear(); 188 while (i.hasNext()) { 189 String pkg = (String)i.next(); 190 try { 191 packagesToAdaptRE.add(new RE("^"+Strings.replace(Strings.replace(Strings.replace(pkg,"$","\\$"),".","\\."),"*",".*")+"$")); 192 } catch(REException e) { 193 logger.warn("RE exception: "+e); 194 } 195 } 196 197 // Get list of packages that must be wrapped 198 fillSetProps(packagesToWrap, ps, toWrapProp, true); 199 200 // Get list of methods that must be wrappable 201 fillMapProps(wrappableMethods, ps, wrappableMethodsProp, 0, false); 202 203 // Get classes whose collection fields must not be translated 204 fillSetProps(dontTranslateFields,ps,dontTranslateFieldsProp,false); 205 206 // Get list of aspects that must be weaved 207 fillMapProps(declaredACs, ps, acsProp, 1, false); 208 209 // Get the order of aspects wrapping 210 fillListStringProps(wrappingOrder, ps, wrappingOrderProp, false); 211 212 fillListStringProps(dependentACs, ps, dependentACsProp, false); 213 214 fillListStringProps(incompatibleACs, ps, incompatibleACsProp, false); 215 216 tmp=fillStringProp(ps, compositionAspectProp); 217 if (tmp!=null) compositionAspect = tmp; 218 219 220 //Get the bytecode modifier name 221 tmp= fillStringProp (ps, bytecodeModifierProp); 222 if (tmp!=null) bytecodeModifier = tmp; 223 224 225 //Get the 226 tmp= fillStringProp (ps, remRefClassProp); 227 if (tmp!=null) bytecodeModifier = tmp; 228 229 //Get the 230 tmp= fillStringProp (ps, namingClassProp); 231 if (tmp!=null) bytecodeModifier = tmp; 232 233 return true; 234 } 235 236 public static void loadProps(boolean d) { 237 loadProps(); 238 } 239 240 /** 241 * Try to load the properties and set all the internal hash tables 242 * in order to be used by the JAC core objects. No parameters. No 243 * returns. 244 */ 245 public static void loadProps() { 246 boolean propsInMemory = false; 247 //props = new Properties(); 248 249 // FOR TEST PURPOSE ONLY 250 /* 251 String myr=System.getProperty ("JAC_ROOT","vide"); 252 Properties p=System.getProperties(); 253 String elt; 254 for (Enumeration e = p.propertyNames() ; e.hasMoreElements() ;) { 255 elt=(String)e.nextElement(); 256 System.out.println ("key '"+ elt + "' has value "+p.getProperty(elt)); 257 258 } 259 */ 260 261 // Try to read a jac.prop in JAC_ROOT 262 //System.getProperty("user.dir"); 263 //File f = new File("."); 264 //loadDirectory = f.getAbsolutePath(); 265 if (!Strings.isEmpty(Jac.getJacRoot())) 266 propsInMemory |= addProps(getPropsFrom(Jac.getJacRoot(), propFileName)); 267 268 String directory; 269 directory = System.getProperty("JAC_ROOT",null); 270 if (directory != null) 271 propsInMemory |= addProps(getPropsFrom(directory, propFileName)); 272 273 274 // Try to read a jac.prop in $HOME 275 directory = System.getProperty("user.home",null); 276 if (directory!=null) 277 propsInMemory|=addProps(getPropsFrom(directory, propFileName)); 278 279 // Try to read a jac.prop file from the current directory 280 propsInMemory |= addProps(getPropsFrom("./", propFileName)); 281 282 //Stop everything if not, at least, one jac property file is found 283 //Call System.exit(); 284 if (!propsInMemory) 285 { 286 logger.warn("Can not find the '"+propFileName+"' file."); 287 } 288 289 acs_count=declaredACs.size(); 290 if (bytecodeModifier == null) 291 bytecodeModifier = "BCEL"; 292 293 if (remoteRefClassName == null) 294 remoteRefClassName = remRefDefaultClassName; 295 296 if (namingClassName == null) 297 namingClassName = namingClassDefaultName; 298 } 299 300 /** 301 * Returns true if the fields of the specified class must be translated 302 */ 303 public static boolean translateFields(String className) { 304 Iterator i = dontTranslateFields.iterator(); 305 while (i.hasNext()) { 306 try { 307 RE dontTranslate = new RE((String)i.next()); 308 logger.debug("Testing "+dontTranslate); 309 if (dontTranslate.isMatch(className)) { 310 logger.debug("Do not translate fields for "+className); 311 return false; 312 } 313 } catch (REException e) { 314 logger.warn("RE exception: "+e); 315 } 316 } 317 logger.debug("Translate fields for "+className); 318 return true; 319 } 320 321 /** 322 * Returns true if the specified class matches the toAdapt property. 323 */ 324 public static boolean adaptClass(String className) { 325 logger.debug("Adapt class "+className+" ???"); 326 Iterator i = packagesToAdaptRE.iterator(); 327 while (i.hasNext()) { 328 RE regexp = (RE)i.next(); 329 logger.debug("Testing "+regexp); 330 if (regexp.isMatch(className)) { 331 logger.debug("Adapt "+className); 332 return true; 333 } 334 } 335 logger.debug("Do not force adaptation of "+className); 336 return false; 337 } 338 339 /** 340 * Returns true if the specified class matches the toNotAdapt property. 341 */ 342 public static boolean doNotAdaptClass(String className) { 343 logger.debug("Do not adapt class "+className+" ???"); 344 Iterator i = packagesToNotAdaptRE.iterator(); 345 while (i.hasNext()) { 346 RE regexp = (RE)i.next(); 347 logger.debug("Testing "+regexp); 348 if (regexp.isMatch(className)) { 349 logger.debug("Do not adapt "+className); 350 return true; 351 } 352 } 353 logger.debug("Adaptation not disabled for "+className); 354 return false; 355 } 356 }