KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > ri > model > beans > PropertyPointer


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.jxpath.ri.model.beans;
17
18 import org.apache.commons.jxpath.AbstractFactory;
19 import org.apache.commons.jxpath.JXPathContext;
20 import org.apache.commons.jxpath.JXPathException;
21 import org.apache.commons.jxpath.JXPathIntrospector;
22 import org.apache.commons.jxpath.ri.QName;
23 import org.apache.commons.jxpath.ri.model.NodePointer;
24 import org.apache.commons.jxpath.util.ValueUtils;
25
26 /**
27  * A pointer allocated by a PropertyOwnerPointer to represent the value of
28  * a property of the parent object.
29  *
30  * @author Dmitri Plotnikov
31  * @version $Revision: 1.14 $ $Date: 2004/04/04 22:06:36 $
32  */

33 public abstract class PropertyPointer extends NodePointer {
34     public static final int UNSPECIFIED_PROPERTY = Integer.MIN_VALUE;
35
36     protected int propertyIndex = UNSPECIFIED_PROPERTY;
37     protected Object JavaDoc bean;
38
39     /**
40      * Takes a javabean, a descriptor of a property of that object and
41      * an offset within that property (starting with 0).
42      */

43     public PropertyPointer(NodePointer parent) {
44         super(parent);
45     }
46
47     public int getPropertyIndex() {
48         return propertyIndex;
49     }
50
51     public void setPropertyIndex(int index) {
52         if (propertyIndex != index) {
53             propertyIndex = index;
54             setIndex(WHOLE_COLLECTION);
55         }
56     }
57
58     public Object JavaDoc getBean() {
59         if (bean == null) {
60             bean = getImmediateParentPointer().getNode();
61         }
62         return bean;
63     }
64
65     public QName getName() {
66         return new QName(null, getPropertyName());
67     }
68
69     public abstract String JavaDoc getPropertyName();
70
71     public abstract void setPropertyName(String JavaDoc propertyName);
72
73     public abstract int getPropertyCount();
74
75     public abstract String JavaDoc[] getPropertyNames();
76
77     protected abstract boolean isActualProperty();
78
79     public boolean isActual() {
80         if (!isActualProperty()) {
81             return false;
82         }
83
84         return super.isActual();
85     }
86
87     private static final Object JavaDoc UNINITIALIZED = new Object JavaDoc();
88
89     private Object JavaDoc value = UNINITIALIZED;
90     public Object JavaDoc getImmediateNode() {
91         if (value == UNINITIALIZED) {
92             if (index == WHOLE_COLLECTION) {
93                 value = ValueUtils.getValue(getBaseValue());
94             }
95             else {
96                 value = ValueUtils.getValue(getBaseValue(), index);
97             }
98         }
99         return value;
100     }
101     
102     public boolean isCollection() {
103         Object JavaDoc value = getBaseValue();
104         return value != null && ValueUtils.isCollection(value);
105     }
106     
107     public boolean isLeaf() {
108         Object JavaDoc value = getNode();
109         return value == null
110             || JXPathIntrospector.getBeanInfo(value.getClass()).isAtomic();
111     }
112
113     /**
114      * If the property contains a collection, then the length of that
115      * collection, otherwise - 1.
116      */

117     public int getLength() {
118         return ValueUtils.getLength(getBaseValue());
119     }
120
121
122     /**
123      * Returns a NodePointer that can be used to access the currently
124      * selected property value.
125      */

126     public NodePointer getImmediateValuePointer() {
127         return NodePointer.newChildNodePointer(
128             this,
129             getName(),
130             getImmediateNode());
131     }
132
133     public NodePointer createPath(JXPathContext context) {
134         if (getImmediateNode() == null) {
135             AbstractFactory factory = getAbstractFactory(context);
136             int inx = (index == WHOLE_COLLECTION ? 0 : index);
137             boolean success =
138                 factory.createObject(
139                     context,
140                     this,
141                     getBean(),
142                     getPropertyName(),
143                     inx);
144             if (!success) {
145                 throw new JXPathException(
146                     "Factory "
147                         + factory
148                         + " could not create an object for path: "
149                         + asPath());
150             }
151         }
152         return this;
153     }
154
155     public NodePointer createPath(JXPathContext context, Object JavaDoc value) {
156         // If neccessary, expand collection
157
if (index != WHOLE_COLLECTION && index >= getLength()) {
158             createPath(context);
159         }
160         setValue(value);
161         return this;
162     }
163
164     public NodePointer createChild(
165         JXPathContext context,
166         QName name,
167         int index,
168         Object JavaDoc value)
169     {
170         PropertyPointer prop = (PropertyPointer) clone();
171         if (name != null) {
172             prop.setPropertyName(name.toString());
173         }
174         prop.setIndex(index);
175         return prop.createPath(context, value);
176     }
177
178     public NodePointer createChild(
179         JXPathContext context,
180         QName name,
181         int index)
182     {
183         PropertyPointer prop = (PropertyPointer) clone();
184         if (name != null) {
185             prop.setPropertyName(name.toString());
186         }
187         prop.setIndex(index);
188         return prop.createPath(context);
189     }
190
191     public int hashCode() {
192         return getImmediateParentPointer().hashCode() + propertyIndex + index;
193     }
194
195     public boolean equals(Object JavaDoc object) {
196         if (object == this) {
197             return true;
198         }
199
200         if (!(object instanceof PropertyPointer)) {
201             return false;
202         }
203
204         PropertyPointer other = (PropertyPointer) object;
205         if (parent != other.parent) {
206             if (parent == null || !parent.equals(other.parent)) {
207                 return false;
208             }
209         }
210
211         if (getPropertyIndex() != other.getPropertyIndex()
212             || !getPropertyName().equals(other.getPropertyName())) {
213             return false;
214         }
215
216         int iThis = (index == WHOLE_COLLECTION ? 0 : index);
217         int iOther = (other.index == WHOLE_COLLECTION ? 0 : other.index);
218         return iThis == iOther;
219     }
220
221     public int compareChildNodePointers(
222         NodePointer pointer1,
223         NodePointer pointer2)
224     {
225         return getValuePointer().compareChildNodePointers(pointer1, pointer2);
226     }
227     
228     private AbstractFactory getAbstractFactory(JXPathContext context) {
229         AbstractFactory factory = context.getFactory();
230         if (factory == null) {
231             throw new JXPathException(
232                 "Factory is not set on the "
233                     + "JXPathContext - cannot create path: "
234                     + asPath());
235         }
236         return factory;
237     }
238 }
Popular Tags