View Javadoc

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