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
018package org.apache.commons.jxpath.ri.model.dom;
019
020import org.apache.commons.jxpath.ri.Compiler;
021import org.apache.commons.jxpath.ri.QName;
022import org.apache.commons.jxpath.ri.compiler.NodeTest;
023import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
024import org.apache.commons.jxpath.ri.model.NodePointer;
025
026/**
027 * Represents a namespace node.
028 */
029public class NamespacePointer extends NodePointer {
030
031    private static final long serialVersionUID = -7622456151550131709L;
032
033    /**
034     * Namespace prefix.
035     */
036    private final String prefix;
037
038    /**
039     * Namespace URI String.
040     */
041    private String namespaceURI;
042
043    /**
044     * Constructs a new NamespacePointer.
045     *
046     * @param parent parent pointer
047     * @param prefix namespace prefix.
048     */
049    public NamespacePointer(final NodePointer parent, final String prefix) {
050        super(parent);
051        this.prefix = prefix;
052    }
053
054    /**
055     * Constructs a new NamespacePointer.
056     *
057     * @param parent       parent pointer
058     * @param prefix       namespace prefix.
059     * @param namespaceURI namespace URI.
060     */
061    public NamespacePointer(final NodePointer parent, final String prefix, final String namespaceURI) {
062        super(parent);
063        this.prefix = prefix;
064        this.namespaceURI = namespaceURI;
065    }
066
067    @Override
068    public String asPath() {
069        final StringBuilder buffer = new StringBuilder();
070        if (parent != null) {
071            buffer.append(parent.asPath());
072            if (buffer.length() == 0 || buffer.charAt(buffer.length() - 1) != '/') {
073                buffer.append('/');
074            }
075        }
076        buffer.append("namespace::");
077        buffer.append(prefix);
078        return buffer.toString();
079    }
080
081    @Override
082    public int compareChildNodePointers(final NodePointer pointer1, final NodePointer pointer2) {
083        // Won't happen - namespaces don't have children
084        return 0;
085    }
086
087    @Override
088    public boolean equals(final Object object) {
089        if (object == this) {
090            return true;
091        }
092        if (!(object instanceof NamespacePointer)) {
093            return false;
094        }
095        final NamespacePointer other = (NamespacePointer) object;
096        return prefix.equals(other.prefix);
097    }
098
099    @Override
100    public Object getBaseValue() {
101        return null;
102    }
103
104    @Override
105    public Object getImmediateNode() {
106        return getNamespaceURI();
107    }
108
109    @Override
110    public int getLength() {
111        return 1;
112    }
113
114    @Override
115    public QName getName() {
116        return new QName(prefix);
117    }
118
119    @Override
120    public String getNamespaceURI() {
121        if (namespaceURI == null) {
122            namespaceURI = parent.getNamespaceURI(prefix);
123        }
124        return namespaceURI;
125    }
126
127    @Override
128    public int hashCode() {
129        return prefix.hashCode();
130    }
131
132    @Override
133    public boolean isCollection() {
134        return false;
135    }
136
137    @Override
138    public boolean isLeaf() {
139        return true;
140    }
141
142    /**
143     * Throws UnsupportedOperationException.
144     *
145     * @param value Object
146     */
147    @Override
148    public void setValue(final Object value) {
149        throw new UnsupportedOperationException("Cannot modify DOM trees");
150    }
151
152    @Override
153    public boolean testNode(final NodeTest nodeTest) {
154        return nodeTest == null || nodeTest instanceof NodeTypeTest && ((NodeTypeTest) nodeTest).getNodeType() == Compiler.NODE_TYPE_NODE;
155    }
156}