1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Copyright 1999-2004 The Apache Software Foundation. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 /* 20 * $Id: ExsltStrings.java,v 1.1.2.1 2005/08/01 02:08:48 jeffsuttor Exp $ 21 */ 22 package com.sun.org.apache.xalan.internal.lib; 23 24 import java.util.StringTokenizer; 25 import com.sun.org.apache.xpath.internal.NodeSet; 26 import jdk.xml.internal.JdkXmlUtils; 27 28 import org.w3c.dom.Document; 29 import org.w3c.dom.Element; 30 import org.w3c.dom.Node; 31 import org.w3c.dom.NodeList; 32 import org.w3c.dom.Text; 33 34 /** 35 * This class contains EXSLT strings extension functions. 36 * 37 * It is accessed by specifying a namespace URI as follows: 38 * <pre> 39 * xmlns:str="http://exslt.org/strings" 40 * </pre> 41 * The documentation for each function has been copied from the relevant 42 * EXSLT Implementer page. 43 * 44 * @see <a href="http://www.exslt.org/">EXSLT</a> 45 46 * @xsl.usage general 47 */ 48 public class ExsltStrings extends ExsltBase 49 { 50 51 /** 52 * The str:align function aligns a string within another string. 53 * <p> 54 * The first argument gives the target string to be aligned. The second argument gives 55 * the padding string within which it is to be aligned. 56 * <p> 57 * If the target string is shorter than the padding string then a range of characters 58 * in the padding string are repaced with those in the target string. Which characters 59 * are replaced depends on the value of the third argument, which gives the type of 60 * alignment. It can be one of 'left', 'right' or 'center'. If no third argument is 61 * given or if it is not one of these values, then it defaults to left alignment. 62 * <p> 63 * With left alignment, the range of characters replaced by the target string begins 64 * with the first character in the padding string. With right alignment, the range of 65 * characters replaced by the target string ends with the last character in the padding 66 * string. With center alignment, the range of characters replaced by the target string 67 * is in the middle of the padding string, such that either the number of unreplaced 68 * characters on either side of the range is the same or there is one less on the left 69 * than there is on the right. 70 * <p> 71 * If the target string is longer than the padding string, then it is truncated to be 72 * the same length as the padding string and returned. 73 * 74 * @param targetStr The target string 75 * @param paddingStr The padding string 76 * @param type The type of alignment 77 * 78 * @return The string after alignment 79 */ 80 public static String align(String targetStr, String paddingStr, String type) 81 { 82 if (targetStr.length() >= paddingStr.length()) 83 return targetStr.substring(0, paddingStr.length()); 84 85 if (type.equals("right")) 86 { 87 return paddingStr.substring(0, paddingStr.length() - targetStr.length()) + targetStr; 88 } 89 else if (type.equals("center")) 90 { 91 int startIndex = (paddingStr.length() - targetStr.length()) / 2; 92 return paddingStr.substring(0, startIndex) + targetStr + paddingStr.substring(startIndex + targetStr.length()); 93 } 94 // Default is left 95 else 96 { 97 return targetStr + paddingStr.substring(targetStr.length()); 98 } 99 } 100 101 /** 102 * See above 103 */ 104 public static String align(String targetStr, String paddingStr) 105 { 106 return align(targetStr, paddingStr, "left"); 107 } 108 109 /** 110 * The str:concat function takes a node set and returns the concatenation of the 111 * string values of the nodes in that node set. If the node set is empty, it returns 112 * an empty string. 113 * 114 * @param nl A node set 115 * @return The concatenation of the string values of the nodes in that node set 116 */ 117 public static String concat(NodeList nl) 118 { 119 StringBuffer sb = new StringBuffer(); 120 for (int i = 0; i < nl.getLength(); i++) 121 { 122 Node node = nl.item(i); 123 String value = toString(node); 124 125 if (value != null && value.length() > 0) 126 sb.append(value); 127 } 128 129 return sb.toString(); 130 } 131 132 /** 133 * The str:padding function creates a padding string of a certain length. 134 * The first argument gives the length of the padding string to be created. 135 * The second argument gives a string to be used to create the padding. This 136 * string is repeated as many times as is necessary to create a string of the 137 * length specified by the first argument; if the string is more than a character 138 * long, it may have to be truncated to produce the required length. If no second 139 * argument is specified, it defaults to a space (' '). If the second argument is 140 * an empty string, str:padding returns an empty string. 141 * 142 * @param length The length of the padding string to be created 143 * @param pattern The string to be used as pattern 144 * 145 * @return A padding string of the given length 146 */ 147 public static String padding(double length, String pattern) 148 { 149 if (pattern == null || pattern.length() == 0) 150 return ""; 151 152 StringBuffer sb = new StringBuffer(); 153 int len = (int)length; 154 int numAdded = 0; 155 int index = 0; 156 while (numAdded < len) 157 { 158 if (index == pattern.length()) 159 index = 0; 160 161 sb.append(pattern.charAt(index)); 162 index++; 163 numAdded++; 164 } 165 166 return sb.toString(); 167 } 168 169 /** 170 * See above 171 */ 172 public static String padding(double length) 173 { 174 return padding(length, " "); 175 } 176 177 /** 178 * The str:split function splits up a string and returns a node set of token 179 * elements, each containing one token from the string. 180 * <p> 181 * The first argument is the string to be split. The second argument is a pattern 182 * string. The string given by the first argument is split at any occurrence of 183 * this pattern. For example: 184 * <pre> 185 * str:split('a, simple, list', ', ') gives the node set consisting of: 186 * 187 * <token>a</token> 188 * <token>simple</token> 189 * <token>list</token> 190 * </pre> 191 * If the second argument is omitted, the default is the string ' ' (i.e. a space). 192 * 193 * @param str The string to be split 194 * @param pattern The pattern 195 * 196 * @return A node set of split tokens 197 */ 198 public static NodeList split(String str, String pattern) 199 { 200 201 202 NodeSet resultSet = new NodeSet(); 203 resultSet.setShouldCacheNodes(true); 204 205 boolean done = false; 206 int fromIndex = 0; 207 int matchIndex = 0; 208 String token = null; 209 210 while (!done && fromIndex < str.length()) 211 { 212 matchIndex = str.indexOf(pattern, fromIndex); 213 if (matchIndex >= 0) 214 { 215 token = str.substring(fromIndex, matchIndex); 216 fromIndex = matchIndex + pattern.length(); 217 } 218 else 219 { 220 done = true; 221 token = str.substring(fromIndex); 222 } 223 224 Document doc = JdkXmlUtils.getDOMDocument(); 225 synchronized (doc) 226 { 227 Element element = doc.createElement("token"); 228 Text text = doc.createTextNode(token); 229 element.appendChild(text); 230 resultSet.addNode(element); 231 } 232 } 233 234 return resultSet; 235 } 236 237 /** 238 * See above 239 */ 240 public static NodeList split(String str) 241 { 242 return split(str, " "); 243 } 244 245 /** 246 * The str:tokenize function splits up a string and returns a node set of token 247 * elements, each containing one token from the string. 248 * <p> 249 * The first argument is the string to be tokenized. The second argument is a 250 * string consisting of a number of characters. Each character in this string is 251 * taken as a delimiting character. The string given by the first argument is split 252 * at any occurrence of any of these characters. For example: 253 * <pre> 254 * str:tokenize('2001-06-03T11:40:23', '-T:') gives the node set consisting of: 255 * 256 * <token>2001</token> 257 * <token>06</token> 258 * <token>03</token> 259 * <token>11</token> 260 * <token>40</token> 261 * <token>23</token> 262 * </pre> 263 * If the second argument is omitted, the default is the string '	

 ' 264 * (i.e. whitespace characters). 265 * <p> 266 * If the second argument is an empty string, the function returns a set of token 267 * elements, each of which holds a single character. 268 * <p> 269 * Note: This one is different from the tokenize extension function in the Xalan 270 * namespace. The one in Xalan returns a set of Text nodes, while this one wraps 271 * the Text nodes inside the token Element nodes. 272 * 273 * @param toTokenize The string to be tokenized 274 * @param delims The delimiter string 275 * 276 * @return A node set of split token elements 277 */ 278 public static NodeList tokenize(String toTokenize, String delims) 279 { 280 281 282 NodeSet resultSet = new NodeSet(); 283 284 if (delims != null && delims.length() > 0) 285 { 286 StringTokenizer lTokenizer = new StringTokenizer(toTokenize, delims); 287 288 Document doc = JdkXmlUtils.getDOMDocument(); 289 synchronized (doc) 290 { 291 while (lTokenizer.hasMoreTokens()) 292 { 293 Element element = doc.createElement("token"); 294 element.appendChild(doc.createTextNode(lTokenizer.nextToken())); 295 resultSet.addNode(element); 296 } 297 } 298 } 299 // If the delimiter is an empty string, create one token Element for 300 // every single character. 301 else 302 { 303 304 Document doc = JdkXmlUtils.getDOMDocument(); 305 synchronized (doc) 306 { 307 for (int i = 0; i < toTokenize.length(); i++) 308 { 309 Element element = doc.createElement("token"); 310 element.appendChild(doc.createTextNode(toTokenize.substring(i, i+1))); 311 resultSet.addNode(element); 312 } 313 } 314 } 315 316 return resultSet; 317 } 318 319 /** 320 * See above 321 */ 322 public static NodeList tokenize(String toTokenize) 323 { 324 return tokenize(toTokenize, " \t\n\r"); 325 } 326 }