001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.jxpath.ri.model.dynamic;
018    
019    import java.util.Locale;
020    
021    import org.apache.commons.jxpath.DynamicPropertyHandler;
022    import org.apache.commons.jxpath.JXPathIntrospector;
023    import org.apache.commons.jxpath.ri.QName;
024    import org.apache.commons.jxpath.ri.model.NodeIterator;
025    import org.apache.commons.jxpath.ri.model.NodePointer;
026    import org.apache.commons.jxpath.ri.model.beans.PropertyIterator;
027    import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer;
028    import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
029    
030    /**
031     * A Pointer that points to an object with Dynamic Properties. It is used for
032     * the first element of a path; following elements will by of type
033     * {@link PropertyPointer}.
034     *
035     * @author Dmitri Plotnikov
036     * @version $Revision: 652884 $ $Date: 2008-05-02 15:02:00 -0500 (Fri, 02 May 2008) $
037     */
038    public class DynamicPointer extends PropertyOwnerPointer {
039        private QName name;
040        private Object bean;
041        private DynamicPropertyHandler handler;
042    
043        private static final long serialVersionUID = -1842347025295904256L;
044    
045        /**
046         * Create a new DynamicPointer.
047         * @param name property name
048         * @param bean owning bean
049         * @param handler DynamicPropertyHandler
050         * @param locale Locale
051         */
052        public DynamicPointer(QName name, Object bean,
053                DynamicPropertyHandler handler, Locale locale) {
054            super(null, locale);
055            this.name = name;
056            this.bean = bean;
057            this.handler = handler;
058        }
059    
060        /**
061         * Create a new DynamicPointer.
062         * @param parent parent pointer
063         * @param name property name
064         * @param bean owning bean
065         * @param handler DynamicPropertyHandler
066         */
067        public DynamicPointer(NodePointer parent, QName name,
068                Object bean, DynamicPropertyHandler handler) {
069            super(parent);
070            this.name = name;
071            this.bean = bean;
072            this.handler = handler;
073        }
074    
075        public PropertyPointer getPropertyPointer() {
076            return new DynamicPropertyPointer(this, handler);
077        }
078    
079        public NodeIterator createNodeIterator(
080                    String property, boolean reverse, NodePointer startWith) {
081            return new PropertyIterator(this, property, reverse, startWith);
082        }
083    
084        public NodeIterator attributeIterator(QName name) {
085            return new DynamicAttributeIterator(this, name);
086        }
087    
088        public QName getName() {
089            return name;
090        }
091    
092        public boolean isDynamicPropertyDeclarationSupported() {
093            return true;
094        }
095    
096        /**
097         * Returns the DP object iself.
098         * @return Object
099         */
100        public Object getBaseValue() {
101            return bean;
102        }
103    
104        public boolean isLeaf() {
105            Object value = getNode();
106            return value == null || JXPathIntrospector.getBeanInfo(value.getClass()).isAtomic();
107        }
108    
109        public boolean isCollection() {
110            return false;
111        }
112    
113        /**
114         * Returns 1.
115         * @return int
116         */
117        public int getLength() {
118            return 1;
119        }
120    
121        public String asPath() {
122            return parent == null ? "/" : super.asPath();
123        }
124    
125        public int hashCode() {
126            return System.identityHashCode(bean) + name.hashCode();
127        }
128    
129        public boolean equals(Object object) {
130            if (object == this) {
131                return true;
132            }
133    
134            if (!(object instanceof DynamicPointer)) {
135                return false;
136            }
137    
138            DynamicPointer other = (DynamicPointer) object;
139            return bean == other.bean && name.equals(other.name);
140        }
141    }