All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.xalan.lib.ExsltStrings Maven / Gradle / Ivy

There is a newer version: 1.2.0.3-jre17-rc1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: ExsltStrings.java 1225758 2011-12-30 05:44:27Z mrglavas $
 */
package org.apache.xalan.lib;

import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.xpath.NodeSet;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * This class contains EXSLT strings extension functions.
 *
 * It is accessed by specifying a namespace URI as follows:
 * 
 *    xmlns:str="http://exslt.org/strings"
 * 
* The documentation for each function has been copied from the relevant * EXSLT Implementer page. * * @see EXSLT * @xsl.usage general */ public class ExsltStrings extends ExsltBase { /** * The str:align function aligns a string within another string. *

* The first argument gives the target string to be aligned. The second argument gives * the padding string within which it is to be aligned. *

* If the target string is shorter than the padding string then a range of characters * in the padding string are repaced with those in the target string. Which characters * are replaced depends on the value of the third argument, which gives the type of * alignment. It can be one of 'left', 'right' or 'center'. If no third argument is * given or if it is not one of these values, then it defaults to left alignment. *

* With left alignment, the range of characters replaced by the target string begins * with the first character in the padding string. With right alignment, the range of * characters replaced by the target string ends with the last character in the padding * string. With center alignment, the range of characters replaced by the target string * is in the middle of the padding string, such that either the number of unreplaced * characters on either side of the range is the same or there is one less on the left * than there is on the right. *

* If the target string is longer than the padding string, then it is truncated to be * the same length as the padding string and returned. * * @param targetStr The target string * @param paddingStr The padding string * @param type The type of alignment * * @return The string after alignment */ public static String align(String targetStr, String paddingStr, String type) { if (targetStr.length() >= paddingStr.length()) return targetStr.substring(0, paddingStr.length()); if (type.equals("right")) { return paddingStr.substring(0, paddingStr.length() - targetStr.length()) + targetStr; } else if (type.equals("center")) { int startIndex = (paddingStr.length() - targetStr.length()) / 2; return paddingStr.substring(0, startIndex) + targetStr + paddingStr.substring(startIndex + targetStr.length()); } // Default is left else { return targetStr + paddingStr.substring(targetStr.length()); } } /** * See above */ public static String align(String targetStr, String paddingStr) { return align(targetStr, paddingStr, "left"); } /** * The str:concat function takes a node set and returns the concatenation of the * string values of the nodes in that node set. If the node set is empty, it returns * an empty string. * * @param nl A node set * @return The concatenation of the string values of the nodes in that node set */ public static String concat(NodeList nl) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); String value = toString(node); if (value != null && value.length() > 0) sb.append(value); } return sb.toString(); } /** * The str:padding function creates a padding string of a certain length. * The first argument gives the length of the padding string to be created. * The second argument gives a string to be used to create the padding. This * string is repeated as many times as is necessary to create a string of the * length specified by the first argument; if the string is more than a character * long, it may have to be truncated to produce the required length. If no second * argument is specified, it defaults to a space (' '). If the second argument is * an empty string, str:padding returns an empty string. * * @param length The length of the padding string to be created * @param pattern The string to be used as pattern * * @return A padding string of the given length */ public static String padding(double length, String pattern) { if (pattern == null || pattern.length() == 0) return ""; StringBuffer sb = new StringBuffer(); int len = (int)length; int numAdded = 0; int index = 0; while (numAdded < len) { if (index == pattern.length()) index = 0; sb.append(pattern.charAt(index)); index++; numAdded++; } return sb.toString(); } /** * See above */ public static String padding(double length) { return padding(length, " "); } /** * The str:split function splits up a string and returns a node set of token * elements, each containing one token from the string. *

* The first argument is the string to be split. The second argument is a pattern * string. The string given by the first argument is split at any occurrence of * this pattern. For example: *

   * str:split('a, simple, list', ', ') gives the node set consisting of: 
   *
   * a
   * simple
   * list
   * 
* If the second argument is omitted, the default is the string ' ' (i.e. a space). * * @param str The string to be split * @param pattern The pattern * * @return A node set of split tokens */ public static NodeList split(String str, String pattern) { NodeSet resultSet = new NodeSet(); resultSet.setShouldCacheNodes(true); boolean done = false; int fromIndex = 0; int matchIndex = 0; String token = null; while (!done && fromIndex < str.length()) { matchIndex = str.indexOf(pattern, fromIndex); if (matchIndex >= 0) { token = str.substring(fromIndex, matchIndex); fromIndex = matchIndex + pattern.length(); } else { done = true; token = str.substring(fromIndex); } Document doc = DocumentHolder.m_doc; synchronized (doc) { Element element = doc.createElement("token"); Text text = doc.createTextNode(token); element.appendChild(text); resultSet.addNode(element); } } return resultSet; } /** * See above */ public static NodeList split(String str) { return split(str, " "); } /** * The str:tokenize function splits up a string and returns a node set of token * elements, each containing one token from the string. *

* The first argument is the string to be tokenized. The second argument is a * string consisting of a number of characters. Each character in this string is * taken as a delimiting character. The string given by the first argument is split * at any occurrence of any of these characters. For example: *

   * str:tokenize('2001-06-03T11:40:23', '-T:') gives the node set consisting of: 
   *
   * 2001
   * 06
   * 03
   * 11
   * 40
   * 23
   * 
* If the second argument is omitted, the default is the string ' ' * (i.e. whitespace characters). *

* If the second argument is an empty string, the function returns a set of token * elements, each of which holds a single character. *

* Note: This one is different from the tokenize extension function in the Xalan * namespace. The one in Xalan returns a set of Text nodes, while this one wraps * the Text nodes inside the token Element nodes. * * @param toTokenize The string to be tokenized * @param delims The delimiter string * * @return A node set of split token elements */ public static NodeList tokenize(String toTokenize, String delims) { NodeSet resultSet = new NodeSet(); if (delims != null && delims.length() > 0) { StringTokenizer lTokenizer = new StringTokenizer(toTokenize, delims); Document doc = DocumentHolder.m_doc; synchronized (doc) { while (lTokenizer.hasMoreTokens()) { Element element = doc.createElement("token"); element.appendChild(doc.createTextNode(lTokenizer.nextToken())); resultSet.addNode(element); } } } // If the delimiter is an empty string, create one token Element for // every single character. else { Document doc = DocumentHolder.m_doc; synchronized (doc) { for (int i = 0; i < toTokenize.length(); i++) { Element element = doc.createElement("token"); element.appendChild(doc.createTextNode(toTokenize.substring(i, i+1))); resultSet.addNode(element); } } } return resultSet; } /** * See above */ public static NodeList tokenize(String toTokenize) { return tokenize(toTokenize, " \t\n\r"); } /** * This class is not loaded until first referenced (see Java Language * Specification by Gosling/Joy/Steele, section 12.4.1) * * The static members are created when this class is first referenced, as a * lazy initialization not needing checking against null or any * synchronization. * */ private static class DocumentHolder { // Reuse the Document object to reduce memory usage. private static final Document m_doc; static { try { m_doc =DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch(ParserConfigurationException pce) { throw new org.apache.xml.utils.WrappedRuntimeException(pce); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy