You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by jw...@apache.org on 2007/05/30 18:46:25 UTC
svn commit: r542870 - in
/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal:
skin/SkinCSSParser.java skin/SkinStyleSheetParserUtils.java
style/util/CSSGenerationUtils.java
Author: jwaldman
Date: Wed May 30 09:46:24 2007
New Revision: 542870
URL: http://svn.apache.org/viewvc?view=rev&rev=542870
Log:
improve performance of skin parsing by not using regexp to split on spaces, commas, semi-colons.
In some cases I keep the regexp, but I compile the Pattern in a constant instead of calling String's
split.
Modified:
myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSParser.java
myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java
myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java
Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSParser.java?view=diff&rev=542870&r1=542869&r2=542870
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSParser.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSParser.java Wed May 30 09:46:24 2007
@@ -109,9 +109,10 @@
List<String> selectorList = new ArrayList<String>();
- // pull apart by the regexp that means
- // (zero or more whitespace) then (comma) then (zero or more whitespace)
- String[] selector = selectors.split("\\s*,\\s*");
+ // pull apart by commas
+ // don't skip whitespace since whitespace means descendant selectors in css
+ String[] selector = _splitString(selectors, ',', false);
+
String trimmedSelector;
for (int i=0; i < selector.length; i++)
{
@@ -146,9 +147,9 @@
// first, parse out any comments
Matcher matcher = _COMMENT_PATTERN.matcher(properties);
properties = matcher.replaceAll("");
-
- String[] property = properties.split("\\s*;\\s*");
-
+ // split into name and value (skip whitespace)
+ String[] property = _splitString(properties, ';', true);
+
for (int i=0; i < property.length; i++)
{
int indexOfColon = property[i].indexOf(':');
@@ -156,15 +157,58 @@
{
String name = property[i].substring(0, indexOfColon);
String value = property[i].substring(indexOfColon+1);
- _documentHandler.property((name.trim()), value.trim());
+ _documentHandler.property((name), value);
}
}
-
-
}
- private static String _trimChar(
+ /**
+ * return the array of strings computed by splitting this string
+ * around matches of the given character
+ * @param in
+ * @param charDelimiter
+ * @param skipWhitespace if true, whitespace is skipped and not included in the return Strings
+ * in the String array.
+ * @return String[] The array of Strings computed by splitting the input String
+ * around matches of the charDelimiter
+ */
+ private static String[] _splitString (
+ String in,
+ char charDelimiter,
+ boolean skipWhitespace)
+ {
+ // return a String[] with each piece that is deliminated by the inChar.
+ int length = in.length();
+ StringBuffer buffer = new StringBuffer(length);
+ List<String> splitList = new ArrayList<String>();
+
+ for (int i=0; i < length; i++)
+ {
+ char c = in.charAt(i);
+ if (c == charDelimiter)
+ {
+ // we hit the delimiter, so put it in the splitList and start a new buffer.
+ splitList.add(buffer.toString());
+ buffer = new StringBuffer(length);
+ }
+ else
+ {
+ // it's ok to put the character in the buffer if we don't want to skip whitespace
+ // or if it isn't whitespace to begin with.
+ if (!skipWhitespace || !(Character.isWhitespace(c)))
+ buffer.append(c);
+ }
+
+ }
+ // we are done with all the characters
+ String lastString = buffer.toString();
+ if (lastString.length() > 0)
+ splitList.add(lastString);
+ return splitList.toArray(_EMPTY_STRING_ARRAY);
+ }
+
+ private static String _trimChar (
String in,
char c)
{
@@ -451,6 +495,9 @@
// comments from the properties, and we use this pattern to do it.
private static final Pattern _COMMENT_PATTERN =
Pattern.compile("(?s)/\\*.*?\\*/");
+
+ private static final String[] _EMPTY_STRING_ARRAY = new String[0];
+
private static final TrinidadLogger _LOG =
TrinidadLogger.createTrinidadLogger(SkinCSSParser.class);
Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java?view=diff&rev=542870&r1=542869&r2=542870
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java Wed May 30 09:46:24 2007
@@ -34,6 +34,8 @@
import java.util.Set;
import java.util.TreeSet;
+import java.util.regex.Pattern;
+
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidadinternal.share.io.InputStreamProvider;
@@ -369,7 +371,7 @@
}
else if (propertyNameSuffix.equals(_PROPERTY_INHIBIT))
{
- for (String value : propertyValue.split("\\s"))
+ for (String value : _SPACE_PATTERN.split(propertyValue))
{
inhibitedPropertySet.add(value);
}
@@ -662,7 +664,8 @@
// if it ends with :alias, it is a namedstyle.
List<String> selectors = new ArrayList<String>();
- String[] test = value.split("selector\\(");
+
+ String[] test = _SELECTOR_PATTERN.split(value);
for (int i=0; i < test.length; i++)
{
int endIndex = test[i].indexOf(")");
@@ -898,6 +901,9 @@
private static final String _PROPERTY_RULE_REF = "rule-ref";
private static final String _PROPERTY_INHIBIT = "inhibit";
private static final String _PROPERTY_TEXT_ANTIALIAS = "text-antialias";
+
+ private static final Pattern _SPACE_PATTERN = Pattern.compile("\\s");
+ private static final Pattern _SELECTOR_PATTERN = Pattern.compile("selector\\(");
static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java?view=diff&rev=542870&r1=542869&r2=542870
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java Wed May 30 09:46:24 2007
@@ -31,8 +31,11 @@
import java.util.Set;
import java.util.Vector;
+import java.util.regex.Pattern;
+
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.OutputUtils;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SkinSelectors;
import org.apache.myfaces.trinidadinternal.style.StyleContext;
import org.apache.myfaces.trinidadinternal.style.xml.parse.PropertyNode;
@@ -234,7 +237,7 @@
if (_hasNamespacePrefix(shortSelector, namespacePrefixArray))
{
- String[] shortSelectorArray = shortSelector.split("\\s");
+ String[] shortSelectorArray = _splitStringByWhitespace(shortSelector);
shortSelector =
_getMappedNSSelector(shortStyleClassMap,
@@ -459,7 +462,7 @@
// now find each af| component selector and map
// e.g., af|menuPath::step maps to af|menuPath A
- // split the string into the spaces
+ // order the pseudo elements and classes
String base = selector.substring(afIndex);
String[] afSelectors =
_orderPseudoElementsAndClasses(base);
@@ -502,8 +505,7 @@
if (namespaceIndex > -1)
{
// get the selector up until the space.
- String[] baseSelector =
- (mappedSelector.substring(namespaceIndex)).split("\\s");
+ String[] baseSelector = _splitStringByWhitespace(mappedSelector.substring(namespaceIndex));
afComponentSelector = baseSelector[0];
afSelectorList.add(afComponentSelector);
}
@@ -759,11 +761,12 @@
}
else
{
- // there are no namespaces in this selector. TODO We still need to convert the pseudo-classes
+ // there are no namespaces in this selector.
mappedSelector = _convertPseudoClassesInSelector(selector);
}
return mappedSelector;
}
+
/**
* Runs a namespaced selector through a map.
* This could be a map to convert the
@@ -918,6 +921,7 @@
String selector,
String[] nsPrefixArray)
{
+ if (selector == null) return false;
boolean hasNamespacePrefix = false;
int numNamespaces = nsPrefixArray.length;
for (int i=0; (i < numNamespaces )&& !hasNamespacePrefix; i++)
@@ -967,7 +971,7 @@
private static String[] _orderPseudoElementsAndClasses(
String selector)
{
- String[] input = selector.split("\\s");
+ String[] input = _splitStringByWhitespace(selector);
List<String> output = new ArrayList<String>();
for (int i=0; i < input.length; i++)
@@ -1042,7 +1046,7 @@
return selector;
// split on spaces.
- String[] spacerArray = selector.split("\\s");
+ String[] spacerArray = _splitStringByWhitespace(selector);
for (int i=0; i < spacerArray.length; i++)
{
@@ -1199,6 +1203,59 @@
return completeBuffer.toString();
}
+ /**
+ * return the array of strings computed by splitting this string
+ * around one or more whitespaces This calls Character.isWhitespace to determine if it is
+ * whitespace. This is important because tabs, newlines, etc count as whitespace
+ * in the selector strings. This is faster than String's split("\\s")
+ * @param selector
+ * @return String[] The array of Strings computed by splitting the input String
+ * around one or more spaces. e.g, "af|foo af|bar" returns "af|foo" and "af|bar" in
+ * a String Array.
+ */
+ private static String[] _splitStringByWhitespace (
+ String selector)
+ {
+ // return a String[] with each piece that is deliminated by the inChar.
+ int length = selector.length();
+ StringBuffer buffer = new StringBuffer(length);
+ List<String> splitList = new ArrayList<String>();
+ boolean inWhitespace = false;
+
+ for (int i=0; i < length; i++)
+ {
+ char c = selector.charAt(i);
+ if (Character.isWhitespace(c))
+ {
+ // we hit the whitespace delimiter, so put it in the splitList and start a new buffer.
+ // ignore spaces that are in a row
+ if (!inWhitespace)
+ {
+ String bufferString = buffer.toString();
+ if (bufferString.length() > 0)
+ {
+ splitList.add(bufferString);
+ buffer = new StringBuffer(length);
+ inWhitespace = true;
+ }
+ }
+ }
+ else
+ {
+ buffer.append(c);
+ if (inWhitespace)
+ inWhitespace = false;
+ }
+ }
+ // we are done with all the characters
+ String lastString = buffer.toString();
+ if (lastString.length() > 0)
+ splitList.add(lastString);
+
+ return splitList.toArray(_EMPTY_STRING_ARRAY);
+
+ }
+
// run through the map. If it's not in the map, return the selector unchanged.
private static String _runThroughMap(Map<String, String> map, String selector)
{
@@ -1247,7 +1304,7 @@
builder.append(".");
builder.append(SkinSelectors.STATE_PREFIX);
- for (String content : pseudoClass.substring(1).split("-"))
+ for (String content : _DASH_PATTERN.split(pseudoClass.substring(1)))
{
if (content.length() > 0)
{
@@ -1273,6 +1330,9 @@
_BUILT_IN_PSEUDO_CLASSES.add(":focus");
}
+ private static final Pattern _SPACE_PATTERN = Pattern.compile("\\s");
+ private static final Pattern _DASH_PATTERN = Pattern.compile("-");
+ private static final String[] _EMPTY_STRING_ARRAY = new String[0];
private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(CSSGenerationUtils.class);
}