dev@javaserverfaces.java.net

[REVIEW] Replace usages of String.split() with Util.split()

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Thu, 18 May 2006 15:21:17 -0700

Added method Util.split() to be used
in the implementation instead
of String.split(). Util.split() caches
the Pattern object where as String
recreates it each time.


SECTION: Modified Files
----------------------------

M src/com/sun/faces/util/Util.jav
  - add split(String toSplit, String regex);

M src/com/sun/faces/config/ConfigureListener.java
M src/com/sun/faces/renderkit/RenderKitImpl.java
M src/com/sun/faces/renderkit/RenderKitUtils.java
  - leverage Util.split();


SECTION: Diffs
----------------------------
Index: src/com/sun/faces/config/ConfigureListener.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/config/ConfigureListener.java,v
retrieving revision 1.74
diff -u -r1.74 ConfigureListener.java
--- src/com/sun/faces/config/ConfigureListener.java 18 May 2006
17:02:16 -0000 1.74
+++ src/com/sun/faces/config/ConfigureListener.java 18 May 2006
22:18:02 -0000
@@ -476,8 +476,8 @@
             // the web application deployment descriptor
             String paths =
                   context.getInitParameter(FacesServlet.CONFIG_FILES_ATTR);
- if (paths != null) {
- String[] tokens = paths.trim().split(",");
+ if (paths != null) {
+ String[] tokens = Util.split(paths.trim(), ",");
                 for (int i = 0; i < tokens.length; i++) {
 
                     url = getContextURLForPath(context, tokens[i].trim());
Index: src/com/sun/faces/renderkit/RenderKitImpl.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/RenderKitImpl.java,v
retrieving revision 1.40
diff -u -r1.40 RenderKitImpl.java
--- src/com/sun/faces/renderkit/RenderKitImpl.java 17 May 2006
19:00:46 -0000 1.40
+++ src/com/sun/faces/renderkit/RenderKitImpl.java 18 May 2006
22:18:02 -0000
@@ -31,16 +31,9 @@
 
 package com.sun.faces.renderkit;
 
-import com.sun.faces.RIConstants;
-import com.sun.faces.config.WebConfiguration;
-import
com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter;
-import com.sun.faces.renderkit.html_basic.HtmlResponseWriter;
-import com.sun.faces.util.MessageUtils;
-import com.sun.faces.util.Util;
-
+import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseStream;
 import javax.faces.context.ResponseWriter;
-import javax.faces.context.FacesContext;
 import javax.faces.render.RenderKit;
 import javax.faces.render.Renderer;
 import javax.faces.render.ResponseStateManager;
@@ -49,9 +42,15 @@
 import java.io.OutputStream;
 import java.io.Writer;
 import java.util.HashMap;
-import java.util.Map;
 import java.util.logging.Logger;
 
+import com.sun.faces.RIConstants;
+import com.sun.faces.config.WebConfiguration;
+import
com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter;
+import com.sun.faces.renderkit.html_basic.HtmlResponseWriter;
+import com.sun.faces.util.MessageUtils;
+import com.sun.faces.util.Util;
+
 /**
  * <B>RenderKitImpl</B> is a class ...
  * <p/>
@@ -270,8 +269,8 @@
         return new HtmlResponseWriter(writer, contentType,
characterEncoding);
     }
 
- private String[] contentTypeSplit(String contentTypeString) {
- String [] result = contentTypeString.split(",");
+ private String[] contentTypeSplit(String contentTypeString) {
+ String[] result = Util.split(contentTypeString, ",");
         for (int i = 0; i < result.length; i++) {
             int semicolon = result[i].indexOf(";");
             if (-1 != semicolon) {
Index: src/com/sun/faces/renderkit/RenderKitUtils.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/RenderKitUtils.java,v
retrieving revision 1.12
diff -u -r1.12 RenderKitUtils.java
--- src/com/sun/faces/renderkit/RenderKitUtils.java 17 May 2006
19:00:47 -0000 1.12
+++ src/com/sun/faces/renderkit/RenderKitUtils.java 18 May 2006
22:18:02 -0000
@@ -27,12 +27,12 @@
 
 import javax.faces.FacesException;
 import javax.faces.FactoryFinder;
-import javax.faces.model.SelectItem;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UISelectItem;
 import javax.faces.component.UISelectItems;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
+import javax.faces.model.SelectItem;
 import javax.faces.render.RenderKit;
 import javax.faces.render.RenderKitFactory;
 import javax.faces.render.ResponseStateManager;
@@ -41,16 +41,13 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 
 import com.sun.faces.RIConstants;
 import com.sun.faces.util.MessageUtils;
-import javax.el.ValueExpression;
+import com.sun.faces.util.Util;
 
 /**
  * <p>A set of utilities for use in {_at_link RenderKit}s.</p>
@@ -657,14 +654,14 @@
             return arrayAccept;
         // some helper variables
         String token = null;
- StringBuffer typeSubType = null;
+ StringBuilder typeSubType = null;
         String type = null;
         String subtype = null;
         String level = null;
         String quality = null;
 
- // Parse "types"
- String[] types = accept.split(CONTENT_TYPE_DELIMITER);
+ // Parse "types"
+ String[] types = Util.split(accept, CONTENT_TYPE_DELIMITER);
         int index = -1;
         for (int i=0; i<types.length; i++) {
             token = types[i].trim();
@@ -672,23 +669,23 @@
             // Check to see if our accept string contains the delimiter
that is used
             // to add uniqueness to a type/subtype, and/or delimits a
qualifier value:
             // Example: text/html;level=1,text/html;level=2; q=.5
- if (token.contains(";")) {
- String[] typeParts = token.split(";");
- typeSubType = new StringBuffer(typeParts[0].trim());
+ if (token.contains(";")) {
+ String[] typeParts = Util.split(token, ";");
+ typeSubType = new StringBuilder(typeParts[0].trim());
                 for (int j=1; j<typeParts.length; j++) {
                     quality = "not set";
                     token = typeParts[j].trim();
                     // if "level" is present, make sure it gets
included in the "type/subtype"
                     if (token.contains("level")) {
                         typeSubType.append(';').append(token);
- String[] levelParts = token.split("=");
+ String[] levelParts = Util.split(token,
"=");
                         level = levelParts[0].trim();
                         if (level.equalsIgnoreCase("level")) {
                             level = levelParts[1].trim();
                         }
                     } else {
                         quality = token;
- String[] qualityParts = quality.split("=");
+ String[] qualityParts = Util.split(quality,
"=");
                         quality = qualityParts[0].trim();
                         if (quality.equalsIgnoreCase("q")) {
                             quality = qualityParts[1].trim();
@@ -699,12 +696,12 @@
                     }
                 }
             } else {
- typeSubType = new StringBuffer(token);
+ typeSubType = new StringBuilder(token);
                 quality = "not set"; // to identifiy that no quality
was supplied
             }
             // now split type and subtype
- if (typeSubType.indexOf(CONTENT_TYPE_SUBTYPE_DELIMITER) >= 0) {
- String[] typeSubTypeParts =
typeSubType.toString().split(CONTENT_TYPE_SUBTYPE_DELIMITER);
+ if (typeSubType.indexOf(CONTENT_TYPE_SUBTYPE_DELIMITER) >=
0) {
+ String[] typeSubTypeParts =
Util.split(typeSubType.toString(), CONTENT_TYPE_SUBTYPE_DELIMITER);
                 type = typeSubTypeParts[0].trim();
                 subtype = typeSubTypeParts[1].trim();
             } else {
Index: src/com/sun/faces/util/Util.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/util/Util.java,v
retrieving revision 1.191
diff -u -r1.191 Util.java
--- src/com/sun/faces/util/Util.java 17 May 2006 19:00:50 -0000 1.191
+++ src/com/sun/faces/util/Util.java 18 May 2006 22:18:02 -0000
@@ -64,6 +64,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.regex.Pattern;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -119,6 +120,9 @@
      * Flag that enables/disables the html TLV.
      */
     private static boolean htmlTLVEnabled = true;
+
+ private static final Map<String,Pattern> patternCache =
+ new LRUMap<String,Pattern>(15);
 
 //
 // Instance Variables
@@ -990,6 +994,30 @@
             }
         }
         return result;
+ }
+
+ /**
+ * <p>A slightly more efficient version of
+ * <code>String.split()</code> which caches
+ * the <code>Pattern</code>s in an LRUMap instead of
+ * creating a new <code>Pattern</code> on each
+ * invocation.</p>
+ * @param toSplit the string to split
+ * @param regex the regex used for splitting
+ * @return the result of <code>Pattern.spit(String, int)</code>
+ */
+ public static String[] split(String toSplit, String regex) {
+ Pattern pattern = patternCache.get(regex);
+ if (pattern == null) {
+ synchronized(patternCache) {
+ pattern = patternCache.get(regex);
+ if (pattern == null) {
+ pattern = Pattern.compile(regex);
+ patternCache.put(regex, pattern);
+ }
+ }
+ }
+ return pattern.split(toSplit, 0);
     }
 
 } // end of class Util