View Javadoc

1   /*
2    * Copyright 1999-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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              // Do nothing as we don't care if it complains
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 }