1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * @LastModified: Oct 2017 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.xpath.internal.axes; 23 24 import com.sun.org.apache.xml.internal.dtm.Axis; 25 import com.sun.org.apache.xml.internal.utils.PrefixResolver; 26 import com.sun.org.apache.xml.internal.utils.QName; 27 import com.sun.org.apache.xpath.internal.compiler.Compiler; 28 import java.util.List; 29 30 /** 31 * This class iterates over set of nodes that needs to be sorted. 32 * @xsl.usage internal 33 */ 34 public class WalkingIteratorSorted extends WalkingIterator 35 { 36 static final long serialVersionUID = -4512512007542368213L; 37 38 // /** True if the nodes will be found in document order */ 39 // protected boolean m_inNaturalOrder = false; 40 41 /** True if the nodes will be found in document order, and this can 42 * be determined statically. */ 43 protected boolean m_inNaturalOrderStatic = false; 44 45 /** 46 * Create a WalkingIteratorSorted object. 47 * 48 * @param nscontext The namespace context for this iterator, 49 * should be OK if null. 50 */ 51 public WalkingIteratorSorted(PrefixResolver nscontext) 52 { 53 super(nscontext); 54 } 55 56 /** 57 * Create a WalkingIterator iterator, including creation 58 * of step walkers from the opcode list, and call back 59 * into the Compiler to create predicate expressions. 60 * 61 * @param compiler The Compiler which is creating 62 * this expression. 63 * @param opPos The position of this iterator in the 64 * opcode list from the compiler. 65 * @param shouldLoadWalkers True if walkers should be 66 * loaded, or false if this is a derived iterator and 67 * it doesn't wish to load child walkers. 68 * 69 * @throws javax.xml.transform.TransformerException 70 */ 71 WalkingIteratorSorted( 72 Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers) 73 throws javax.xml.transform.TransformerException 74 { 75 super(compiler, opPos, analysis, shouldLoadWalkers); 76 } 77 78 /** 79 * Returns true if all the nodes in the iteration well be returned in document 80 * order. 81 * 82 * @return true as a default. 83 */ 84 public boolean isDocOrdered() 85 { 86 return m_inNaturalOrderStatic; 87 } 88 89 90 /** 91 * Tell if the nodeset can be walked in doc order, via static analysis. 92 * 93 * 94 * @return true if the nodeset can be walked in doc order, without sorting. 95 */ 96 boolean canBeWalkedInNaturalDocOrderStatic() 97 { 98 99 if (null != m_firstWalker) 100 { 101 AxesWalker walker = m_firstWalker; 102 int prevAxis = -1; 103 boolean prevIsSimpleDownAxis = true; 104 105 for(int i = 0; null != walker; i++) 106 { 107 int axis = walker.getAxis(); 108 109 if(walker.isDocOrdered()) 110 { 111 boolean isSimpleDownAxis = ((axis == Axis.CHILD) 112 || (axis == Axis.SELF) 113 || (axis == Axis.ROOT)); 114 // Catching the filtered list here is only OK because 115 // FilterExprWalker#isDocOrdered() did the right thing. 116 if(isSimpleDownAxis || (axis == -1)) 117 walker = walker.getNextWalker(); 118 else 119 { 120 boolean isLastWalker = (null == walker.getNextWalker()); 121 if(isLastWalker) 122 { 123 if(walker.isDocOrdered() && (axis == Axis.DESCENDANT || 124 axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT 125 || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE)) 126 return true; 127 } 128 return false; 129 } 130 } 131 else 132 return false; 133 } 134 return true; 135 } 136 return false; 137 } 138 139 140 // /** 141 // * NEEDSDOC Method canBeWalkedInNaturalDocOrder 142 // * 143 // * 144 // * NEEDSDOC (canBeWalkedInNaturalDocOrder) @return 145 // */ 146 // boolean canBeWalkedInNaturalDocOrder() 147 // { 148 // 149 // if (null != m_firstWalker) 150 // { 151 // AxesWalker walker = m_firstWalker; 152 // int prevAxis = -1; 153 // boolean prevIsSimpleDownAxis = true; 154 // 155 // for(int i = 0; null != walker; i++) 156 // { 157 // int axis = walker.getAxis(); 158 // 159 // if(walker.isDocOrdered()) 160 // { 161 // boolean isSimpleDownAxis = ((axis == Axis.CHILD) 162 // || (axis == Axis.SELF) 163 // || (axis == Axis.ROOT)); 164 // // Catching the filtered list here is only OK because 165 // // FilterExprWalker#isDocOrdered() did the right thing. 166 // if(isSimpleDownAxis || (axis == -1)) 167 // walker = walker.getNextWalker(); 168 // else 169 // { 170 // boolean isLastWalker = (null == walker.getNextWalker()); 171 // if(isLastWalker) 172 // { 173 // if(walker.isDocOrdered() && (axis == Axis.DESCENDANT || 174 // axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT 175 // || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE)) 176 // return true; 177 // } 178 // return false; 179 // } 180 // } 181 // else 182 // return false; 183 // } 184 // return true; 185 // } 186 // return false; 187 // } 188 189 /** 190 * This function is used to perform some extra analysis of the iterator. 191 * 192 * @param vars List of QNames that correspond to variables. This list 193 * should be searched backwards for the first qualified name that 194 * corresponds to the variable reference qname. The position of the 195 * QName in the vector from the start of the vector will be its position 196 * in the stack frame (but variables above the globalsTop value will need 197 * to be offset to the current stack frame). 198 */ 199 public void fixupVariables(List<QName> vars, int globalsSize) 200 { 201 super.fixupVariables(vars, globalsSize); 202 203 int analysis = getAnalysisBits(); 204 if(WalkerFactory.isNaturalDocOrder(analysis)) 205 { 206 m_inNaturalOrderStatic = true; 207 } 208 else 209 { 210 m_inNaturalOrderStatic = false; 211 // System.out.println("Setting natural doc order to false: "+ 212 // WalkerFactory.getAnalysisString(analysis)); 213 } 214 215 } 216 217 }