diff --git a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java index 6c2e9ada926..a82bfcf6478 100644 --- a/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java +++ b/jetty-ant/src/main/java/org/eclipse/jetty/ant/AntWebInfConfiguration.java @@ -28,6 +28,7 @@ import java.util.regex.Pattern; import org.apache.tools.ant.AntClassLoader; import org.eclipse.jetty.util.PatternMatcher; +import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.webapp.WebAppClassLoader; import org.eclipse.jetty.webapp.WebAppContext; @@ -88,7 +89,7 @@ public class AntWebInfConfiguration extends WebInfConfiguration } catch (URISyntaxException e) { - containerUris[i] = new URI(u.toString().replaceAll(" ", "%20")); + containerUris[i] = new URI(URIUtil.encodeSpaces(u.toString())); } i++; } diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java index 3a5a6b63a4d..4f836fddfe2 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpSenderOverFCGI.java @@ -88,7 +88,7 @@ public class HttpSenderOverFCGI extends HttpSender for (HttpField field : headers) { String name = field.getName(); - String fcgiName = "HTTP_" + name.replaceAll("-", "_").toUpperCase(Locale.ENGLISH); + String fcgiName = "HTTP_" + name.replace('-', '_').toUpperCase(Locale.ENGLISH); fcgiHeaders.add(fcgiName, field.getValue()); } diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java index 3964dea1150..7a047c6c1cc 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilter.java @@ -24,7 +24,6 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; - import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -35,6 +34,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.util.StringUtil; + /** * Inspired by nginx's try_files functionality. *
@@ -132,7 +133,7 @@ public class TryFilesFilter implements Filter path += info; if (!path.startsWith("/")) path = "/" + path; - return value.replaceAll("\\$path", path); + return StringUtil.replace(value, "$path", path); } @Override diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java index 333163dd53f..3b428888e80 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java @@ -196,7 +196,7 @@ public class MimeTypes int charset=type.toString().indexOf(";charset="); if (charset>0) { - String alt=type.toString().replace(";charset=","; charset="); + String alt = StringUtil.replace(type.toString(), ";charset=", "; charset="); CACHE.put(alt,type); TYPES.put(alt,type.asBuffer()); } diff --git a/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java b/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java new file mode 100644 index 00000000000..61419271778 --- /dev/null +++ b/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java @@ -0,0 +1,119 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@Fork(value = 3) +@State(Scope.Benchmark) +@Warmup(iterations = 4, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 4, time = 1, timeUnit = TimeUnit.SECONDS) +public class StringReplaceBenchmark +{ + @Param({"3", "100", "1000"}) + int size; + + @Param({"0", "1", "3", "50"}) + int matches; + + String input; + + @Setup(Level.Trial) + public void setupTrial() throws Exception + { + String pattern = "abc"; + StringBuilder str = new StringBuilder(); + while (str.length() < size) + { + str.append(pattern); + } + + if (matches > 0) + { + int partSize = (int)((double)str.length() / (double)matches); + for (int i = 0; i < matches; i++) + { + str.insert((i * partSize), "'"); + } + } + input = str.toString(); + } + + @Benchmark + public void testJavaStringReplace_Growth(Blackhole blackhole) + { + blackhole.consume(input.replace("'", "FOOBAR")); + } + + @Benchmark + public void testJavaStringReplace_Same(Blackhole blackhole) + { + blackhole.consume(input.replace("'", "X")); + } + + @Benchmark + public void testJavaStringReplace_Reduce(Blackhole blackhole) + { + blackhole.consume(input.replace("'", "")); + } + + @Benchmark + public void testJettyStringUtilReplace_Growth(Blackhole blackhole) + { + blackhole.consume(StringUtil.replace(input, "'", "FOOBAR")); + } + + @Benchmark + public void testJettyStringUtilReplace_Same(Blackhole blackhole) + { + blackhole.consume(StringUtil.replace(input, "'", "X")); + } + + @Benchmark + public void testJettyStringUtilReplace_Reduce(Blackhole blackhole) + { + blackhole.consume(StringUtil.replace(input, "'", "")); + } + + public static void main(String[] args) throws RunnerException + { + Options opt = new OptionsBuilder() + .include(StringReplaceBenchmark.class.getSimpleName()) +// .addProfiler(GCProfiler.class) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java index 9dfec359bba..a66ca44cc54 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java @@ -27,10 +27,10 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; -import org.eclipse.jetty.util.ClassLoadingObjectInputStream; - import com.mongodb.BasicDBObject; import com.mongodb.DBObject; +import org.eclipse.jetty.util.ClassLoadingObjectInputStream; +import org.eclipse.jetty.util.StringUtil; /** * MongoUtils @@ -69,23 +69,23 @@ public class MongoUtils throw new IllegalStateException(valueToDecode.getClass().toString()); } } - - - + public static String decodeName(String name) { - return name.replace("%2E",".").replace("%25","%"); + String cleaned = name; + cleaned = StringUtil.replace(cleaned, "%2E", "."); + cleaned = StringUtil.replace(cleaned, "%25", "%"); + return cleaned; } - - public static String encodeName(String name) { - return name.replace("%","%25").replace(".","%2E"); + String cleaned = name; + cleaned = StringUtil.replace(cleaned, "%", "%25"); + cleaned = StringUtil.replace(cleaned, ".", "%2E"); + return cleaned; } - - public static Object encodeName(Object value) throws IOException { if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date) diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java index 11af9ca7985..1ba0c301e91 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/OSGiWebInfConfiguration.java @@ -35,6 +35,7 @@ import java.util.regex.Pattern; import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory; import org.eclipse.jetty.osgi.boot.utils.Util; import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker; +import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; @@ -339,7 +340,7 @@ public class OSGiWebInfConfiguration extends WebInfConfiguration } catch (URISyntaxException e) { - uri = new URI(url.toString().replaceAll(" ", "%20")); + uri = new URI(URIUtil.encodeSpaces(url.toString())); } String key = resourcePath.startsWith("/") ? resourcePath.substring(1) : resourcePath; resourceMap.put(key + ";" + fragment.getSymbolicName(), Resource.newResource(uri)); diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java index 8791899bb18..71afb0e0904 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ProxyServletTest.java @@ -43,7 +43,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; import java.util.zip.GZIPOutputStream; - import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; @@ -670,7 +669,7 @@ public class ProxyServletTest // Make the request to the proxy, it should transparently forward to the server ContentResponse response = client.newRequest("localhost", proxyConnector.getLocalPort()) - .path((prefix + target).replaceAll("//", "/")) + .path((prefix + target).replace("//", "/")) .timeout(5, TimeUnit.SECONDS) .send(); assertEquals(200, response.getStatus()); diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java index c153be32d3c..522bcccf6b5 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java @@ -37,6 +37,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; @@ -454,13 +455,7 @@ public class AttributeNormalizer // leftover expanded.append(str.substring(offset)); - // special case for "$$" - if (expanded.indexOf("$$") >= 0) - { - return expanded.toString().replaceAll("\\$\\$","\\$"); - } - - return expanded.toString(); + return StringUtil.replace(expanded.toString(), "$$", "$"); } private String getString(String property) diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java index 1f023bd432a..acd31fa7960 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.Name; /** @@ -93,7 +94,7 @@ public class RedirectRegexRule extends RegexRule for (int g = 1; g <= matcher.groupCount(); g++) { String group = matcher.group(g); - target = target.replaceAll("\\$" + g, group); + target = StringUtil.replace(target, "$" + g, group); } target = response.encodeRedirectURL(target); @@ -110,6 +111,11 @@ public class RedirectRegexRule extends RegexRule @Override public String toString() { - return String.format("%s[%d>%s]", super.toString(), _statusCode, _location); + StringBuilder str = new StringBuilder(); + str.append(super.toString()); + str.append('[').append(_statusCode); + str.append('>').append(_location); + str.append(']'); + return str.toString(); } } diff --git a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java index 1888fdc9815..f41cbdb9032 100644 --- a/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java +++ b/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java @@ -20,11 +20,11 @@ package org.eclipse.jetty.rewrite.handler; import java.io.IOException; import java.util.regex.Matcher; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.annotation.Name; /** @@ -96,15 +96,22 @@ public class RewriteRegexRule extends RegexRule implements Rule.ApplyURI group=""; else group = Matcher.quoteReplacement(group); - target=target.replaceAll("\\$"+g,group); - if (query!=null) - query=query.replaceAll("\\$"+g,group); + String dollarGroup = "$" + g; + target = StringUtil.replace(target, dollarGroup, group); + if (query != null) + query = StringUtil.replace(query, dollarGroup, group); } if (query!=null) { if (_queryGroup) - query=query.replace("$Q",request.getQueryString()==null?"":request.getQueryString()); + { + String replacement = ""; + if (request.getQueryString() != null) + replacement = request.getQueryString(); + + query = StringUtil.replace(query, "$Q", replacement); + } request.setAttribute("org.eclipse.jetty.rewrite.handler.RewriteRegexRule.Q",query); } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index e43f4719d30..9d0ea1004b4 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -140,7 +140,8 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener int bang_slash = uri.indexOf("!/"); if (colon < 0 || bang_slash < 0 || colon > bang_slash) throw new IllegalArgumentException("Not resolved JarFile resource: " + uri); - String entry_path = uri.substring(colon + 2).replace("!/", "__").replace('/', '_').replace('.', '_'); + + String entry_path = StringUtil.sanitizeFileSystemPath(uri.substring(colon + 2)); Path tmpDirectory = Files.createTempDirectory("users_store"); tmpDirectory.toFile().deleteOnExit(); diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java index f5733470fb2..1809d5b1cea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java @@ -52,12 +52,10 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.http.PreEncodedHttpField; -import org.eclipse.jetty.http.Syntax; import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; @@ -237,7 +235,7 @@ public class Response implements HttpServletResponse if (i >= 0) { httpOnly = true; - comment = comment.replace(HTTP_ONLY_COMMENT, "").trim(); + comment = StringUtil.replace(comment.trim(), HTTP_ONLY_COMMENT, ""); if (comment.length() == 0) comment = null; } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java index 06c74a91a21..21e814f03d6 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java @@ -164,7 +164,7 @@ public class DefaultHandler extends AbstractHandler { writer.append(""); } - writer.append(contextPath.replaceAll("%", "%")); + writer.append(StringUtil.replace(contextPath, "%", "%")); if (context.isRunning()) { writer.append(""); diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ResponseHeadersTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ResponseHeadersTest.java index ffaaed78bf0..eb801824bea 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ResponseHeadersTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ResponseHeadersTest.java @@ -18,13 +18,9 @@ package org.eclipse.jetty.servlet; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - import java.io.IOException; import java.net.URLDecoder; import java.nio.ByteBuffer; - import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -38,6 +34,9 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + public class ResponseHeadersTest { public static class SimulateUpgradeServlet extends HttpServlet @@ -144,7 +143,7 @@ public class ResponseHeadersTest assertThat("Response Code",response.getStatus(),is(200)); assertThat("Response Header Content-Type",response.get("Content-Type"),is("text/plain;charset=UTF-8")); - String expected = actualPathInfo.replaceAll("%0A", " "); // replace OBS fold with space + String expected = actualPathInfo.replace("%0A", " "); // replace OBS fold with space expected = URLDecoder.decode(expected, "utf-8"); // decode the rest expected = expected.trim(); // trim whitespace at start/end assertThat("Response Header X-example", response.get("X-Example"), is(expected)); diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java index 692be858f1c..4c3393a90a4 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java @@ -26,7 +26,6 @@ import java.util.Enumeration; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -368,8 +367,8 @@ public class CrossOriginFilter implements Filter private String parseAllowedWildcardOriginToRegex(String allowedOrigin) { - String regex = allowedOrigin.replace(".", "\\."); - return regex.replace("*", ".*"); // we want to be greedy here to match multiple subdomains, thus we use .* + String regex = StringUtil.replace(allowedOrigin, ".", "\\."); + return StringUtil.replace(regex, "*", ".*"); // we want to be greedy here to match multiple subdomains, thus we use .* } private boolean isSimpleRequest(HttpServletRequest request) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java index 9b1ef63603b..0bf5a431194 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java @@ -26,14 +26,13 @@ import java.util.List; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -/** Fast String Utilities. +/** + * Fast String Utilities. * * These string utilities provide both convenience methods and * performance improvements over most standard library versions. The * main aim of the optimizations is to avoid object creation unless * absolutely required. - * - * */ public class StringUtil { @@ -62,8 +61,7 @@ public class StringUtil CHARSETS.put("iso-8859-1",__ISO_8859_1); CHARSETS.put("iso_8859_1",__ISO_8859_1); } - - /* ------------------------------------------------------------ */ + /** Convert alternate charset names (eg utf8) to normalized * name (eg UTF-8). * @param s the charset to normalize @@ -74,8 +72,7 @@ public class StringUtil String n=CHARSETS.get(s); return (n==null)?s:n; } - - /* ------------------------------------------------------------ */ + /** Convert alternate charset names (eg utf8) to normalized * name (eg UTF-8). * @param s the charset to normalize @@ -88,9 +85,7 @@ public class StringUtil String n=CHARSETS.get(s,offset,length); return (n==null)?s.substring(offset,offset+length):n; } - - /* ------------------------------------------------------------ */ public static final char[] lowercases = { '\000','\001','\002','\003','\004','\005','\006','\007', '\010','\011','\012','\013','\014','\015','\016','\017', @@ -109,7 +104,6 @@ public class StringUtil '\160','\161','\162','\163','\164','\165','\166','\167', '\170','\171','\172','\173','\174','\175','\176','\177' }; - /* ------------------------------------------------------------ */ /** * fast lower case conversion. Only works on ascii (not unicode) * @param s the string to convert @@ -122,7 +116,6 @@ public class StringUtil char[] c = null; int i=s.length(); - // look for first conversion while (i-->0) { @@ -138,7 +131,6 @@ public class StringUtil } } } - while (i-->0) { if(c[i]<=127) @@ -148,8 +140,43 @@ public class StringUtil return c==null?s:new String(c); } + /** + * Replace all characters from input string that are known to have + * special meaning in various filesytems. + * + *
+ * This will replace all of the following characters + * with a "{@code _}" (underscore). + *
+ *+ * Fast replacement for {@code java.lang.String#}{@link String#replace(CharSequence, CharSequence)} + *
+ * * @param s the input string * @param sub the string to look for * @param with the string to replace with @@ -232,27 +259,56 @@ public class StringUtil */ public static String replace(String s, String sub, String with) { - int c=0; - int i=s.indexOf(sub,c); + int c = 0; + int i = s.indexOf(sub, c); if (i == -1) + { return s; - - StringBuilder buf = new StringBuilder(s.length()+with.length()); - + } + StringBuilder buf = new StringBuilder(s.length() + with.length()); do { - buf.append(s.substring(c,i)); + buf.append(s, c, i); buf.append(with); - c=i+sub.length(); - } while ((i=s.indexOf(sub,c))!=-1); - - if (c@@ -494,7 +540,6 @@ public class StringUtil return str == null || str.isEmpty(); } - /* ------------------------------------------------------------ */ /** * Test if a string is not null and contains at least 1 non-whitespace characters in it. *
@@ -534,14 +579,11 @@ public class StringUtil
return false;
}
- /* ------------------------------------------------------------ */
public static boolean isUTF8(String charset)
{
return __UTF8.equalsIgnoreCase(charset)||__UTF8.equalsIgnoreCase(normalizeCharset(charset));
}
-
- /* ------------------------------------------------------------ */
public static String printable(String name)
{
if (name==null)
@@ -556,7 +598,7 @@ public class StringUtil
return buf.toString();
}
- /* ------------------------------------------------------------ */
+
public static String printable(byte[] b)
{
StringBuilder buf = new StringBuilder();
@@ -592,13 +634,10 @@ public class StringUtil
}
catch(Exception e)
{
- LOG.warn(e);
return s.getBytes();
}
}
-
-
-
+
/**
* Converts a binary SID to a string SID
*
@@ -631,7 +670,6 @@ public class StringUtil
// the number of subAuthorities we need to attach
int subAuthorityCount = sidBytes[1];
-
// attach each of the subAuthorities
for (int i = 0; i < subAuthorityCount; ++i)
{
@@ -670,10 +708,8 @@ public class StringUtil
// the revision byte
sidBytes[byteCount++] = (byte)Integer.parseInt(sidTokens[1]);
-
// the # of sub authorities byte
sidBytes[byteCount++] = (byte)subAuthorityCount;
-
// the certAuthority
String hexStr = Long.toHexString(Long.parseLong(sidTokens[2]));
@@ -681,7 +717,6 @@ public class StringUtil
{
hexStr = "0" + hexStr;
}
-
// place the certAuthority 6 bytes
for ( int i = 0 ; i < hexStr.length(); i = i + 2)
{
@@ -720,7 +755,6 @@ public class StringUtil
int val = 0;
boolean started = false;
boolean minus = false;
-
for (int i = from; i < string.length(); i++)
{
char b = string.charAt(i);
@@ -741,7 +775,6 @@ public class StringUtil
else
break;
}
-
if (started)
return minus?(-val):val;
throw new NumberFormatException(string);
@@ -759,7 +792,6 @@ public class StringUtil
long val = 0;
boolean started = false;
boolean minus = false;
-
for (int i = 0; i < string.length(); i++)
{
char b = string.charAt(i);
@@ -780,7 +812,6 @@ public class StringUtil
else
break;
}
-
if (started)
return minus?(-val):val;
throw new NumberFormatException(string);
@@ -799,12 +830,10 @@ public class StringUtil
{
return null;
}
-
if (str.length() <= maxSize)
{
return str;
}
-
return str.substring(0,maxSize);
}
@@ -817,20 +846,18 @@ public class StringUtil
{
if (s==null)
return new String[]{};
-
if (!s.startsWith("[") || !s.endsWith("]"))
throw new IllegalArgumentException();
if (s.length()==2)
return new String[]{};
-
return csvSplit(s,1,s.length()-2);
}
/**
- * Parse a CSV string using {@link #csvSplit(List,String, int, int)}
- * @param s The string to parse
- * @return An array of parsed values.
- */
+ * Parse a CSV string using {@link #csvSplit(List,String, int, int)}
+ * @param s The string to parse
+ * @return An array of parsed values.
+ */
public static String[] csvSplit(String s)
{
if (s==null)
@@ -851,13 +878,12 @@ public class StringUtil
return null;
if (off<0 || len<0 || off>s.length())
throw new IllegalArgumentException();
-
List Handle rfc4180-like
@@ -890,7 +916,6 @@ public class StringUtil
case PRE_DATA:
if (Character.isWhitespace(ch))
continue;
-
if ('"'==ch)
{
state=CsvSplitState.QUOTE;
@@ -902,11 +927,9 @@ public class StringUtil
list.add("");
continue;
}
-
state=CsvSplitState.DATA;
out.append(ch);
continue;
-
case DATA:
if (Character.isWhitespace(ch))
{
@@ -923,7 +946,6 @@ public class StringUtil
state=CsvSplitState.PRE_DATA;
continue;
}
-
out.append(ch);
continue;
@@ -947,7 +969,6 @@ public class StringUtil
out.append(ch);
last=-1;
continue;
-
case QUOTE:
if ('\\'==ch)
{
@@ -978,13 +999,11 @@ public class StringUtil
continue;
}
}
-
switch(state)
{
case PRE_DATA:
case POST_DATA:
break;
-
case DATA:
case QUOTE:
case SLOSH:
@@ -1011,7 +1030,6 @@ public class StringUtil
loop: for (;i\n");
- pout.write(" "+name.replace("."," .")+": ");
+ pout.write("" + name.replace(".", ZWSP + ".") + ": ");
Object value=request.getAttribute(name);
if (value instanceof File)
{
@@ -678,7 +678,7 @@ public class Dump extends HttpServlet
{
name= (String)a.nextElement();
pout.write("\n");
- pout.write(" "+name.replace("."," .")+": ");
+ pout.write("" + name.replace(".", ZWSP + ".") + ": ");
pout.write(""+ toString(getServletContext().getInitParameter(name)) + " ");
}
@@ -689,7 +689,7 @@ public class Dump extends HttpServlet
{
name= (String)a.nextElement();
pout.write("\n");
- pout.write(" "+name.replace("."," .")+": ");
+ pout.write("" + name.replace(".", ZWSP + ".") + ": ");
pout.write(""+" ");
}
@@ -1055,9 +1055,9 @@ public class Dump extends HttpServlet
{
if (s==null)
return "null";
- s=s.replaceAll("&","&");
- s=s.replaceAll("<","<");
- s=s.replaceAll(">",">");
+ s = s.replace("&","&");
+ s = s.replace("<","<");
+ s = s.replace(">",">");
return s;
}
}
" + toString(getServletContext().getAttribute(name)) + "
"+"