1 package org.apache.beehive.controls.api.properties; 2 19 20 import java.io.IOException ; 21 import java.lang.annotation.Annotation ; 22 import java.lang.annotation.Inherited ; 23 import java.lang.reflect.AnnotatedElement ; 24 import java.lang.reflect.Field ; 25 import java.lang.reflect.Method ; 26 import java.util.HashMap ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 30 31 import org.apache.beehive.controls.api.bean.ControlBean; 32 import org.apache.beehive.controls.api.bean.ControlExtension; 33 import org.apache.beehive.controls.api.bean.ControlInterface; 34 35 39 public class AnnotatedElementMap extends BaseMap implements PropertyMap,java.io.Serializable 40 { 41 45 public AnnotatedElementMap(AnnotatedElement annotElem) 46 { 47 if (annotElem instanceof Class ) 48 setMapClass((Class )annotElem); 49 else if (annotElem instanceof Field ) 50 setMapClass(((Field )annotElem).getType()); 51 else if (annotElem instanceof Method ) 52 { 53 Class mapClass = getMethodMapClass((Method )annotElem); 54 setMapClass(mapClass); 55 } 56 else 57 throw new IllegalArgumentException ("Unsupported element type: " + annotElem.getClass()); 58 59 _annotElem = annotElem; 60 } 61 62 66 Class getMethodMapClass(Method method) { 67 68 Class origMapClass = method.getDeclaringClass(); 69 Class mapClass = origMapClass; 70 while (mapClass != null && !isValidMapClass(mapClass)) { 71 mapClass = mapClass.getDeclaringClass(); 72 } 73 if (mapClass == null) { 74 mapClass = origMapClass; 75 } 76 return mapClass; 77 } 78 79 boolean isValidMapClass(Class mapClass) { 80 if (ControlBean.class.isAssignableFrom(mapClass)) 81 { 82 return true; 83 } 84 else 85 { 86 if (mapClass.isAnnotation() || 87 mapClass.isAnnotationPresent(ControlInterface.class) || 88 mapClass.isAnnotationPresent(ControlExtension.class)) { 89 return true; 90 } 91 } 92 return false; 93 } 94 95 98 public void setProperty(PropertyKey key, Object value) 99 { 100 throw new IllegalStateException ("AnnotatedElementMap is a read-only PropertyMap"); 101 } 102 103 106 public Object getProperty(PropertyKey key) 107 { 108 if (!isValidKey(key)) 109 throw new IllegalArgumentException ("Key " + key + " is not valid for " + _mapClass); 110 111 112 Class propertySet = key.getPropertySet(); 116 Annotation annot = _annotElem.getAnnotation(propertySet); 117 if (annot != null) 118 return key.extractValue(annot); 119 120 if (propertySet.isAnnotationPresent(Inherited .class) && _annotElem instanceof Class ) 126 { 127 Class controlIntf = (Class )_annotElem; 128 do 129 { 130 Class [] superIntfs = controlIntf.getInterfaces(); 131 controlIntf = null; 132 for (int i = 0; i < superIntfs.length; i++) 133 { 134 if (superIntfs[i].isAnnotationPresent(ControlInterface.class) || 135 superIntfs[i].isAnnotationPresent(ControlExtension.class)) 136 { 137 controlIntf = superIntfs[i]; 138 annot = controlIntf.getAnnotation(propertySet); 139 if (annot != null) 140 return key.extractValue(annot); 141 } 142 } 143 144 } 145 while (controlIntf != null); 146 } 147 148 return super.getProperty(key); 152 } 153 154 158 public boolean containsPropertySet(Class <? extends Annotation > propertySet) 159 { 160 if (_annotElem.isAnnotationPresent(propertySet)) 161 return true; 162 163 return super.containsPropertySet(propertySet); 167 } 168 169 172 public AnnotatedElement getAnnotatedElement() 173 { 174 return _annotElem; 175 } 176 177 180 private String getMethodArgs(Method m) 181 { 182 StringBuffer sb = new StringBuffer (); 183 Class [] argTypes = m.getParameterTypes(); 184 for (int i = 0; i < argTypes.length; i++) 185 { 186 if (i != 0) sb.append(","); 187 sb.append(argTypes[i].toString()); 188 } 189 return sb.toString(); 190 } 191 192 196 private void writeObject(java.io.ObjectOutputStream out) throws IOException 197 { 198 if (_annotElem instanceof Class ) 203 { 204 _elemClass = (Class )_annotElem; 205 _elemDesc = null; } 207 else if (_annotElem instanceof Field ) 208 { 209 Field f = (Field )_annotElem; 210 _elemClass = f.getDeclaringClass(); 211 _elemDesc = f.getName(); 212 } 213 else if (_annotElem instanceof Method ) 214 { 215 Method m = (Method )_annotElem; 216 _elemClass = m.getDeclaringClass(); 217 _elemDesc = m.getName() + "(" + getMethodArgs(m) + ")"; 218 } 219 220 out.defaultWriteObject(); 221 } 222 223 227 private void readObject(java.io.ObjectInputStream in) 228 throws IOException , ClassNotFoundException 229 { 230 in.defaultReadObject(); 231 232 if (_elemDesc == null) _annotElem = _elemClass; 234 else 235 { 236 int argsIndex = _elemDesc.indexOf('/'); 237 if (argsIndex < 0) { 239 try 240 { 241 _annotElem = _elemClass.getDeclaredField(_elemDesc); 242 } 243 catch (NoSuchFieldException nsfe) 244 { 245 throw new IOException ("Unable to locate field " + nsfe); 246 } 247 } 248 else { 250 String methodName = _elemDesc.substring(0, argsIndex); 251 if (_elemDesc.charAt(argsIndex+1) == ')') 252 { 253 try 255 { 256 _annotElem = _elemClass.getDeclaredMethod(methodName, new Class [] {}); 257 } 258 catch (NoSuchMethodException nsme) 259 { 260 throw new IOException ("Unable to locate method " +_elemDesc); 261 } 262 } 263 else 264 { 265 String methodArgs = _elemDesc.substring(argsIndex+1, _elemDesc.length()-1); 267 Method [] methods = _elemClass.getDeclaredMethods(); 268 for (int i = 0; i < methods.length; i++) 269 { 270 if (methods[i].getName().equals(methodName) && 271 getMethodArgs(methods[i]).equals(methodArgs)) 272 { 273 _annotElem = methods[i]; 274 break; 275 } 276 } 277 278 if (_annotElem == null) 279 { 280 throw new IOException ("Unable to locate method " + _elemDesc); 281 } 282 } 283 } 284 } 285 } 286 287 transient private AnnotatedElement _annotElem; 290 291 private Class _elemClass; private String _elemDesc; } 294 | Popular Tags |