1 /* 2 * $Header$ 3 * $Revision$ 4 * $Date$ 5 * 6 * ==================================================================== 7 * 8 * Copyright 2000-2002 bob mcwhirter & James Strachan. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions are 13 * met: 14 * 15 * * Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 18 * * Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * * Neither the name of the Jaxen Project nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 27 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 29 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 30 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 * 38 * ==================================================================== 39 * This software consists of voluntary contributions made by many 40 * individuals on behalf of the Jaxen Project and was originally 41 * created by bob mcwhirter <bob@werken.com> and 42 * James Strachan <jstrachan@apache.org>. For more information on the 43 * Jaxen Project, please see <http://www.jaxen.org/>. 44 * 45 * $Id$ 46 */ 47 48 49 package org.jaxen.function; 50 51 import java.util.List; 52 53 import org.jaxen.Context; 54 import org.jaxen.Function; 55 import org.jaxen.FunctionCallException; 56 import org.jaxen.Navigator; 57 58 /** 59 * <p><b>4.2</b> <code><i>string</i> substring-after(<i>string</i>,<i>string</i>)</code></p> 60 * 61 * 62 * <blockquote cite="http://www.w3.org/TR/xpath"> 63 * The <b>substring-after</b> function returns the substring of the first argument string 64 * that follows the first occurrence of the second argument string in the first 65 * argument string, or the empty string if the first argument string does not contain the second argument string. 66 * For example, substring-after("1999/04/01","/") returns 04/01, 67 * and substring-after("1999/04/01","19") returns 99/04/01. 68 * </blockquote> 69 * 70 * @author bob mcwhirter (bob @ werken.com) 71 * @see <a href="https://www.w3.org/TR/xpath#function-substring-after" target="_top">Section 4.2 of the XPath Specification</a> 72 */ 73 public class SubstringAfterFunction implements Function 74 { 75 76 /** 77 * Create a new <code>SubstringAfterFunction</code> object. 78 */ 79 public SubstringAfterFunction() {} 80 81 82 /** 83 * Returns the part of the string-value of the first item in <code>args</code> 84 * that follows the string-value of the second item in <code>args</code>; 85 * or the empty string if the second string is not a substring of the first string. 86 * 87 * @param context the context at the point in the 88 * expression when the function is called 89 * @param args a list that contains two items 90 * 91 * @return a <code>String</code> containing that 92 * part of the string-value of the first item in <code>args</code> 93 * that comes before the string-value of the second item in <code>args</code> 94 * 95 * @throws FunctionCallException if <code>args</code> does not have length two 96 */ 97 public Object call(Context context, 98 List args) throws FunctionCallException 99 { 100 if (args.size() == 2) 101 { 102 return evaluate( args.get(0), 103 args.get(1), 104 context.getNavigator() ); 105 } 106 107 throw new FunctionCallException( "substring-after() requires two arguments." ); 108 } 109 110 111 /** 112 * Returns the part of <code>strArg</code> that follows the first occurence 113 * of <code>matchArg</code>; or the empty string if the 114 * <code>strArg</code> does not contain <code>matchArg</code> 115 * 116 * @param strArg the string from which the substring is extracted 117 * @param matchArg the string that marks the boundary of the substring 118 * @param nav the <code>Navigator</code> used to calculate the string-values of 119 * the first two arguments 120 * 121 * @return a <code>String</code> containing 122 * the part of <code>strArg</code> that precedes the first occurence 123 * of <code>matchArg</code> 124 * 125 */ 126 public static String evaluate(Object strArg, 127 Object matchArg, 128 Navigator nav) 129 { 130 String str = StringFunction.evaluate( strArg, 131 nav ); 132 133 String match = StringFunction.evaluate( matchArg, 134 nav ); 135 136 int loc = str.indexOf(match); 137 138 if ( loc < 0 ) 139 { 140 return ""; 141 } 142 143 return str.substring(loc+match.length()); 144 } 145 }