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 package org.apache.commons.jxpath.ri.compiler;
018
019 import org.apache.commons.jxpath.ri.Compiler;
020
021 /**
022 * @author Dmitri Plotnikov
023 * @version $Revision: 652845 $ $Date: 2008-05-02 12:46:46 -0500 (Fri, 02 May 2008) $
024 */
025 public class Step {
026 private int axis;
027 private NodeTest nodeTest;
028 private Expression[] predicates;
029
030 /**
031 * Create a new Step.
032 * @param axis axis code
033 * @param nodeTest step test
034 * @param predicates predicate expressions
035 */
036 protected Step(int axis, NodeTest nodeTest, Expression[] predicates) {
037 this.axis = axis;
038 this.nodeTest = nodeTest;
039 this.predicates = predicates;
040 }
041
042 /**
043 * Get the axis code.
044 * @return int
045 */
046 public int getAxis() {
047 return axis;
048 }
049
050 /**
051 * Get the step test.
052 * @return NodeTest
053 */
054 public NodeTest getNodeTest() {
055 return nodeTest;
056 }
057
058 /**
059 * Get the predicates.
060 * @return Expression[]
061 */
062 public Expression[] getPredicates() {
063 return predicates;
064 }
065
066 /**
067 * Learn whether this step contains any predicate that is context dependent.
068 * @return boolean
069 */
070 public boolean isContextDependent() {
071 if (predicates != null) {
072 for (int i = 0; i < predicates.length; i++) {
073 if (predicates[i].isContextDependent()) {
074 return true;
075 }
076 }
077 }
078 return false;
079 }
080
081 public String toString() {
082 StringBuffer buffer = new StringBuffer();
083 int axis = getAxis();
084 if (axis == Compiler.AXIS_CHILD) {
085 buffer.append(nodeTest);
086 }
087 else if (axis == Compiler.AXIS_ATTRIBUTE) {
088 buffer.append('@');
089 buffer.append(nodeTest);
090 }
091 else if (axis == Compiler.AXIS_SELF
092 && nodeTest instanceof NodeTypeTest
093 && ((NodeTypeTest) nodeTest).getNodeType()
094 == Compiler.NODE_TYPE_NODE) {
095 buffer.append(".");
096 }
097 else if (axis == Compiler.AXIS_PARENT
098 && nodeTest instanceof NodeTypeTest
099 && ((NodeTypeTest) nodeTest).getNodeType()
100 == Compiler.NODE_TYPE_NODE) {
101 buffer.append("..");
102 }
103 else if (axis == Compiler.AXIS_DESCENDANT_OR_SELF
104 && nodeTest instanceof NodeTypeTest
105 && ((NodeTypeTest) nodeTest).getNodeType()
106 == Compiler.NODE_TYPE_NODE
107 && (predicates == null || predicates.length == 0)) {
108 buffer.append("");
109 }
110 else {
111 buffer.append(axisToString(axis));
112 buffer.append("::");
113 buffer.append(nodeTest);
114 }
115 Expression[] predicates = getPredicates();
116 if (predicates != null) {
117 for (int i = 0; i < predicates.length; i++) {
118 buffer.append('[');
119 buffer.append(predicates[i]);
120 buffer.append(']');
121 }
122 }
123 return buffer.toString();
124 }
125
126 /**
127 * Decode an axis code to its name.
128 * @param axis int code
129 * @return String name.
130 * @see Compiler
131 * @see http://www.w3.org/TR/xpath#axes
132 */
133 public static String axisToString(int axis) {
134 switch (axis) {
135 case Compiler.AXIS_SELF :
136 return "self";
137 case Compiler.AXIS_CHILD :
138 return "child";
139 case Compiler.AXIS_PARENT :
140 return "parent";
141 case Compiler.AXIS_ANCESTOR :
142 return "ancestor";
143 case Compiler.AXIS_ATTRIBUTE :
144 return "attribute";
145 case Compiler.AXIS_NAMESPACE :
146 return "namespace";
147 case Compiler.AXIS_PRECEDING :
148 return "preceding";
149 case Compiler.AXIS_FOLLOWING :
150 return "following";
151 case Compiler.AXIS_DESCENDANT :
152 return "descendant";
153 case Compiler.AXIS_ANCESTOR_OR_SELF :
154 return "ancestor-or-self";
155 case Compiler.AXIS_FOLLOWING_SIBLING :
156 return "following-sibling";
157 case Compiler.AXIS_PRECEDING_SIBLING :
158 return "preceding-sibling";
159 case Compiler.AXIS_DESCENDANT_OR_SELF :
160 return "descendant-or-self";
161 default:
162 return "UNKNOWN";
163 }
164 }
165 }