ASF Bugzilla – Attachment 25711 Details for
Bug 49554
Clean up Functions
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to clean up Functions
taglibs-49554.patch (text/plain), 22.25 KB, created by
Jeremy Boynes
on 2010-07-05 16:01:53 UTC
(
hide
)
Description:
Patch to clean up Functions
Filename:
MIME Type:
Creator:
Jeremy Boynes
Created:
2010-07-05 16:01:53 UTC
Size:
22.25 KB
patch
obsolete
>Index: pom.xml >=================================================================== >--- pom.xml (revision 960668) >+++ pom.xml (working copy) >@@ -120,6 +120,14 @@ > </dependencies> > > <build> >+ <resources> >+ <resource> >+ <directory>src/main/java</directory> >+ <includes> >+ <include>**/*.properties</include> >+ </includes> >+ </resource> >+ </resources> > <plugins> > <plugin> > <groupId>org.apache.maven.plugins</groupId> >@@ -137,7 +145,8 @@ > <includes> > <include>org/apache/taglibs/standard/lang/jstl/test/StaticFunctionTests.java</include> > <include>org/apache/taglibs/standard/TestVersion.java</include> >- <include>org/apache/taglibs/standard/tag/**/Test*.java</include> >+ <include>org/apache/taglibs/standard/functions/TestFunctions.java</include> >+ <include>org/apache/taglibs/standard/tag/common/core/TestSetSupport.java</include> > </includes> > <excludes> > <!-- Old tests --> >Index: src/test/java/org/apache/taglibs/standard/functions/TestFunctions.java >=================================================================== >--- src/test/java/org/apache/taglibs/standard/functions/TestFunctions.java (revision 0) >+++ src/test/java/org/apache/taglibs/standard/functions/TestFunctions.java (revision 0) >@@ -0,0 +1,114 @@ >+/* >+ * 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. >+ */ >+package org.apache.taglibs.standard.functions; >+ >+import org.apache.taglibs.standard.resources.Resources; >+import org.junit.Assert; >+import org.junit.Test; >+ >+import javax.servlet.jsp.JspTagException; >+import java.util.Arrays; >+import java.util.Collections; >+ >+import static org.apache.taglibs.standard.functions.Functions.*; >+/** >+ */ >+public class TestFunctions { >+ >+ @Test >+ public void testSubstring() { >+ Assert.assertEquals("el", substring("Hello", 1, 3)); >+ Assert.assertEquals("", substring("Hello", 10, 0)); >+ Assert.assertEquals("He", substring("Hello", -1, 2)); >+ Assert.assertEquals("Hello", substring("Hello", -4, -1)); >+ Assert.assertEquals("ello", substring("Hello", 1, -1)); >+ Assert.assertEquals("ello", substring("Hello", 1, 10)); >+ Assert.assertEquals("", substring("Hello", 3, 1)); >+ Assert.assertEquals("", substring("Hello", 10, 6)); >+ Assert.assertEquals("Hello", substring("Hello", -1, -4)); >+ } >+ >+ @Test >+ public void testSubstringAfter() { >+ Assert.assertEquals("lo", substringAfter("Hello", "el")); >+ Assert.assertEquals("", substringAfter("", "el")); >+ Assert.assertEquals("Hello", substringAfter("Hello", "")); >+ Assert.assertEquals("", substringAfter("", "lx")); >+ Assert.assertEquals("lo All", substringAfter("Hello All", "l")); >+ } >+ >+ @Test >+ public void testSubstringBefore() { >+ Assert.assertEquals("H", substringBefore("Hello", "el")); >+ Assert.assertEquals("", substringBefore("", "el")); >+ Assert.assertEquals("", substringBefore("Hello", "")); >+ Assert.assertEquals("", substringBefore("", "lx")); >+ Assert.assertEquals("He", substringBefore("Hello All", "l")); >+ } >+ >+ @Test >+ public void testReplace() { >+ Assert.assertEquals("Hxxlo", replace("Hello", "el", "xx")); >+ Assert.assertEquals("Hexxxxo", replace("Hello", "l", "xx")); >+ Assert.assertEquals("", replace("", "l", "xx")); >+ Assert.assertEquals("Heo", replace("Hello", "l", "")); >+ Assert.assertEquals("Hello", replace("Hello", "", "xx")); >+ Assert.assertEquals("Hellllo", replace("Hello", "l", "ll")); >+ Assert.assertEquals("Hello", replace("Hello", "x", "ll")); >+ } >+ >+ @Test >+ public void testSplit() { >+ Assert.assertArrayEquals(new String[]{"a", "b", "c"}, split("a:b:c", ":")); >+ Assert.assertArrayEquals(new String[]{"a", "b", "c"}, split("a:b/c", ":/")); >+ Assert.assertArrayEquals(new String[]{"a", "b", "c"}, split("a:b/c", "/:")); >+ Assert.assertArrayEquals(new String[]{"a", "b"}, split("a:b:", ":")); >+ Assert.assertArrayEquals(new String[]{"a:b:c"}, split("a:b:c", "x")); >+ Assert.assertArrayEquals(new String[]{""}, split("", "")); >+ Assert.assertArrayEquals(new String[]{""}, split("", ":")); >+ Assert.assertArrayEquals(new String[]{"Hello"}, split("Hello", "")); >+ } >+ >+ @Test >+ public void testJoin() { >+ Assert.assertEquals("a:b:c", join(new String[]{"a", "b", "c"}, ":")); >+ Assert.assertEquals("abc", join(new String[]{"a", "b", "c"}, "")); >+ Assert.assertEquals("axxbxxc", join(new String[]{"a", "b", "c"}, "xx")); >+ Assert.assertEquals("", join(null, "")); >+ Assert.assertEquals("", join(new String[]{}, ":")); >+ Assert.assertEquals("a:null:c", join(new String[]{"a", null, "c"}, ":")); >+ Assert.assertEquals("a", join(new String[]{"a"}, ":")); >+ Assert.assertEquals("null", join(new String[]{null}, ":")); >+ } >+ >+ @Test >+ public void testLength() throws Exception { >+ Assert.assertEquals(0, length(null)); >+ Assert.assertEquals(0, length("")); >+ Assert.assertEquals(3, length(new int[]{1,2,3})); >+ Assert.assertEquals(3, length(Arrays.asList(1,2,3))); >+ Assert.assertEquals(3, length(Arrays.asList(1,2,3).iterator())); >+ Assert.assertEquals(3, length(Collections.enumeration(Arrays.asList(1,2,3)))); >+ Assert.assertEquals(1, length(Collections.singletonMap("Hello", "World"))); >+ try { >+ length(3); >+ Assert.fail(); >+ } catch (JspTagException e) { >+ Assert.assertEquals(Resources.getMessage("PARAM_BAD_VALUE"), e.getMessage()); >+ } >+ } >+} >Index: src/main/java/org/apache/taglibs/standard/functions/Functions.java >=================================================================== >--- src/main/java/org/apache/taglibs/standard/functions/Functions.java (revision 960668) >+++ src/main/java/org/apache/taglibs/standard/functions/Functions.java (working copy) >@@ -30,7 +30,13 @@ > import org.apache.taglibs.standard.tag.common.core.Util; > > /** >- * <p>JSTL Functions</p> >+ * Static functions that extend the Expression Language with standardized behaviour >+ * commonly used by page authors. >+ * >+ * <strong>Implementation Note:</strong> When passing a String parameter, section >+ * 1.18.2 of the EL specification requires the container to coerce a null value to an >+ * empty string. These implementation assume such behaviour and do not check for null >+ * parameters. Passing a null will generally trigger a NullPointerException. > * > * @author Pierre Delisle > */ >@@ -41,14 +47,22 @@ > // String capitalization > > /** >- * Converts all of the characters of the input string to upper case. >+ * Converts all of the characters of the input string to upper case according to the >+ * semantics of method <code>String#toUpperCase()</code>. >+ * >+ * @param input the input string on which the transformation to upper case is applied >+ * @return the input string transformed to upper case > */ > public static String toUpperCase(String input) { > return input.toUpperCase(); > } > > /** >- * Converts all of the characters of the input string to lower case. >+ * Converts all of the characters of the input string to lower case according to the >+ * semantics of method <code>String#toLowerCase()</code>. >+ * >+ * @param input the input string on which the transformation to lower case is applied >+ * @return the input string transformed to lower case > */ > public static String toLowerCase(String input) { > return input.toLowerCase(); >@@ -56,52 +70,105 @@ > > //********************************************************************* > // Substring processing >- >+ >+ /** >+ * Returns the index (0-based) withing a string of the first occurrence of a specified >+ * substring according to the semantics of the method <code>String#indexOf()</code>. >+ * >+ * If <code>substring</code> is empty, this matches the beginning of the string and the >+ * value returned is 0. >+ * >+ * @param input the input string on which the function is applied >+ * @param substring the substring to search for in the input string >+ * @return the 0-based index of the first matching substring, or -1 if it does not occur >+ */ > public static int indexOf(String input, String substring) { >- if (input == null) input = ""; >- if (substring == null) substring = ""; > return input.indexOf(substring); >- } >+ } > >+ /** >+ * Tests if a string contains the specified substring. >+ * >+ * @param input the input string on which the function is applied >+ * @param substring the substring tested for >+ * @return true if the character sequence represented by the substring >+ * exists in the string >+ */ > public static boolean contains(String input, String substring) { >- return indexOf(input, substring) != -1; >+ return input.contains(substring); > } > >+ /** >+ * Tests if a string contains the specified substring in a case insensitive way. >+ * Equivalent to <code>fn:contains(fn:toUpperCase(string), fn:toUpperCase(substring))</code>. >+ * >+ * @param input the input string on which the function is applied >+ * @param substring the substring tested for >+ * @return true if the character sequence represented by the substring >+ * exists in the string >+ */ > public static boolean containsIgnoreCase(String input, String substring) { >- if (input == null) input = ""; >- if (substring == null) substring = ""; >- String inputUC = input.toUpperCase(); >- String substringUC = substring.toUpperCase(); >- return indexOf(inputUC, substringUC) != -1; >- } >+ return contains(input.toUpperCase(), substring.toUpperCase()); >+ } > >- public static boolean startsWith(String input, String substring) { >- if (input == null) input = ""; >- if (substring == null) substring = ""; >- return input.startsWith(substring); >+ /** >+ * Tests if a string starts with the specified prefix according to the semantics >+ * of <code>String#startsWith()</code>. >+ * >+ * @param input the input string on which the function is applied >+ * @param prefix the prefix to be matched >+ * @return true if the input string starts with the prefix >+ */ >+ public static boolean startsWith(String input, String prefix) { >+ return input.startsWith(prefix); > } > >- public static boolean endsWith(String input, String substring) { >- if (input == null) input = ""; >- if (substring == null) substring = ""; >- return input.endsWith(substring); >- } >- >+ /** >+ * Tests if a string ends with the specified suffix according to the semantics >+ * of <code>String#endsWith()</code>. >+ * >+ * @param input the input string on which the function is applied >+ * @param suffix the suffix to be matched >+ * @return true if the input string ends with the suffix >+ */ >+ public static boolean endsWith(String input, String suffix) { >+ return input.endsWith(suffix); >+ } >+ >+ /** >+ * Returns a subset of a string according to the semantics of <code>String#substring()</code> >+ * with additional semantics as follows: >+ * <ul> >+ * <li>if <code>beginIndex < 0</code> its value is adjusted to 0</li> >+ * <li>if <code>endIndex < 0 or greater than the string length</code>, >+ * its value is adjusted to the length of the string</li> >+ * <li>if <code>endIndex < beginIndex</code>, an empty string is returned</li> >+ * </ul> >+ * >+ * @param input the input string on which the substring function is applied >+ * @param beginIndex the beginning index (0-based), inclusive >+ * @param endIndex the end index (0-based), exclusive >+ * @return a subset of string >+ */ > public static String substring(String input, int beginIndex, int endIndex) { >- if (input == null) input = ""; >- if (beginIndex >= input.length()) return ""; > if (beginIndex < 0) beginIndex = 0; > if (endIndex < 0 || endIndex > input.length()) endIndex = input.length(); > if (endIndex < beginIndex) return ""; > return input.substring(beginIndex, endIndex); >- } >- >+ } >+ >+ /** >+ * Returns a subset of a string following the first occurrence of a specific substring. >+ * >+ * If the substring is empty, it matches the beginning of the input string and the >+ * entire input string is returned. If the substring does not occur, an empty string is returned. >+ * >+ * @param input the input string on which the substring function is applied >+ * @param substring the substring that delimits the beginning of the subset >+ * of the input string to be returned >+ * @return a substring of the input string that starts at the first character after the specified substring >+ */ > public static String substringAfter(String input, String substring) { >- if (input == null) input = ""; >- if (input.length() == 0) return ""; >- if (substring == null) substring = ""; >- if (substring.length() == 0) return input; >- > int index = input.indexOf(substring); > if (index == -1) { > return ""; >@@ -110,12 +177,18 @@ > } > } > >+ /** >+ * Returns a subset of a string immediately before the first occurrence of a specific substring. >+ * >+ * If the substring is empty, it matches the beginning of the input string and an empty string is returned. >+ * If the substring does not occur, an empty string is returned. >+ * >+ * @param input the input string on which the substring function is applied >+ * @param substring the substring that delimits the beginning of the subset >+ * of the input string to be returned >+ * @return a substring of the input string that starts at the first character after the specified substring >+ */ > public static String substringBefore(String input, String substring) { >- if (input == null) input = ""; >- if (input.length() == 0) return ""; >- if (substring == null) substring = ""; >- if (substring.length() == 0) return ""; >- > int index = input.indexOf(substring); > if (index == -1) { > return ""; >@@ -126,75 +199,124 @@ > > //********************************************************************* > // Character replacement >- >+ >+ /** >+ * Escapes characters that could be interpreted as XML markup as defined by the <code><c:out> action. >+ * >+ * @param input the string to escape >+ * @return escaped string >+ */ > public static String escapeXml(String input) { >- if (input == null) return ""; > return Util.escapeXml(input); > } >- >+ >+ /** >+ * removes whitespace from both ends of a string according to the semantics of <code>String#trim()</code>. >+ * >+ * @param input the input string to be trimmed >+ * @return the trimmed string >+ */ > public static String trim(String input) { >- if (input == null) return ""; > return input.trim(); >- } >+ } > >- public static String replace( >- String input, >- String substringBefore, >- String substringAfter) >+ /** >+ * Returns a string resulting from replacing all occurrences of a "before" substring with an "after" substring. >+ * The string is processed once and not reprocessed for further replacements. >+ * >+ * @param input the string on which the replacement is to be applied >+ * @param before the substring to replace >+ * @param after the replacement substring >+ * @return a string with before replaced with after >+ */ >+ public static String replace(String input, String before, String after) > { >- if (input == null) input = ""; >- if (input.length() == 0) return ""; >- if (substringBefore == null) substringBefore = ""; >- if (substringBefore.length() == 0) return input; >- >- StringBuffer buf = new StringBuffer(input.length()); >- int startIndex = 0; >- int index; >- while ((index = input.indexOf(substringBefore, startIndex)) != -1) { >- buf.append(input.substring(startIndex, index)).append(substringAfter); >- startIndex = index + substringBefore.length(); >+ if (before.length() == 0) { >+ return input; > } >- return buf.append(input.substring(startIndex)).toString(); >+ return input.replace(before, after); > } >- >- public static String[] split( >- String input, >- String delimiters) >+ >+ /** >+ * Splits a string into an array of substrings according to the semantics of <code>StringTokenizer</code>. >+ * If the input string is empty, a single element array containing an empty string is returned. >+ * If the delimiters are empty, a single element array containing the input string is returned. >+ * >+ * @param input the string to split >+ * @param delimiters characters used to split the string >+ * @return an array of strings >+ */ >+ public static String[] split(String input, String delimiters) > { >- String[] array; >- if (input == null) input = ""; >- if (input.length() == 0) { >- array = new String[1]; >- array[0] = ""; >- return array; >+ if (input.length() == 0 || delimiters.length() == 0) { >+ return new String[] { input }; > } >- >- if (delimiters == null) delimiters = ""; > > StringTokenizer tok = new StringTokenizer(input, delimiters); >- int count = tok.countTokens(); >- array = new String[count]; >+ String[] array = new String[tok.countTokens()]; > int i = 0; > while (tok.hasMoreTokens()) { > array[i++] = tok.nextToken(); > } > return array; >- } >- >+ } >+ >+ /** >+ * Joins all elements of an array into a string. >+ * >+ * <strong>Implementation Note</strong>: The specification does not define what happens when >+ * elements in the array are null. For compatibility with previous implementations, the string >+ * "null" is used although EL conventions would suggest an empty string might be better. >+ * >+ * @param array an array of strings to be joined >+ * @param separator used to separate the joined strings >+ * @return all array elements joined into one string with the specified separator >+ */ >+ public static String join(String[] array, String separator) { >+ if (array == null || array.length == 0) { >+ return ""; >+ } >+ if (array.length == 1) { >+ return array[0] == null ? "null" : array[0]; >+ } >+ >+ StringBuilder buf = new StringBuilder(); >+ buf.append(array[0]); >+ for (int i = 1; i < array.length; i++) { >+ buf.append(separator).append(array[i]); >+ } >+ return buf.toString(); >+ } >+ > //********************************************************************* > // Collections processing >- >+ >+ /** >+ * Returns the number of items in a collection or the number of characters in a string. >+ * The collection can be of any type supported for the <code>items</code> attribute of >+ * the <code><c:forEach></code> action. >+ * >+ * @param obj the collection or string whose length should be computed >+ * @return the length of the collection or string; 0 if obj is null >+ * @throws JspTagException if the type is not valid >+ */ > public static int length(Object obj) throws JspTagException { >- if (obj == null) return 0; >+ if (obj == null) { >+ return 0; >+ } > >- if (obj instanceof String) return ((String)obj).length(); >- if (obj instanceof Collection) return ((Collection)obj).size(); >- if (obj instanceof Map) return ((Map)obj).size(); >- >- int count = 0; >+ if (obj instanceof String) { >+ return ((String) obj).length(); >+ } >+ if (obj instanceof Collection) { >+ return ((Collection) obj).size(); >+ } >+ if (obj instanceof Map) { >+ return ((Map) obj).size(); >+ } > if (obj instanceof Iterator) { >+ int count = 0; > Iterator iter = (Iterator)obj; >- count = 0; > while (iter.hasNext()) { > count++; > iter.next(); >@@ -203,30 +325,16 @@ > } > if (obj instanceof Enumeration) { > Enumeration enum_ = (Enumeration)obj; >- count = 0; >+ int count = 0; > while (enum_.hasMoreElements()) { > count++; > enum_.nextElement(); > } > return count; > } >- try { >- count = Array.getLength(obj); >- return count; >- } catch (IllegalArgumentException ex) {} >- throw new JspTagException(Resources.getMessage("PARAM_BAD_VALUE")); >+ if (obj.getClass().isArray()) { >+ return Array.getLength(obj); >+ } >+ throw new JspTagException(Resources.getMessage("PARAM_BAD_VALUE")); > } >- >- public static String join(String[] array, String separator) { >- if (array == null) return ""; >- if (separator == null) separator = ""; >- >- StringBuffer buf = new StringBuffer(); >- for (int i=0; i<array.length; i++) { >- buf.append(array[i]); >- if (i < array.length-1) buf.append(separator); >- } >- >- return buf.toString(); >- } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 49554
: 25711