/*
* Copyright 2004-2012 the Seasar Foundation and the Others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.seasar.mayaa.impl.engine.specification.xpath;
import java.util.Iterator;
import org.jaxen.DefaultNavigator;
import org.jaxen.NamedAccessNavigator;
import org.jaxen.Navigator;
import org.jaxen.XPath;
import org.jaxen.util.SingleObjectIterator;
import org.seasar.mayaa.engine.specification.Namespace;
import org.seasar.mayaa.engine.specification.NodeAttribute;
import org.seasar.mayaa.engine.specification.NodeTreeWalker;
import org.seasar.mayaa.engine.specification.PrefixAwareName;
import org.seasar.mayaa.engine.specification.PrefixMapping;
import org.seasar.mayaa.engine.specification.QName;
import org.seasar.mayaa.engine.specification.Specification;
import org.seasar.mayaa.engine.specification.SpecificationNode;
import org.seasar.mayaa.engine.specification.URI;
import org.seasar.mayaa.impl.CONST_IMPL;
import org.seasar.mayaa.impl.engine.specification.SpecificationUtil;
import org.seasar.mayaa.impl.util.StringUtil;
import org.seasar.mayaa.impl.util.collection.AbstractScanningIterator;
import org.seasar.mayaa.impl.util.collection.NullIterator;
/**
* @author Masataka Kurihara (Gluegent, Inc.)
*/
public class SpecificationNavigator extends DefaultNavigator
implements NamedAccessNavigator, CONST_IMPL {
private static final long serialVersionUID = -8845415744894196361L;
private static final Navigator INSTANCE = new SpecificationNavigator();
public static Navigator getInstance() {
return INSTANCE;
}
protected SpecificationNavigator() {
// singleton
}
protected URI getNamespaceURI(Namespace namespace, String prefix) {
if (namespace == null) {
throw new IllegalArgumentException();
}
if (prefix == null) {
prefix = "";
}
PrefixMapping mapping = namespace.getMappingFromPrefix(prefix, true);
if (mapping != null) {
return mapping.getNamespaceURI();
}
return null;
}
public Iterator getParentAxisIterator(Object obj) {
Object parent = null;
if (obj instanceof NodeAttribute) {
parent = ((NodeAttribute) obj).getNode();
} else if (obj instanceof NodeTreeWalker) {
parent = ((NodeTreeWalker) obj).getParentNode();
}
if (parent != null) {
return new SingleObjectIterator(parent);
}
return NullIterator.getInstance();
}
public Iterator getNamespaceAxisIterator(Object obj) {
if (obj instanceof Namespace) {
Namespace namespace = (Namespace) obj;
return namespace.iteratePrefixMapping(true);
}
return NullIterator.getInstance();
}
public Iterator getAttributeAxisIterator(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return node.iterateAttribute();
}
return NullIterator.getInstance();
}
public Iterator getAttributeAxisIterator(
Object obj, String localName, String namespacePrefix,
String namespaceURI) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
if (StringUtil.isEmpty(namespaceURI)) {
URI uri = getNamespaceURI(node, namespacePrefix);
if (uri == null) {
return NullIterator.getInstance();
}
namespaceURI = uri.getValue();
}
QName qName = SpecificationUtil.createQName(
SpecificationUtil.createURI(namespaceURI), localName);
return new QNameFilteredIterator(qName, node.iterateAttribute());
}
return NullIterator.getInstance();
}
public Iterator getChildAxisIterator(Object obj) {
if (obj instanceof NodeTreeWalker) {
NodeTreeWalker node = (NodeTreeWalker) obj;
return node.iterateChildNode();
}
return NullIterator.getInstance();
}
public Iterator getChildAxisIterator(
Object obj, String localName, String namespacePrefix,
String namespaceURI) {
if (obj instanceof NodeTreeWalker) {
NodeTreeWalker node = (NodeTreeWalker) obj;
if (StringUtil.isEmpty(namespaceURI)) {
if (node instanceof Namespace) {
namespaceURI = getNamespaceURI(
(Namespace) node, namespacePrefix).getValue();
} else {
namespaceURI = URI_MAYAA.getValue();
}
}
QName qName = SpecificationUtil.createQName(
SpecificationUtil.createURI(namespaceURI), localName);
return new QNameFilteredIterator(qName, node.iterateChildNode());
}
return NullIterator.getInstance();
}
public Object getDocumentNode(Object obj) {
if (obj instanceof NodeTreeWalker) {
for (NodeTreeWalker current = (NodeTreeWalker) obj;
current != null; current = current.getParentNode()) {
if (current instanceof Specification) {
return current;
}
}
}
return null;
}
public String translateNamespacePrefixToUri(String prefix, Object obj) {
Namespace namaspace = null;
if (obj instanceof Namespace) {
namaspace = (Namespace) obj;
}
if (namaspace != null) {
return getNamespaceURI(namaspace, prefix).getValue();
}
return null;
}
public String getAttributeName(Object obj) {
if (obj instanceof NodeAttribute) {
NodeAttribute attr = (NodeAttribute) obj;
return attr.getQName().getLocalName();
}
return null;
}
public String getAttributeNamespaceUri(Object obj) {
if (obj instanceof NodeAttribute) {
NodeAttribute attr = (NodeAttribute) obj;
return attr.getQName().getNamespaceURI().getValue();
}
return null;
}
public String getAttributeQName(Object obj) {
if (obj instanceof NodeAttribute) {
NodeAttribute attr = (NodeAttribute) obj;
String prefix = attr.getPrefix();
if (StringUtil.hasValue(prefix)) {
return prefix + ":" + getAttributeName(obj);
}
return getAttributeName(obj);
}
return null;
}
public String getAttributeStringValue(Object obj) {
if (obj instanceof NodeAttribute) {
NodeAttribute attr = (NodeAttribute) obj;
return attr.getValue();
}
return null;
}
public String getCommentStringValue(Object obj) {
if (isComment(obj)) {
SpecificationNode node = (SpecificationNode) obj;
return SpecificationUtil.getAttributeValue(node, QM_TEXT);
}
return null;
}
public String getElementName(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return node.getQName().getLocalName();
}
return null;
}
public String getElementNamespaceUri(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return node.getQName().getNamespaceURI().getValue();
}
return null;
}
public String getElementQName(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
String prefix = node.getPrefix();
if (StringUtil.hasValue(prefix)) {
return prefix + ":" + getElementName(obj);
}
return getElementName(obj);
}
return null;
}
public String getElementStringValue(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
StringBuffer buffer = new StringBuffer();
for (Iterator it = node.iterateChildNode(); it.hasNext();) {
SpecificationNode child = (SpecificationNode) it.next();
if (isText(child)) {
String value = getTextStringValue(child);
if (value != null) {
buffer.append(value.trim());
}
}
}
return buffer.toString();
}
return null;
}
public String getNamespacePrefix(Object obj) {
if (obj instanceof PrefixMapping) {
PrefixMapping mapping = (PrefixMapping) obj;
return mapping.getPrefix();
}
return null;
}
public String getNamespaceStringValue(Object obj) {
if (obj instanceof PrefixMapping) {
PrefixMapping mapping = (PrefixMapping) obj;
return mapping.getNamespaceURI().getValue();
}
return null;
}
public String getTextStringValue(Object obj) {
if (obj instanceof String) {
return (String) obj;
} else if (isText(obj)) {
SpecificationNode node = (SpecificationNode) obj;
String text = SpecificationUtil.getAttributeValue(node, QM_TEXT);
if (text != null) {
return text;
}
}
return "";
}
public boolean isAttribute(Object obj) {
return obj instanceof NodeAttribute;
}
public boolean isComment(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return QM_COMMENT.equals(node.getQName());
}
return false;
}
public boolean isDocument(Object obj) {
return obj instanceof Specification;
}
public boolean isElement(Object obj) {
return obj instanceof SpecificationNode
&& isProcessingInstruction(obj) == false
&& isText(obj) == false && isDocType(obj) == false;
}
public boolean isNamespace(Object obj) {
return obj instanceof PrefixMapping;
}
public boolean isProcessingInstruction(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return QM_PI.equals(node.getQName());
}
return false;
}
public boolean isText(Object obj) {
if (obj instanceof String) {
return true;
} else if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return QM_CHARACTERS.equals(node.getQName())
|| QM_CDATA.equals(node.getQName());
}
return false;
}
public XPath parseXPath(String xpath) {
return SpecificationXPath.createXPath(xpath, null);
}
public boolean isDocType(Object obj) {
if (obj instanceof SpecificationNode) {
SpecificationNode node = (SpecificationNode) obj;
return QM_DOCTYPE.equals(node.getQName());
}
return false;
}
// support class ------------------------------------------------
protected static class QNameFilteredIterator extends AbstractScanningIterator {
private QName _qName;
public QNameFilteredIterator(QName qName, Iterator iterator) {
super(iterator);
if (qName == null) {
throw new IllegalArgumentException();
}
_qName = qName;
}
protected boolean filter(Object test) {
if (test == null || (test instanceof PrefixAwareName == false)) {
return false;
}
PrefixAwareName prefixAwareName = (PrefixAwareName) test;
return _qName.equals(prefixAwareName.getQName());
}
}
}