1 16 17 package org.apache.cocoon.forms.flow.javascript; 18 import org.apache.cocoon.forms.formmodel.AggregateField; 19 import org.apache.cocoon.forms.formmodel.BooleanField; 20 import org.apache.cocoon.forms.formmodel.Field; 21 import org.apache.cocoon.forms.formmodel.MultiValueField; 22 import org.apache.cocoon.forms.formmodel.Output; 23 import org.apache.cocoon.forms.formmodel.Repeater; 24 import org.apache.cocoon.forms.formmodel.Widget; 25 import org.apache.cocoon.forms.formmodel.WidgetState; 26 import org.mozilla.javascript.Context; 27 import org.mozilla.javascript.NativeArray; 28 import org.mozilla.javascript.Scriptable; 29 import org.mozilla.javascript.ScriptableObject; 30 import org.mozilla.javascript.Undefined; 31 import org.mozilla.javascript.Wrapper; 32 33 import java.util.Collection ; 34 35 39 public class ScriptableWidget extends ScriptableObject { 40 41 Widget delegate; 42 43 public String getClassName() { 44 return "Widget"; 45 } 46 47 public ScriptableWidget() { 48 } 49 50 public ScriptableWidget(Object widget) { 51 this.delegate = (Widget)unwrap(widget); 52 } 53 54 private Object unwrap(Object obj) { 55 if (obj == Undefined.instance) { 56 return null; 57 } 58 if (obj instanceof Wrapper) { 59 return ((Wrapper)obj).unwrap(); 60 } 61 return obj; 62 } 63 64 private ScriptableWidget wrap(Widget w) { 65 ScriptableWidget result = new ScriptableWidget(w); 66 result.setPrototype(getClassPrototype(this, "Widget")); 67 result.setParentScope(getParentScope()); 68 return result; 69 } 70 71 public boolean has(String id, Scriptable start) { 72 if (delegate instanceof Repeater) { 73 if (id.equals("length")) { 74 return true; 75 } 76 } else if (delegate instanceof MultiValueField) { 77 if (id.equals("length")) { 78 return true; 79 } 80 } else if (delegate != null) { 81 Widget sub = delegate.lookupWidget(id); 82 if (sub != null) { 83 return true; 84 } 85 } 86 return super.has(id, start); 87 } 88 89 public boolean has(int index, Scriptable start) { 90 if (delegate instanceof Repeater) { 91 Repeater repeater = (Repeater)delegate; 92 return index >= 0 && index < repeater.getSize(); 93 } 94 if (delegate instanceof MultiValueField) { 95 Object [] values = (Object [])delegate.getValue(); 96 return index >= 0 && index < values.length; 97 } 98 return super.has(index, start); 99 } 100 101 public Object get(String id, Scriptable start) { 102 if (delegate instanceof Repeater) { 103 if (id.equals("length")) { 104 Repeater repeater = (Repeater)delegate; 105 return new Integer (repeater.getSize()); 106 } 107 } else if (delegate instanceof MultiValueField) { 108 if (id.equals("length")) { 109 Object [] values = (Object [])delegate.getValue(); 110 return new Integer (values.length); 111 } 112 } else if (delegate != null) { 113 Widget sub = delegate.lookupWidget(id); 114 if (sub != null) { 115 if (sub instanceof Field || 116 sub instanceof BooleanField || 117 sub instanceof AggregateField || 118 sub instanceof Output) { 119 return sub.getValue(); 120 } 121 return wrap(sub); 122 } 123 } 124 return super.get(id, start); 125 } 126 127 public Object get(int index, Scriptable start) { 128 if (delegate instanceof Repeater) { 129 Repeater repeater = (Repeater)delegate; 130 if (index >= 0) { 131 while (index >= repeater.getSize()) { 132 repeater.addRow(); 133 } 134 return wrap(repeater.getRow(index)); 135 } 136 } 137 if (delegate instanceof MultiValueField) { 138 Object [] values = (Object [])delegate.getValue(); 139 if (index >= 0 && index < values.length) { 140 return values[index]; 141 } else { 142 return NOT_FOUND; 143 } 144 } 145 return super.get(index, start); 146 } 147 148 public void delete(String id) { 149 super.delete(id); 150 } 151 152 public void delete(int index) { 153 if (delegate instanceof Repeater) { 154 Repeater repeater = (Repeater)delegate; 155 if (index >= 0 && index < repeater.getSize()) { 156 repeater.removeRow(index); 157 return; 158 } 159 } else if (delegate instanceof MultiValueField) { 160 MultiValueField field = (MultiValueField)delegate; 161 Object [] values = (Object [])field.getValue(); 162 if (values != null && values.length > index) { 163 Object [] newValues = new Object [values.length-1]; 164 int i; 165 for (i = 0; i < index; i++) { 166 newValues[i] = values[i]; 167 } 168 i++; 169 for (;i < values.length;i++) { 170 newValues[i-1] = values[i]; 171 } 172 field.setValues(newValues); 173 } 174 return; 175 } 176 super.delete(index); 177 } 178 179 public void put(String id, Scriptable start, Object value) { 180 if (delegate instanceof Repeater) { 181 if (id.equals("length")) { 182 int len = (int)Context.toNumber(value); 183 Repeater repeater = (Repeater)delegate; 184 int size = repeater.getSize(); 185 if (size > len) { 186 while (repeater.getSize() > len) { 187 repeater.removeRow(repeater.getSize() -1); 188 } 189 } else { 190 for (int i = size; i < len; ++i) { 191 repeater.addRow(); 192 } 193 } 194 } 195 } else if (delegate != null) { 196 Widget sub = delegate.lookupWidget(id); 197 if (sub instanceof Field) { 198 Field field = (Field)sub; 199 value = unwrap(value); 200 if (value instanceof Double ) { 201 Class typeClass = 203 field.getFieldDefinition().getDatatype().getTypeClass(); 204 if (typeClass == long.class || typeClass == Long .class) { 205 value = new Long (((Number )value).longValue()); 206 } else if (typeClass == int.class || typeClass == Integer .class) { 207 value = new Integer (((Number )value).intValue()); 208 } else if (typeClass == float.class || typeClass == Float .class) { 209 value = new Float (((Number )value).floatValue()); 210 } else if (typeClass == short.class || typeClass == Short .class) { 211 value = new Short (((Number )value).shortValue()); 212 } 213 } 214 field.setValue(value); 215 return; 216 } else if (sub instanceof BooleanField) { 217 BooleanField field = (BooleanField)sub; 218 value = unwrap(value); 219 field.setValue(value); 220 } else if (sub instanceof Output) { 221 Output field = (Output)sub; 222 value = unwrap(value); 223 field.setValue(value); 224 } else if (sub instanceof Repeater) { 225 Repeater repeater = (Repeater)sub; 226 if (value instanceof NativeArray) { 227 NativeArray arr = (NativeArray)value; 228 Object length = getProperty(arr, "length"); 229 int len = ((Number )length).intValue(); 230 for (int i = repeater.getSize(); i >= len; --i) { 231 repeater.removeRow(i); 232 } 233 for (int i = 0; i < len; i++) { 234 Object elemValue = getProperty(arr, i); 235 if (elemValue instanceof Scriptable) { 236 Scriptable s = (Scriptable)elemValue; 237 Object [] ids = s.getIds(); 238 ScriptableWidget wid = wrap(repeater.getRow(i)); 239 for (int j = 0; j < ids.length; j++) { 240 String idStr = ids[j].toString(); 241 wid.put(idStr, wid, getProperty(s, idStr)); 242 } 243 } 244 } 245 return; 246 } 247 } else if (sub instanceof MultiValueField) { 248 MultiValueField field = (MultiValueField)sub; 249 Object [] values = null; 250 if (value instanceof NativeArray) { 251 NativeArray arr = (NativeArray)value; 252 Object length = getProperty(arr, "length"); 253 int len = ((Number )length).intValue(); 254 values = new Object [len]; 255 for (int i = 0; i < len; i++) { 256 Object elemValue = getProperty(arr, i); 257 values[i] = unwrap(elemValue); 258 } 259 } else if (value instanceof Object []) { 260 values = (Object [])value; 261 } else if (value instanceof Collection ) { 262 values = ((Collection )value).toArray(); 263 } 264 field.setValues(values); 265 } else { 266 if (value instanceof Scriptable) { 267 Scriptable s = (Scriptable)value; 268 Object [] ids = s.getIds(); 269 ScriptableWidget wid = wrap(sub); 270 for (int j = 0; j < ids.length; j++) { 271 String idStr = ids[j].toString(); 272 wid.put(idStr, wid, getProperty(s, idStr)); 273 } 274 return; 275 } 276 } 277 } 278 super.put(id, start, value); 279 } 280 281 public String jsGet_id() { 282 return delegate.getId(); 283 } 284 285 public WidgetState jsGet_state() { 286 return delegate.getState(); 287 } 288 289 public void jsSet_state(Object stateObj) { 290 Object obj = unwrap(stateObj); 291 WidgetState state = null; 292 293 if (obj instanceof String ) { 294 state = WidgetState.stateForName((String )obj); 295 } else if (obj instanceof WidgetState) { 296 state = (WidgetState)obj; 297 } 298 299 if (state == null) { 300 throw new IllegalArgumentException ("Invalid value for widgetState " + stateObj); 301 } 302 303 delegate.setState(state); 304 } 305 306 public Object jsGet_parent() { 307 if (delegate != null) { 308 return wrap(delegate.getParent()); 309 } 310 return Undefined.instance; 311 } 312 313 public boolean jsFunction_equals(Object other) { 314 if (other instanceof ScriptableWidget) { 315 ScriptableWidget otherWidget = (ScriptableWidget)other; 316 return delegate.equals(otherWidget.delegate); 317 } 318 return false; 319 } 320 321 public void jsFunction_remove(int index) { 322 delete(index); 323 } 324 325 } 326 | Popular Tags |