1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.ri.model.beans;
19
20 import org.apache.commons.jxpath.AbstractFactory;
21 import org.apache.commons.jxpath.JXPathAbstractFactoryException;
22 import org.apache.commons.jxpath.JXPathContext;
23 import org.apache.commons.jxpath.JXPathInvalidAccessException;
24 import org.apache.commons.jxpath.ri.QName;
25 import org.apache.commons.jxpath.ri.model.NodePointer;
26
27
28
29
30 public class NullPropertyPointer extends PropertyPointer {
31
32 private static final long serialVersionUID = 5296593071854982754L;
33
34
35
36
37 private String propertyName = "*";
38
39
40
41
42 private boolean byNameAttribute;
43
44
45
46
47
48
49 public NullPropertyPointer(final NodePointer parent) {
50 super(parent);
51 }
52
53 @Override
54 public String asPath() {
55 if (!byNameAttribute) {
56 return super.asPath();
57 }
58 final StringBuilder buffer = new StringBuilder();
59 buffer.append(getImmediateParentPointer().asPath());
60 buffer.append("[@name='");
61 buffer.append(escape(getPropertyName()));
62 buffer.append("']");
63 if (index != WHOLE_COLLECTION) {
64 buffer.append('[').append(index + 1).append(']');
65 }
66 return buffer.toString();
67 }
68
69
70
71
72
73
74
75 private JXPathAbstractFactoryException createBadFactoryException(final AbstractFactory factory) {
76 return new JXPathAbstractFactoryException("Factory " + factory + " reported success creating object for path: " + asPath()
77 + " but object was null. Terminating to avoid stack recursion.");
78 }
79
80 @Override
81 public NodePointer createChild(final JXPathContext context, final QName qName, final int index) {
82 return createPath(context).createChild(context, qName, index);
83 }
84
85 @Override
86 public NodePointer createChild(final JXPathContext context, final QName qName, final int index, final Object value) {
87 return createPath(context).createChild(context, qName, index, value);
88 }
89
90 @Override
91 public NodePointer createPath(final JXPathContext context) {
92 NodePointer newParent = parent.createPath(context);
93 if (isAttribute()) {
94 return newParent.createAttribute(context, getName());
95 }
96 if (parent instanceof NullPointer && parent.equals(newParent)) {
97 throw createBadFactoryException(context.getFactory());
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111
112 if (newParent instanceof PropertyOwnerPointer) {
113 final PropertyOwnerPointer pop = (PropertyOwnerPointer) newParent;
114 newParent = pop.getPropertyPointer();
115 }
116 return newParent.createChild(context, getName(), getIndex());
117 }
118
119 @Override
120 public NodePointer createPath(final JXPathContext context, final Object value) {
121 NodePointer newParent = parent.createPath(context);
122 if (isAttribute()) {
123 final NodePointer pointer = newParent.createAttribute(context, getName());
124 pointer.setValue(value);
125 return pointer;
126 }
127 if (parent instanceof NullPointer && parent.equals(newParent)) {
128 throw createBadFactoryException(context.getFactory());
129 }
130 if (newParent instanceof PropertyOwnerPointer) {
131 final PropertyOwnerPointer pop = (PropertyOwnerPointer) newParent;
132 newParent = pop.getPropertyPointer();
133 }
134 return newParent.createChild(context, getName(), index, value);
135 }
136
137 @Override
138 public Object getBaseValue() {
139 return null;
140 }
141
142 @Override
143 public Object getImmediateNode() {
144 return null;
145 }
146
147 @Override
148 public int getLength() {
149 return 0;
150 }
151
152 @Override
153 public QName getName() {
154 return new QName(propertyName);
155 }
156
157 @Override
158 public int getPropertyCount() {
159 return 0;
160 }
161
162 @Override
163 public String getPropertyName() {
164 return propertyName;
165 }
166
167 @Override
168 public String[] getPropertyNames() {
169 return new String[0];
170 }
171
172 @Override
173 public NodePointer getValuePointer() {
174 return new NullPointer(this, new QName(getPropertyName()));
175 }
176
177 @Override
178 public boolean isActual() {
179 return false;
180 }
181
182 @Override
183 protected boolean isActualProperty() {
184 return false;
185 }
186
187 @Override
188 public boolean isCollection() {
189 return getIndex() != WHOLE_COLLECTION;
190 }
191
192 @Override
193 public boolean isContainer() {
194 return true;
195 }
196
197 @Override
198 public boolean isLeaf() {
199 return true;
200 }
201
202
203
204
205
206
207 public void setNameAttributeValue(final String attributeValue) {
208 this.propertyName = attributeValue;
209 byNameAttribute = true;
210 }
211
212 @Override
213 public void setPropertyIndex(final int index) {
214 }
215
216 @Override
217 public void setPropertyName(final String propertyName) {
218 this.propertyName = propertyName;
219 }
220
221 @Override
222 public void setValue(final Object value) {
223 if (parent == null || parent.isContainer()) {
224 throw new JXPathInvalidAccessException("Cannot set property " + asPath() + ", the target object is null");
225 }
226 if (!(parent instanceof PropertyOwnerPointer) || !((PropertyOwnerPointer) parent).isDynamicPropertyDeclarationSupported()) {
227 throw new JXPathInvalidAccessException("Cannot set property " + asPath() + ", path does not match a changeable location");
228 }
229
230
231 final PropertyPointer propertyPointer = ((PropertyOwnerPointer) parent).getPropertyPointer();
232 propertyPointer.setPropertyName(propertyName);
233 propertyPointer.setValue(value);
234 }
235 }