1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jxpath.ri.model.dynabeans;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21
22 import org.apache.commons.beanutils.DynaBean;
23 import org.apache.commons.beanutils.DynaClass;
24 import org.apache.commons.beanutils.DynaProperty;
25 import org.apache.commons.jxpath.JXPathTypeConversionException;
26 import org.apache.commons.jxpath.ri.model.NodePointer;
27 import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
28 import org.apache.commons.jxpath.util.TypeUtils;
29 import org.apache.commons.jxpath.util.ValueUtils;
30
31
32
33
34
35
36
37
38 public class DynaBeanPropertyPointer extends PropertyPointer {
39 private static final String CLASS = "class";
40
41 private DynaBean dynaBean;
42 private String name;
43 private String[] names;
44
45 private static final long serialVersionUID = 2094421509141267239L;
46
47
48
49
50
51
52 public DynaBeanPropertyPointer(NodePointer parent, DynaBean dynaBean) {
53 super(parent);
54 this.dynaBean = dynaBean;
55 }
56
57 public Object getBaseValue() {
58 return dynaBean.get(getPropertyName());
59 }
60
61
62
63
64
65 public boolean isContainer() {
66 return true;
67 }
68
69 public int getPropertyCount() {
70 return getPropertyNames().length;
71 }
72
73 public String[] getPropertyNames() {
74
75 if (names == null) {
76 DynaClass dynaClass = dynaBean.getDynaClass();
77 DynaProperty[] dynaProperties = dynaClass.getDynaProperties();
78 ArrayList properties = new ArrayList(dynaProperties.length);
79 for (int i = 0; i < dynaProperties.length; i++) {
80 String name = dynaProperties[i].getName();
81 if (!CLASS.equals(name)) {
82 properties.add(name);
83 }
84 }
85 names = (String[]) properties.toArray(new String[properties.size()]);
86 Arrays.sort(names);
87 }
88 return names;
89 }
90
91
92
93
94
95
96 public String getPropertyName() {
97 if (name == null) {
98 String[] names = getPropertyNames();
99 name = propertyIndex >= 0 && propertyIndex < names.length ? names[propertyIndex] : "*";
100 }
101 return name;
102 }
103
104
105
106
107
108 public void setPropertyName(String propertyName) {
109 setPropertyIndex(UNSPECIFIED_PROPERTY);
110 this.name = propertyName;
111 }
112
113
114
115
116
117
118 public int getPropertyIndex() {
119 if (propertyIndex == UNSPECIFIED_PROPERTY) {
120 String[] names = getPropertyNames();
121 for (int i = 0; i < names.length; i++) {
122 if (names[i].equals(name)) {
123 propertyIndex = i;
124 name = null;
125 break;
126 }
127 }
128 }
129 return super.getPropertyIndex();
130 }
131
132
133
134
135
136
137 public void setPropertyIndex(int index) {
138 if (propertyIndex != index) {
139 super.setPropertyIndex(index);
140 name = null;
141 }
142 }
143
144
145
146
147
148
149
150
151 public Object getImmediateNode() {
152 String name = getPropertyName();
153 if (name.equals("*")) {
154 return null;
155 }
156
157 Object value;
158 if (index == WHOLE_COLLECTION) {
159 value = ValueUtils.getValue(dynaBean.get(name));
160 }
161 else if (isIndexedProperty()) {
162
163
164
165
166 try {
167 value = ValueUtils.getValue(dynaBean.get(name, index));
168 }
169 catch (ArrayIndexOutOfBoundsException ex) {
170 value = null;
171 }
172 catch (IllegalArgumentException ex) {
173 value = dynaBean.get(name);
174 value = ValueUtils.getValue(value, index);
175 }
176 }
177 else {
178 value = dynaBean.get(name);
179 if (ValueUtils.isCollection(value)) {
180 value = ValueUtils.getValue(value, index);
181 }
182 else if (index != 0) {
183 value = null;
184 }
185 }
186 return value;
187 }
188
189
190
191
192
193 protected boolean isActualProperty() {
194 DynaClass dynaClass = dynaBean.getDynaClass();
195 return dynaClass.getDynaProperty(getPropertyName()) != null;
196 }
197
198
199
200
201
202 protected boolean isIndexedProperty() {
203 DynaClass dynaClass = dynaBean.getDynaClass();
204 DynaProperty property = dynaClass.getDynaProperty(name);
205 return property.isIndexed();
206 }
207
208
209
210
211
212
213
214 public void setValue(Object value) {
215 setValue(index, value);
216 }
217
218 public void remove() {
219 if (index == WHOLE_COLLECTION) {
220 dynaBean.set(getPropertyName(), null);
221 }
222 else if (isIndexedProperty()) {
223 dynaBean.set(getPropertyName(), index, null);
224 }
225 else if (isCollection()) {
226 Object collection = ValueUtils.remove(getBaseValue(), index);
227 dynaBean.set(getPropertyName(), collection);
228 }
229 else if (index == 0) {
230 dynaBean.set(getPropertyName(), null);
231 }
232 }
233
234
235
236
237
238
239 private void setValue(int index, Object value) {
240 if (index == WHOLE_COLLECTION) {
241 dynaBean.set(getPropertyName(), convert(value, false));
242 }
243 else if (isIndexedProperty()) {
244 dynaBean.set(getPropertyName(), index, convert(value, true));
245 }
246 else {
247 Object baseValue = dynaBean.get(getPropertyName());
248 ValueUtils.setValue(baseValue, index, value);
249 }
250 }
251
252
253
254
255
256
257
258
259 private Object convert(Object value, boolean element) {
260 DynaClass dynaClass = dynaBean.getDynaClass();
261 DynaProperty property = dynaClass.getDynaProperty(getPropertyName());
262 Class type = property.getType();
263 if (element) {
264 if (type.isArray()) {
265 type = type.getComponentType();
266 }
267 else {
268 return value;
269 }
270 }
271
272 try {
273 return TypeUtils.convert(value, type);
274 }
275 catch (Exception ex) {
276 String string = value == null ? "null" : value.getClass().getName();
277 throw new JXPathTypeConversionException(
278 "Cannot convert value of class " + string + " to type "
279 + type, ex);
280 }
281 }
282 }