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 */ 017package org.apache.commons.jxpath.ri.compiler; 018 019import org.apache.commons.jxpath.ri.Compiler; 020 021/** 022 * @author Dmitri Plotnikov 023 * @version $Revision: 1523200 $ $Date: 2013-09-14 11:48:25 +0200 (Sa, 14 Sep 2013) $ 024 */ 025public 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}