View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.ast.xpath.saxon;
5   
6   import net.sf.saxon.om.Axis;
7   import net.sf.saxon.om.AxisIterator;
8   import net.sf.saxon.om.DocumentInfo;
9   import net.sf.saxon.om.EmptyIterator;
10  import net.sf.saxon.om.Navigator;
11  import net.sf.saxon.om.NodeArrayIterator;
12  import net.sf.saxon.om.NodeInfo;
13  import net.sf.saxon.om.SingleNodeIterator;
14  import net.sf.saxon.type.Type;
15  import net.sourceforge.pmd.lang.ast.Node;
16  
17  /**
18   * A Saxon OM Element type node for an AST Node.
19   */
20  public class ElementNode extends AbstractNodeInfo {
21  
22      protected final DocumentNode document;
23      protected final ElementNode parent;
24      protected final Node node;
25      protected final int id;
26      protected final int siblingPosition;
27      protected final NodeInfo[] children;
28  
29      public ElementNode(DocumentNode document, IdGenerator idGenerator, ElementNode parent, Node node,
30  	    int siblingPosition) {
31  	this.document = document;
32  	this.parent = parent;
33  	this.node = node;
34  	this.id = idGenerator.getNextId();
35  	this.siblingPosition = siblingPosition;
36  	if (node.jjtGetNumChildren() > 0) {
37  	    this.children = new NodeInfo[node.jjtGetNumChildren()];
38  	    for (int i = 0; i < children.length; i++) {
39  		children[i] = new ElementNode(document, idGenerator, this, node.jjtGetChild(i), i);
40  	    }
41  	} else {
42  	    this.children = null;
43  	}
44  	document.nodeToElementNode.put(node, this);
45      }
46  
47      @Override
48      public Object getUnderlyingNode() {
49  	return node;
50      }
51  
52      @Override
53      public int getSiblingPosition() {
54  	return siblingPosition;
55      }
56  
57      @Override
58      public int getColumnNumber() {
59  	return node.getBeginColumn();
60      }
61  
62      @Override
63      public int getLineNumber() {
64  	return node.getBeginLine();
65      }
66  
67      @Override
68      public boolean hasChildNodes() {
69  	return children != null;
70      }
71  
72      @Override
73      public int getNodeKind() {
74  	return Type.ELEMENT;
75      }
76  
77      @Override
78      public DocumentInfo getDocumentRoot() {
79  	return document;
80      }
81  
82      @Override
83      public String getLocalPart() {
84  	return node.toString();
85      }
86  
87      @Override
88      public String getURI() {
89  	return "";
90      }
91  
92      @Override
93      public NodeInfo getParent() {
94  	return parent;
95      }
96  
97      @Override
98      public int compareOrder(NodeInfo other) {
99  	return Integer.signum(this.node.jjtGetId() - ((ElementNode) other).node.jjtGetId());
100     }
101 
102     @SuppressWarnings("PMD.MissingBreakInSwitch")
103     @Override
104     public AxisIterator iterateAxis(byte axisNumber) {
105 	switch (axisNumber) {
106 	case Axis.ANCESTOR:
107 	    return new Navigator.AncestorEnumeration(this, false);
108 	case Axis.ANCESTOR_OR_SELF:
109 	    return new Navigator.AncestorEnumeration(this, true);
110 	case Axis.ATTRIBUTE:
111 	    return new AttributeAxisIterator(this);
112 	case Axis.CHILD:
113 	    if (children == null) {
114 		return EmptyIterator.getInstance();
115 	    } else {
116 		return new NodeArrayIterator(children);
117 	    }
118 	case Axis.DESCENDANT:
119 	    return new Navigator.DescendantEnumeration(this, false, true);
120 	case Axis.DESCENDANT_OR_SELF:
121 	    return new Navigator.DescendantEnumeration(this, true, true);
122 	case Axis.FOLLOWING:
123 	    return new Navigator.FollowingEnumeration(this);
124 	case Axis.FOLLOWING_SIBLING:
125 	    if (parent == null || siblingPosition == parent.children.length - 1) {
126 		return EmptyIterator.getInstance();
127 	    } else {
128 		return new NodeArrayIterator(parent.children, siblingPosition + 1, parent.children.length);
129 	    }
130 	case Axis.NAMESPACE:
131 	    return super.iterateAxis(axisNumber);
132 	case Axis.PARENT:
133 	    return SingleNodeIterator.makeIterator(parent);
134 	case Axis.PRECEDING:
135 	    return new Navigator.PrecedingEnumeration(this, false);
136 	case Axis.PRECEDING_SIBLING:
137 	    if (parent == null || siblingPosition == 0) {
138 		return EmptyIterator.getInstance();
139 	    } else {
140 		return new NodeArrayIterator(parent.children, 0, siblingPosition);
141 	    }
142 	case Axis.SELF:
143 	    return SingleNodeIterator.makeIterator(this);
144 	case Axis.PRECEDING_OR_ANCESTOR:
145 	    return new Navigator.PrecedingEnumeration(this, true);
146 	default:
147 	    return super.iterateAxis(axisNumber);
148 	}
149     }
150 
151 }