/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license this file to you 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 jlibs.xml.sax.dog; import jlibs.core.io.IOUtil; import jlibs.core.lang.ImpossibleException; import jlibs.xml.Namespaces; import jlibs.xml.dom.DOMNavigator; import jlibs.xml.dom.DOMUtil; import jlibs.xml.sax.dog.sniff.Event; import org.jaxen.dom.NamespaceNode; import org.w3c.dom.Attr; import org.w3c.dom.Node; import javax.xml.namespace.NamespaceContext; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.util.BitSet; /** * @author Santhosh Kumar T */ public class NodeItem implements NodeType{ /** * This field tells the type of this NodeItem. * It is one of the constants in NodeType other than ANY, MAX */ public final int type; public final String location; // unique xpath public final String value; public final String localName; public final String namespaceURI; public final String qualifiedName; public final long order; /** * This field tells how many expressions have hit or might hit * this NodeItem. This is incremented by Event. and decremented by * XMLBuilder. * * This field is used to decide whether xml needs be built for this * NodeItem or not. If refCount becomes zero before xml is completely * built, then the xml object built so far is discarded. */ public int refCount; /** * This field holds the in-memory xml representation of this node item. * This could be DOM Node or XOM Node etc based on which type of * XMLBuilder is being used. */ public Object xml; /** * This field tells if the value of field `xml` is completely built * or not. */ public boolean xmlBuilt; public NodeItem(){ order = 0; type = DOCUMENT; location = "/"; value = null; localName = null; namespaceURI = null; qualifiedName = null; } public NodeItem(Event event){ order = event.order(); type = event.type(); location = event.location(); value = event.value(); localName = event.localName(); namespaceURI = event.namespaceURI(); qualifiedName = event.qualifiedName(); } // used only for testing purposes public NodeItem(Node node, NamespaceContext nsContext){ order = -100; // not used if(node instanceof Attr && Namespaces.URI_XMLNS.equals(node.getNamespaceURI())) type = NAMESPACE; else if(node.getNodeType()==NamespaceNode.NAMESPACE_NODE) type = NAMESPACE; else type = node.getNodeType(); location = new DOMNavigator().getXPath(node, nsContext); value = node.getNodeValue(); localName = node.getLocalName(); namespaceURI = node.getNamespaceURI(); qualifiedName = node.getNodeName(); xml = node; } // used only for testing purposes public NodeItem(int type, String location, String value, String localName, String namespaceURI, String qualifiedName){ order = -100; // not used this.type = type; this.location = location; this.value = value; this.localName = localName; this.namespaceURI = namespaceURI; this.qualifiedName = qualifiedName; } // used only for testing purposes public NodeItem(Node node, String prefix, String uri, NamespaceContext nsContext){ order = -100; // not used type = NAMESPACE; location = new DOMNavigator().getXPath(node, nsContext)+"/namespace::"+prefix; value = uri; localName = prefix; namespaceURI = Namespaces.URI_XMLNS; qualifiedName = "xmlns:"+prefix; xml = node; } public void printTo(PrintStream out){ if(xml instanceof Node){ out.println(location); DOMUtil.serialize((Node)xml, out); }else out.print(localName); } @Override public String toString(){ if(xml instanceof Node){ ByteArrayOutputStream bout = new ByteArrayOutputStream(); printTo(new PrintStream(bout, true)); try{ return bout.toString(IOUtil.UTF_8.name()); }catch(UnsupportedEncodingException ex){ throw new ImpossibleException(ex); } }else return location; } /** * This field is used only in instantResults mode; * This field tells which expressions has hit this node. * if ith bit is set, it means the doc-expression whose id is i * has hit this node. * * This is used not to notify same node in an expression's result * more than once */ public BitSet expressions; }