001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jxpath.ri.model.beans;
017:
018: import org.apache.commons.jxpath.JXPathContext;
019: import org.apache.commons.jxpath.JXPathException;
020: import org.apache.commons.jxpath.ri.QName;
021: import org.apache.commons.jxpath.ri.model.NodePointer;
022:
023: /**
024: * @author Dmitri Plotnikov
025: * @version $Revision: 1.18 $ $Date: 2004/03/25 03:49:50 $
026: */
027: public class NullPropertyPointer extends PropertyPointer {
028:
029: private String propertyName = "*";
030: private boolean byNameAttribute = false;
031:
032: /**
033: */
034: public NullPropertyPointer(NodePointer parent) {
035: super (parent);
036: }
037:
038: public QName getName() {
039: return new QName(propertyName);
040: }
041:
042: public void setPropertyIndex(int index) {
043: }
044:
045: public int getLength() {
046: return 0;
047: }
048:
049: public Object getBaseValue() {
050: return null;
051: }
052:
053: public Object getImmediateNode() {
054: return null;
055: }
056:
057: public boolean isLeaf() {
058: return true;
059: }
060:
061: public NodePointer getValuePointer() {
062: return new NullPointer(this , new QName(getPropertyName()));
063: }
064:
065: protected boolean isActualProperty() {
066: return false;
067: }
068:
069: public boolean isActual() {
070: return false;
071: }
072:
073: public boolean isContainer() {
074: return true;
075: }
076:
077: public void setValue(Object value) {
078: if (parent == null || parent.isContainer()) {
079: throw new JXPathException("Cannot set property " + asPath()
080: + ", the target object is null");
081: } else if (parent instanceof PropertyOwnerPointer
082: && ((PropertyOwnerPointer) parent)
083: .isDynamicPropertyDeclarationSupported()) {
084: // If the parent property owner can create
085: // a property automatically - let it do so
086: PropertyPointer propertyPointer = ((PropertyOwnerPointer) parent)
087: .getPropertyPointer();
088: propertyPointer.setPropertyName(propertyName);
089: propertyPointer.setValue(value);
090: } else {
091: throw new JXPathException("Cannot set property " + asPath()
092: + ", path does not match a changeable location");
093: }
094: }
095:
096: public NodePointer createPath(JXPathContext context) {
097: NodePointer newParent = parent.createPath(context);
098: if (isAttribute()) {
099: return newParent.createAttribute(context, getName());
100: } else {
101: // Consider these two use cases:
102: // 1. The parent pointer of NullPropertyPointer is
103: // a PropertyOwnerPointer other than NullPointer. When we call
104: // createPath on it, it most likely returns itself. We then
105: // take a PropertyPointer from it and get the PropertyPointer
106: // to expand the collection for the corresponsing property.
107: //
108: // 2. The parent pointer of NullPropertyPointer is a NullPointer.
109: // When we call createPath, it may return a PropertyOwnerPointer
110: // or it may return anything else, like a DOMNodePointer.
111: // In the former case we need to do exactly what we did in use
112: // case 1. In the latter case, we simply request that the
113: // non-property pointer expand the collection by itself.
114: if (newParent instanceof PropertyOwnerPointer) {
115: PropertyOwnerPointer pop = (PropertyOwnerPointer) newParent;
116: newParent = pop.getPropertyPointer();
117: }
118: return newParent
119: .createChild(context, getName(), getIndex());
120: }
121: }
122:
123: public NodePointer createPath(JXPathContext context, Object value) {
124: NodePointer newParent = parent.createPath(context);
125: if (isAttribute()) {
126: NodePointer pointer = newParent.createAttribute(context,
127: getName());
128: pointer.setValue(value);
129: return pointer;
130: } else {
131: if (newParent instanceof PropertyOwnerPointer) {
132: PropertyOwnerPointer pop = (PropertyOwnerPointer) newParent;
133: newParent = pop.getPropertyPointer();
134: }
135: return newParent.createChild(context, getName(), index,
136: value);
137: }
138: }
139:
140: public NodePointer createChild(JXPathContext context, QName name,
141: int index) {
142: return createPath(context).createChild(context, name, index);
143: }
144:
145: public NodePointer createChild(JXPathContext context, QName name,
146: int index, Object value) {
147: return createPath(context).createChild(context, name, index,
148: value);
149: }
150:
151: public String getPropertyName() {
152: return propertyName;
153: }
154:
155: public void setPropertyName(String propertyName) {
156: this .propertyName = propertyName;
157: }
158:
159: public void setNameAttributeValue(String attributeValue) {
160: this .propertyName = attributeValue;
161: byNameAttribute = true;
162: }
163:
164: public boolean isCollection() {
165: return getIndex() != WHOLE_COLLECTION;
166: }
167:
168: public int getPropertyCount() {
169: return 0;
170: }
171:
172: public String[] getPropertyNames() {
173: return new String[0];
174: }
175:
176: public String asPath() {
177: if (!byNameAttribute) {
178: return super .asPath();
179: } else {
180: StringBuffer buffer = new StringBuffer();
181: buffer.append(getImmediateParentPointer().asPath());
182: buffer.append("[@name='");
183: buffer.append(escape(getPropertyName()));
184: buffer.append("']");
185: if (index != WHOLE_COLLECTION) {
186: buffer.append('[').append(index + 1).append(']');
187: }
188: return buffer.toString();
189: }
190: }
191:
192: private String escape(String string) {
193: int index = string.indexOf('\'');
194: while (index != -1) {
195: string = string.substring(0, index) + "'"
196: + string.substring(index + 1);
197: index = string.indexOf('\'');
198: }
199: index = string.indexOf('\"');
200: while (index != -1) {
201: string = string.substring(0, index) + """
202: + string.substring(index + 1);
203: index = string.indexOf('\"');
204: }
205: return string;
206: }
207: }
|