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 */
017package org.apache.commons.jxpath.ri.model.dom;
018
019import org.apache.commons.jxpath.ri.Compiler;
020import org.apache.commons.jxpath.ri.QName;
021import org.apache.commons.jxpath.ri.compiler.NodeTest;
022import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
023import org.apache.commons.jxpath.ri.model.NodePointer;
024import org.apache.commons.jxpath.util.TypeUtils;
025import 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 22:10:38 +0200 (Mo, 23 Jun 2008) $
033 */
034public 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}