1 18 package org.apache.beehive.netui.script.el.tokens; 19 20 import java.lang.reflect.Array ; 21 import java.lang.reflect.Field ; 22 import java.lang.reflect.Method ; 23 import java.util.List ; 24 import java.util.Map ; 25 26 import org.apache.beehive.netui.util.internal.cache.PropertyCache; 27 import org.apache.beehive.netui.util.logging.Logger; 28 import org.apache.beehive.netui.script.el.util.ParseUtils; 29 30 33 public abstract class ExpressionToken { 34 35 private static final Logger LOGGER = Logger.getInstance(ArrayIndexToken.class); 36 37 private static final PropertyCache PROPERTY_CACHE = new PropertyCache(); 38 39 public abstract Object evaluate(Object value); 40 41 public abstract void update(Object root, Object newValue); 42 43 public abstract String getTokenString(); 44 45 46 51 protected final Object mapLookup(Map map, Object identifier) { 52 if(LOGGER.isDebugEnabled()) 53 LOGGER.debug("mapLookup: " + identifier); 54 return map.get(identifier); 55 } 56 57 protected final Object beanLookup(Object bean, Object identifier) { 58 if(LOGGER.isDebugEnabled()) 59 LOGGER.debug("beanLookup: " + identifier); 60 61 return ParseUtils.getProperty(bean, identifier.toString(), PROPERTY_CACHE); 62 } 63 64 protected final Object listLookup(List list, int index) { 65 if(LOGGER.isDebugEnabled()) 66 LOGGER.debug("listLookup: " + index); 67 68 return list.get(index); 69 } 70 71 protected final Object arrayLookup(Object array, int index) { 72 if(LOGGER.isDebugEnabled()) 73 LOGGER.debug("arrayLookup: " + index); 74 75 return Array.get(array, index); 76 } 77 78 protected final void mapUpdate(Map map, Object identifier, Object value) { 79 Object converted = value; 80 81 Object o = map.get(identifier); 82 if(o != null) { 83 Class type = o.getClass(); 84 value = ParseUtils.convertType(value, type); 85 } 86 87 map.put(identifier, value); 88 } 89 90 protected final void arrayUpdate(Object array, int index, Object value) { 91 Object converted = value; 92 93 Class elementType = array.getClass().getComponentType(); 94 if(!elementType.isAssignableFrom(value.getClass())) { 95 converted = ParseUtils.convertType(value, elementType); 96 } 97 98 try { 99 Array.set(array, index, converted); 100 } catch(Exception e) { 101 String msg = "An error occurred setting a value at index \"" + index + "\" on an array with component types \"" + 102 elementType + "\". Cause: " + e.toString(); 103 104 if(LOGGER.isErrorEnabled()) LOGGER.error(msg); 105 throw new RuntimeException (msg); 106 } 107 } 108 109 protected final void listUpdate(List list, int index, Object value) { 110 Object converted = value; 111 112 if(list.size() > index) { 113 Object o = list.get(index); 114 if(o != null) { 116 Class itemType = o.getClass(); 117 converted = ParseUtils.convertType(value, itemType); 118 } 119 120 list.set(index, value); 121 } else { 122 String msg = "An error occurred setting a value at index \"" + index + "\" because the list is " + 143 (list != null ? (" of size " + list.size()) : "null") + ". " + 144 "Be sure to allocate enough items in the List to accomodate any updates which may occur against the list."; 145 146 if(LOGGER.isErrorEnabled()) LOGGER.error(msg); 147 148 throw new RuntimeException (msg); 149 } 150 } 151 152 protected final void beanUpdate(Object bean, Object identifier, Object value) { 153 if(LOGGER.isDebugEnabled()) LOGGER.debug("Update \"" + bean + "\" type property \"" + identifier + "\""); 154 155 String id = identifier.toString(); 156 Class beanType = bean.getClass(); 157 Class propType = PROPERTY_CACHE.getPropertyType(beanType, id); 158 if(propType != null) { 159 try { 160 if(java.util.List .class.isAssignableFrom(propType)) { 161 Method lm = PROPERTY_CACHE.getPropertyGetter(beanType, id); 162 if(lm != null) { 163 List list = (List )lm.invoke(bean, (Object [])null); 164 applyValuesToList(value, list); 165 return; 166 } 167 } else { 168 Method m = PROPERTY_CACHE.getPropertySetter(beanType, id); 169 170 if(m != null) { 171 if(LOGGER.isDebugEnabled()) 172 LOGGER.debug("Apply value to property via method: " + m); 173 174 Class targetType = m.getParameterTypes()[0]; 175 Object converted = ParseUtils.convertType(value, targetType); 176 177 m.invoke(bean, new Object []{converted}); 178 return; 179 } 180 } 181 } catch(Exception e) { 182 String msg = "Could not update proprety named \"" + id + "\" on bean of type \"" + beanType + "\". Cause: " + e; 183 if(LOGGER.isErrorEnabled()) 184 LOGGER.error(msg, e); 185 throw new RuntimeException (msg, e); 186 } 187 } 188 189 String msg = "Could not update expression because a public JavaBean setter for the property \"" + identifier + "\" could not be found."; 190 LOGGER.error(msg); 191 throw new RuntimeException (msg); 192 } 193 194 protected final int parseIndex(String identifier) { 195 try { 196 return Integer.parseInt(identifier); 197 } catch(Exception e) { 198 String msg = "Error performing an array look-up with the index \"" + identifier + "\". Cause: " + e; 199 200 if(LOGGER.isDebugEnabled()) 201 LOGGER.debug(msg, e); 202 203 throw new RuntimeException (msg, e); 204 } 205 } 206 207 private static final void applyValuesToList(Object value, List list) { 208 if(list == null) { 209 String msg = "Can not add a value to a null java.util.List"; 210 LOGGER.error(msg); 211 throw new RuntimeException (msg); 212 } 213 214 if(value instanceof String []) { 215 String [] ary = (String [])value; 216 for(int i = 0; i < ary.length; i++) { 217 list.add(ary[i]); 218 } 219 } else if(value instanceof String ) { 220 list.add(value); 221 } 222 else list.add(value); 224 } 225 } 226 | Popular Tags |