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 java.util.Locale;
20
21 import org.apache.commons.jxpath.JXPathInvalidAccessException;
22 import org.apache.commons.jxpath.ri.Compiler;
23 import org.apache.commons.jxpath.ri.QName;
24 import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
25 import org.apache.commons.jxpath.ri.compiler.NodeTest;
26 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
27 import org.apache.commons.jxpath.ri.model.NodeIterator;
28 import org.apache.commons.jxpath.ri.model.NodePointer;
29 import org.apache.commons.jxpath.util.ValueUtils;
30
31
32
33
34
35
36
37
38 public abstract class PropertyOwnerPointer extends NodePointer {
39 private static final Object UNINITIALIZED = new Object();
40
41 private Object value = UNINITIALIZED;
42
43 public NodeIterator childIterator(NodeTest test, boolean reverse,
44 NodePointer startWith) {
45 if (test == null) {
46 return createNodeIterator(null, reverse, startWith);
47 }
48 if (test instanceof NodeNameTest) {
49 NodeNameTest nodeNameTest = (NodeNameTest) test;
50 QName testName = nodeNameTest.getNodeName();
51 if (isValidProperty(testName)) {
52 return createNodeIterator(nodeNameTest.isWildcard() ? null
53 : testName.toString(), reverse, startWith);
54 }
55 return null;
56 }
57 return test instanceof NodeTypeTest && ((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE
58 ? createNodeIterator(null, reverse, startWith) : null;
59 }
60
61
62
63
64
65
66
67
68 public NodeIterator createNodeIterator(String property, boolean reverse,
69 NodePointer startWith) {
70 return new PropertyIterator(this, property, reverse, startWith);
71 }
72
73 public NodeIterator attributeIterator(QName name) {
74 return new BeanAttributeIterator(this, name);
75 }
76
77
78
79
80
81
82 protected PropertyOwnerPointer(NodePointer parent, Locale locale) {
83 super(parent, locale);
84 }
85
86
87
88
89
90 protected PropertyOwnerPointer(NodePointer parent) {
91 super(parent);
92 }
93
94 public void setIndex(int index) {
95 if (this.index != index) {
96 super.setIndex(index);
97 value = UNINITIALIZED;
98 }
99 }
100
101 public Object getImmediateNode() {
102 if (value == UNINITIALIZED) {
103 value = index == WHOLE_COLLECTION ? ValueUtils.getValue(getBaseValue())
104 : ValueUtils.getValue(getBaseValue(), index);
105 }
106 return value;
107 }
108
109 public abstract QName getName();
110
111
112
113
114
115
116
117 public boolean isValidProperty(QName name) {
118 return isDefaultNamespace(name.getPrefix());
119 }
120
121
122
123
124
125
126 public void setValue(Object value) {
127 this.value = value;
128 if (parent != null) {
129 if (parent.isContainer()) {
130 parent.setValue(value);
131 }
132 else {
133 if (index == WHOLE_COLLECTION) {
134 throw new UnsupportedOperationException(
135 "Cannot setValue of an object that is not "
136 + "some other object's property");
137 }
138 throw new JXPathInvalidAccessException(
139 "The specified collection element does not exist: " + this);
140 }
141 }
142 else {
143 throw new UnsupportedOperationException(
144 "Cannot replace the root object");
145 }
146 }
147
148
149
150
151
152 public void remove() {
153 this.value = null;
154 if (parent != null) {
155 parent.remove();
156 }
157 else {
158 throw new UnsupportedOperationException(
159 "Cannot remove an object that is not "
160 + "some other object's property or a collection element");
161 }
162 }
163
164
165
166
167
168 public abstract PropertyPointer getPropertyPointer();
169
170
171
172
173
174
175
176 public boolean isDynamicPropertyDeclarationSupported() {
177 return false;
178 }
179
180 public int compareChildNodePointers(NodePointer pointer1,
181 NodePointer pointer2) {
182 int r = pointer1.getName().toString().compareTo(pointer2.getName().toString());
183 return r == 0 ? pointer1.getIndex() - pointer2.getIndex() : r;
184 }
185 }