001 /* 002 Copyright (C) 2001-2002 Renaud Pawlak, Laurent Martelli 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.core.rtti; 019 020 import java.lang.reflect.*; 021 import java.util.*; 022 import org.objectweb.jac.core.ACManager; 023 import org.objectweb.jac.util.ExtArrays; 024 025 /** 026 * This class defines the super class for all the meta items whithin 027 * the rtti aspect.<p> 028 * 029 * A meta item encapsulates a <code>java.lang.reflect</code> item so 030 * that the user of this item can add extra informations 031 * (attributes). Typically this feature can be used by an aspect to 032 * tag an element of the model to react to this tag later on.<p> 033 * 034 * Examples:<p> <ul> 035 * 036 * <li>A persistence aspect can tag some field persistent, add methods 037 * that change the object states even if they do not fit naming 038 * conventions...<p> 039 * 040 * <li>A GUI can tag a given field to be invisible or a class to be 041 * displayed by a special view (eg a given Swing component)... 042 * 043 * </ul> 044 * 045 * @author Renaud Pawlak 046 * @author Laurent Martelli 047 */ 048 049 public abstract class MetaItem { 050 051 /** A correspondance table between the RRTI attributes and the 052 aspect components that set them. */ 053 protected static HashMap attrACs = new HashMap(); 054 055 /** 056 * Unsets all the attributes of all the RTTI items that have been 057 * set by a given aspect component.<p> 058 * 059 * @param acName the aspect component name 060 * @see #unsetAttribute(String) */ 061 062 public static void unsetAttributesFor( String acName ) {} 063 064 /* A <code>name -> value</code> container. */ 065 private HashMap attributes = new HashMap(); 066 067 static ACManager acManager; 068 static Method acManagerGetObjectMethod; 069 static Method acManagerGetMethod; 070 071 static { 072 try { 073 acManagerGetMethod = 074 Class.forName("org.objectweb.jac.core.ACManager").getMethod("get",new Class[0]); 075 acManagerGetObjectMethod = 076 Class.forName("org.objectweb.jac.core.ACManager").getMethod( 077 "getObject",new Class[]{String.class}); 078 } catch(Exception e) { 079 e.printStackTrace(); 080 } 081 } 082 083 Object getAC(String name) { 084 Object ac = null; 085 try { 086 if (acManager==null) { 087 acManager = 088 (ACManager)acManagerGetMethod.invoke(null,ExtArrays.emptyObjectArray); 089 } 090 ac = acManagerGetObjectMethod.invoke(acManager,new Object[]{name}); 091 } catch (Exception e) { 092 e.printStackTrace(); 093 } 094 return ac; 095 } 096 097 boolean isRegisteredAC( String name ) { 098 return getAC(name)!=null; 099 } 100 101 static Method collabGetMethod = null; 102 static Method collabGetCurACMethod = null; 103 104 String getCurAC() { 105 /* 106 Object acName = null; 107 try { 108 Class collaboration = Class.forName("org.objectweb.jac.core.Collaboration"); 109 if (collabGetMethod==null) { 110 collabGetMethod = collaboration.getMethod("get",ExtArrays.emptyClassArray); 111 } 112 Object coll = collabGetMethod.invoke(null,ExtArrays.emptyObjectArray); 113 if (collabGetCurACMethod==null) { 114 collabGetCurACMethod = 115 coll.getClass().getMethod("getCurAC",ExtArrays.emptyClassArray); 116 } 117 acName = collabGetCurACMethod.invoke(coll,ExtArrays.emptyObjectArray); 118 } catch (Exception e) { 119 e.printStackTrace(); 120 } 121 return (String)acName; 122 */ 123 return null; 124 } 125 126 static AttributeController accessController = null; 127 128 /** 129 * Registers a new access controller for this application. 130 * 131 * @param controller the controller object 132 */ 133 public static void registerAccessController(AttributeController controller) { 134 accessController = controller; 135 } 136 137 Object controlledAccess(Object substance, String name, Object value) { 138 if ( accessController==null || 139 ! (name.equals("GuiAC.VISIBLE") || 140 name.equals("GuiAC.EDITABLE") || 141 name.equals("GuiAC.ADDABLE") || 142 name.equals("GuiAC.CREATABLE") || 143 name.equals("GuiAC.REMOVABLE")) ) 144 return value; 145 146 Object result = null; 147 try { 148 result = accessController.controlAttribute(substance,this,name,value); 149 } catch(Exception e) { 150 e.printStackTrace(); 151 return value; 152 } 153 return result; 154 } 155 156 157 /** 158 * Gets the value of an attribute. 159 * 160 * @param name the name of the attribute 161 * @return the value of the attribute 162 */ 163 164 public Object getAttribute(String name) { 165 return getAttribute(name,false); 166 } 167 168 /** 169 * Gets the value of an attribute even if the aspect if not yet 170 * configured and weaved. 171 * 172 * @param name the name of the attribute 173 * @return the value of the attribute 174 */ 175 public Object getAttributeAlways(String name) { 176 return getAttribute(name,true); 177 } 178 179 /** 180 * Gets the value of an attribute. 181 * 182 * @param name the name of the attribute 183 * @param always if true, return a value even the aspect is not weaved 184 * @return the value of the attribute 185 * 186 */ 187 public Object getAttribute(String name, boolean always) { 188 String acName = (String)attrACs.get(name); 189 if (!always && (acName!=null && (!isRegisteredAC(acName))) ) { 190 return null; 191 } 192 Object value=attributes.get(name); 193 if (value==null && itemClass!=null) { 194 value = itemClass.getAttribute(name); 195 } 196 return controlledAccess(null,name,value); 197 } 198 199 /** 200 * Gets the value of a boolean attribute. 201 * 202 * @param name the name of the attribute 203 * @param defValue default value for the attribute if it is not set 204 * @return the value of the attribute 205 */ 206 public boolean getBoolean(String name, boolean defValue) { 207 Boolean value = (Boolean)getAttribute(name); 208 if (value==null) 209 return defValue; 210 else 211 return value.booleanValue(); 212 } 213 214 /** 215 * Gets the value of an attribute. 216 * 217 * @param substance 218 * @param name the name of the attribute 219 * @return the value of the attribute 220 */ 221 222 public Object getAttribute(Object substance, String name) { 223 String acName = (String)attrACs.get(name); 224 if( acName!=null && (!isRegisteredAC(acName)) ) { 225 return null; 226 } 227 Object value=attributes.get(name); 228 if (value==null && itemClass!=null) { 229 value = itemClass.getAttribute(name); 230 } 231 return controlledAccess(substance,name,value); 232 } 233 234 /** 235 * Sets the value of an attribute. 236 * 237 * @param name the name of the attribute 238 * @param value the value of the attribute 239 */ 240 241 public final void setAttribute(String name, Object value) { 242 if (name == null) 243 return; 244 String acName = (String)getCurAC(); 245 if (acName != null) { 246 if ( !attrACs.containsKey(name) ) { 247 attrACs.put(name,acName); 248 } 249 } 250 attributes.put(name,value); 251 } 252 253 /** 254 * Unsets the value of an attribute. 255 * 256 * @param name the name of the attribute to unset 257 */ 258 259 public void unsetAttribute(String name) { 260 attributes.remove(name); 261 } 262 263 /** 264 * This method gets the name of the meta item by delegating to the 265 * actual <code>java.lang.reflect</code> meta item.<p> 266 * 267 * @return the item name */ 268 269 public abstract String getName(); 270 271 MetaItem itemClass; 272 public void setItemClass(MetaItem itemClass) { 273 this.itemClass = itemClass; 274 } 275 public MetaItem getItemClass() { 276 return itemClass; 277 } 278 }