1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.struts.flow.sugar;
17
18 import org.mozilla.javascript.NativeJavaObject;
19 import org.mozilla.javascript.Scriptable;
20 import org.mozilla.javascript.Wrapper;
21 import org.apache.commons.beanutils.DynaBean;
22 import org.apache.commons.beanutils.DynaProperty;
23
24 import java.io.Serializable;
25
26 import java.util.Map;
27
28 /***
29 * Wrap a DynaBean for JavaScript. Currently only supports named,
30 * and not mapped or indexed properties for Javascript shortcuts.
31 * Mapped and indexed properties are still available through their
32 * get() methods.
33 */
34 public class ScriptableDynaBean extends JavaObjectWrapper implements Scriptable, Wrapper, Serializable {
35
36 private DynaBean bean;
37
38 public ScriptableDynaBean() {
39 super();
40 }
41
42 public ScriptableDynaBean(DynaBean bean) {
43 this.bean = bean;
44 }
45
46 public ScriptableDynaBean(Scriptable scope, Object javaObject, Class staticType, Map functions) {
47 super(scope, javaObject, staticType, functions);
48 if (javaObject instanceof DynaBean) {
49 this.bean = (DynaBean)javaObject;
50 } else {
51 throw new IllegalArgumentException("Passed object "+javaObject+" is not an instance of DynaBean");
52 }
53 }
54
55 public String getClassName() {
56 return "DynaBean";
57 }
58
59 public boolean has(String name, Scriptable start) {
60 return (super.has(name, start) || has(name));
61 }
62
63 /***
64 * no numeric properties
65 */
66 public boolean has(int index, Scriptable start) {
67 return false;
68 }
69
70 public Object get(String name, Scriptable start) {
71 if (super.has(name, start)) {
72 return super.get(name, start);
73 } else if (has(name)) {
74 return wrap(this.bean.get(name), start);
75 } else {
76 return Scriptable.NOT_FOUND;
77 }
78 }
79
80 private boolean has(String name) {
81 try {
82 Object val = this.bean.get(name);
83 return (val != null);
84 } catch (IllegalArgumentException ex) {
85
86 }
87 return false;
88 }
89
90 public Object get(int index, Scriptable start) {
91 return NOT_FOUND;
92 }
93
94 public void put(String name, Scriptable start, Object value) {
95 if (value instanceof NativeJavaObject) {
96 value = ((NativeJavaObject)value).unwrap();
97 }
98 bean.set(name, value);
99 }
100
101 public void put(int index, Scriptable start, Object value) {
102 }
103
104 public void delete(String id) {
105 bean.set(id, null);
106 }
107
108 public void delete(int index) {
109 }
110
111 public Scriptable getPrototype() {
112 return prototype;
113 }
114
115 public void setPrototype(Scriptable prototype) {
116 this.prototype = prototype;
117 }
118
119 public Scriptable getParentScope() {
120 return parent;
121 }
122
123 public void setParentScope(Scriptable parent) {
124 this.parent = parent;
125 }
126
127 /***
128 * The id array that is returned is of class DynaProperties,
129 * rather than the perhaps expected String.
130 */
131 public Object[] getIds() {
132 DynaProperty[] props = this.bean.getDynaClass().getDynaProperties();
133 String[] ids = new String[props.length];
134 for (int x=0; x < props.length; x++) {
135 ids[x] = props[x].getName();
136 }
137 return ids;
138 }
139
140 public Object getDefaultValue(Class typeHint) {
141 return this.bean.toString();
142 }
143
144 public boolean hasInstance(Scriptable value) {
145 Scriptable proto = value.getPrototype();
146 while (proto != null) {
147 if (proto.equals(this))
148 return true;
149 proto = proto.getPrototype();
150 }
151
152 return false;
153 }
154
155 /***
156 * Return the DynaBean that is wrapped by this class.
157 */
158 public Object unwrap() {
159 return this.bean;
160 }
161
162 }