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.dom;
018    
019    import org.apache.commons.jxpath.ri.Compiler;
020    import org.apache.commons.jxpath.ri.QName;
021    import org.apache.commons.jxpath.ri.compiler.NodeTest;
022    import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
023    import org.apache.commons.jxpath.ri.model.NodePointer;
024    import org.apache.commons.jxpath.util.TypeUtils;
025    import org.w3c.dom.Attr;
026    
027    /**
028     * A Pointer that points to a DOM node. Because the underlying DOM Attr is not Serializable,
029     * neither is this pointer class truly so.
030     *
031     * @author Dmitri Plotnikov
032     * @version $Revision: 670727 $ $Date: 2008-06-23 15:10:38 -0500 (Mon, 23 Jun 2008) $
033     */
034    public class DOMAttributePointer extends NodePointer {
035        private static final long serialVersionUID = 1115085175427555951L;
036    
037        private Attr attr;
038    
039        /**
040         * Create a new DOMAttributePointer.
041         * @param parent pointer
042         * @param attr pointed
043         */
044        public DOMAttributePointer(NodePointer parent, Attr attr) {
045            super(parent);
046            this.attr = attr;
047        }
048    
049        public QName getName() {
050            return new QName(
051                DOMNodePointer.getPrefix(attr),
052                DOMNodePointer.getLocalName(attr));
053        }
054    
055        public String getNamespaceURI() {
056            String prefix = DOMNodePointer.getPrefix(attr);
057            return prefix == null ? null : parent.getNamespaceURI(prefix);
058        }
059    
060        public Object getValue() {
061            String value = attr.getValue();
062            if (value == null || (value.equals("") && !attr.getSpecified())) {
063                return null;
064            }
065            return value;
066        }
067    
068        public Object getBaseValue() {
069            return attr;
070        }
071    
072        public boolean isCollection() {
073            return false;
074        }
075    
076        public int getLength() {
077            return 1;
078        }
079    
080        public Object getImmediateNode() {
081            return attr;
082        }
083    
084        public boolean isActual() {
085            return true;
086        }
087    
088        public boolean isLeaf() {
089            return true;
090        }
091    
092        public boolean testNode(NodeTest nodeTest) {
093            return nodeTest == null
094                || ((nodeTest instanceof NodeTypeTest)
095                    && ((NodeTypeTest) nodeTest).getNodeType() == Compiler.NODE_TYPE_NODE);
096        }
097    
098        /**
099         * Sets the value of this attribute.
100         * @param value to set
101         */
102        public void setValue(Object value) {
103            attr.setValue((String) TypeUtils.convert(value, String.class));
104        }
105    
106        public void remove() {
107            attr.getOwnerElement().removeAttributeNode(attr);
108        }
109    
110        public String asPath() {
111            StringBuffer buffer = new StringBuffer();
112            if (parent != null) {
113                buffer.append(parent.asPath());
114                if (buffer.length() == 0
115                    || buffer.charAt(buffer.length() - 1) != '/') {
116                    buffer.append('/');
117                }
118            }
119            buffer.append('@');
120            buffer.append(getName());
121            return buffer.toString();
122        }
123    
124        public int hashCode() {
125            return System.identityHashCode(attr);
126        }
127    
128        public boolean equals(Object object) {
129            return object == this || object instanceof DOMAttributePointer
130                    && attr == ((DOMAttributePointer) object).attr;
131        }
132    
133        public int compareChildNodePointers(NodePointer pointer1,
134                NodePointer pointer2) {
135            // Won't happen - attributes don't have children
136            return 0;
137        }
138    }