1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jxpath.ri.model.beans;
18
19 import org.apache.commons.jxpath.AbstractFactory;
20 import org.apache.commons.jxpath.JXPathAbstractFactoryException;
21 import org.apache.commons.jxpath.JXPathContext;
22 import org.apache.commons.jxpath.JXPathIntrospector;
23 import org.apache.commons.jxpath.ri.QName;
24 import org.apache.commons.jxpath.ri.model.NodePointer;
25 import org.apache.commons.jxpath.util.ValueUtils;
26
27
28
29
30
31
32
33
34 public abstract class PropertyPointer extends NodePointer {
35 public static final int UNSPECIFIED_PROPERTY = Integer.MIN_VALUE;
36
37
38 protected int propertyIndex = UNSPECIFIED_PROPERTY;
39
40
41 protected Object bean;
42
43
44
45
46
47
48 public PropertyPointer(NodePointer parent) {
49 super(parent);
50 }
51
52
53
54
55
56 public int getPropertyIndex() {
57 return propertyIndex;
58 }
59
60
61
62
63
64 public void setPropertyIndex(int index) {
65 if (propertyIndex != index) {
66 propertyIndex = index;
67 setIndex(WHOLE_COLLECTION);
68 }
69 }
70
71
72
73
74
75 public Object getBean() {
76 if (bean == null) {
77 bean = getImmediateParentPointer().getNode();
78 }
79 return bean;
80 }
81
82 public QName getName() {
83 return new QName(null, getPropertyName());
84 }
85
86
87
88
89
90 public abstract String getPropertyName();
91
92
93
94
95
96 public abstract void setPropertyName(String propertyName);
97
98
99
100
101
102 public abstract int getPropertyCount();
103
104
105
106
107
108 public abstract String[] getPropertyNames();
109
110
111
112
113
114 protected abstract boolean isActualProperty();
115
116 public boolean isActual() {
117 if (!isActualProperty()) {
118 return false;
119 }
120
121 return super.isActual();
122 }
123
124 private static final Object UNINITIALIZED = new Object();
125
126 private Object value = UNINITIALIZED;
127
128 public Object getImmediateNode() {
129 if (value == UNINITIALIZED) {
130 value = index == WHOLE_COLLECTION ? ValueUtils.getValue(getBaseValue())
131 : ValueUtils.getValue(getBaseValue(), index);
132 }
133 return value;
134 }
135
136 public boolean isCollection() {
137 Object value = getBaseValue();
138 return value != null && ValueUtils.isCollection(value);
139 }
140
141 public boolean isLeaf() {
142 Object value = getNode();
143 return value == null || JXPathIntrospector.getBeanInfo(value.getClass()).isAtomic();
144 }
145
146
147
148
149
150
151 public int getLength() {
152 Object baseValue = getBaseValue();
153 return baseValue == null ? 1 : ValueUtils.getLength(baseValue);
154 }
155
156
157
158
159
160
161 public NodePointer getImmediateValuePointer() {
162 return NodePointer.newChildNodePointer(
163 (NodePointer) this.clone(),
164 getName(),
165 getImmediateNode());
166 }
167
168 public NodePointer createPath(JXPathContext context) {
169 if (getImmediateNode() == null) {
170 AbstractFactory factory = getAbstractFactory(context);
171 int inx = (index == WHOLE_COLLECTION ? 0 : index);
172 boolean success =
173 factory.createObject(
174 context,
175 this,
176 getBean(),
177 getPropertyName(),
178 inx);
179 if (!success) {
180 throw new JXPathAbstractFactoryException("Factory " + factory
181 + " could not create an object for path: " + asPath());
182 }
183 }
184 return this;
185 }
186
187 public NodePointer createPath(JXPathContext context, Object value) {
188
189 if (index != WHOLE_COLLECTION && index >= getLength()) {
190 createPath(context);
191 }
192 setValue(value);
193 return this;
194 }
195
196 public NodePointer createChild(
197 JXPathContext context,
198 QName name,
199 int index,
200 Object value) {
201 PropertyPointer prop = (PropertyPointer) clone();
202 if (name != null) {
203 prop.setPropertyName(name.toString());
204 }
205 prop.setIndex(index);
206 return prop.createPath(context, value);
207 }
208
209 public NodePointer createChild(
210 JXPathContext context,
211 QName name,
212 int index) {
213 PropertyPointer prop = (PropertyPointer) clone();
214 if (name != null) {
215 prop.setPropertyName(name.toString());
216 }
217 prop.setIndex(index);
218 return prop.createPath(context);
219 }
220
221 public int hashCode() {
222 return getImmediateParentPointer().hashCode() + propertyIndex + index;
223 }
224
225 public boolean equals(Object object) {
226 if (object == this) {
227 return true;
228 }
229
230 if (!(object instanceof PropertyPointer)) {
231 return false;
232 }
233
234 PropertyPointer other = (PropertyPointer) object;
235 if (parent != other.parent && (parent == null || !parent.equals(other.parent))) {
236 return false;
237 }
238
239 if (getPropertyIndex() != other.getPropertyIndex()
240 || !getPropertyName().equals(other.getPropertyName())) {
241 return false;
242 }
243
244 int iThis = (index == WHOLE_COLLECTION ? 0 : index);
245 int iOther = (other.index == WHOLE_COLLECTION ? 0 : other.index);
246 return iThis == iOther;
247 }
248
249 public int compareChildNodePointers(
250 NodePointer pointer1,
251 NodePointer pointer2) {
252 return getValuePointer().compareChildNodePointers(pointer1, pointer2);
253 }
254
255 }