org.apache.brooklyn.util.text.StringEscapes Maven / Gradle / Ivy
Show all versions of brooklyn-utils-common Show documentation
/*
* 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.brooklyn.util.text;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.net.URLParamEncoder;
import org.apache.brooklyn.util.yaml.Yamls;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
public class StringEscapes {
private static final Logger log = LoggerFactory.getLogger(StringEscapes.class);
/** if s is wrapped in double quotes containing no unescaped double quotes */
public static boolean isWrappedInDoubleQuotes(String s) {
if (Strings.isEmpty(s)) return false;
if (!s.startsWith("\"") || !s.endsWith("\"")) return false;
return (s.substring(1, s.length()-1).replace("\\\\", "").replace("\\\"", "").indexOf("\"")==-1);
}
/** if s is wrapped in single quotes containing no unescaped single quotes */
public static boolean isWrappedInSingleQuotes(String s) {
if (Strings.isEmpty(s)) return false;
if (!s.startsWith("\'") || !s.endsWith("\'")) return false;
return (s.substring(1, s.length()-1).replace("\\\\", "").replace("\\\'", "").indexOf("\'")==-1);
}
/** if s is wrapped in single or double quotes containing no unescaped quotes of that type */
public static boolean isWrappedInMatchingQuotes(String s) {
return isWrappedInDoubleQuotes(s) || isWrappedInSingleQuotes(s);
}
/**
* Encodes a string suitable for use as a parameter in a URL.
*/
public static String escapeUrlParam(String input) {
return URLParamEncoder.encode(input);
}
/**
* Encodes a string suitable for use as a URL in an HTML form: space to +, and high-numbered chars assuming UTF-8.
* However, it will also convert the first "http://" to "http%3A%2F%2F" so is not suitable for converting an
* entire URL.
*
* Also note that parameter-conversion doesn't work in way you'd expect when trying to create a "normal" url.
* See http://stackoverflow.com/questions/724043/http-url-address-encoding-in-java
*
* @see escapeUrlParam(String), and consider using that instead.
*/
public static String escapeHtmlFormUrl(String url) {
try {
return URLEncoder.encode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw Exceptions.propagate(e);
}
}
/** encodes a string to SQL, that is ' becomes '' */
public static String escapeSql(String x) {
//identical to apache commons StringEscapeUtils.escapeSql
if (x==null) return null;
return x.replaceAll("'", "''");
}
public static class BashStringEscapes {
// single quotes don't permit escapes! e.g. echo 'hello \' world' doesn't work;
// you must do 'hello '\'' world' (to get "hello ' world")
public static class WrapBashFunction implements Function {
@Override
public String apply(String input) {
return wrapBash(input);
}
}
public static Function wrapBash() {
return new WrapBashFunction();
}
/** wraps plain text in double quotes escaped for use in bash double-quoting */
public static String wrapBash(String value) {
StringBuilder out = new StringBuilder();
try {
wrapBash(value, out);
} catch (IOException e) {
//shouldn't happen for string buffer
throw Exceptions.propagate(e);
}
return out.toString();
}
/** @see #wrapBash(String) */
public static void wrapBash(String value, Appendable out) throws IOException {
out.append('"');
escapeLiteralForDoubleQuotedBash(value, out);
out.append('"');
}
private static void escapeLiteralForDoubleQuotedBash(String value, Appendable out) throws IOException {
for (int i=0; i wrapJavaStrings(Iterable values) {
if (values==null) return null;
List result = MutableList.of();
for (String v: values) result.add(wrapJavaString(v));
return result;
}
/** as {@link #unwrapJavaString(String)} if the given string is wrapped in double quotes;
* otherwise just returns the given string */
public static String unwrapJavaStringIfWrapped(String s) {
if (!StringEscapes.isWrappedInDoubleQuotes(s)) return s;
return unwrapJavaString(s);
}
/** converts normal string to java escaped for double-quotes and wrapped in those double quotes */
public static void wrapJavaString(String value, Appendable out) throws IOException {
if (value==null) {
out.append("null");
} else {
out.append('"');
escapeJavaString(value, out);
out.append('"');
}
}
/** converts normal string to java escaped for double-quotes (but not wrapped in double quotes) */
public static void escapeJavaString(@Nonnull String value, Appendable out) throws IOException {
for (int i=0; i unwrapQuotedJavaStringList(String s, String separator) {
List result = new ArrayList();
String remaining = s.trim();
while (remaining.length() > 0) {
int endIndex = findNextClosingQuoteOf(remaining);
result.add(unwrapJavaString(remaining.substring(0, endIndex+1)));
remaining = remaining.substring(endIndex+1).trim();
if (remaining.startsWith(separator)) {
remaining = remaining.substring(separator.length()).trim();
} else if (remaining.length() > 0) {
throw new IllegalArgumentException("String '"+s+"' has invalid separators, should be '"+separator+"'");
}
}
return result;
}
private static int findNextClosingQuoteOf(String s) {
boolean escaped = false;
boolean quoted = false;
for (int i=0; i unwrapJsonishListIfPossible(String input) {
return unwrapJsonishListStringIfPossible(input);
}
/** converts a comma separated list in a single string to a list of json primitives or maps,
* falling back to returning the input.
*
* specifically:
*
1) if of form [ X ]
(in brackets after trim), parse as YAML;
* if parse succeeds return the result, or if parse fails, return {@link Maybe#absent()}.
* 2) if not of form [ X ]
, wrap in brackets and parse as YAML,
* and if that succeeds and is a list, return the result.
* 3) otherwise, expect comma-separated tokens which after trimming are of the form "A" or B,
* where "A" is a valid Java string or B is any string not containing any of the chars ",.
* and not starting with '
, and returns the list of those tokens, where A is
* returned as its string value, and B as a primitive if it is a number or boolean or null,
* or else a string (including the empty string if empty)
* 4) if such tokens are not found, return {@link Maybe#absent()}.
*
* @see #unwrapOptionallyQuotedJavaStringList(String)
**/
public static Maybe> tryUnwrapJsonishList(String input) {
if (input==null) return Maybe.absent("null input cannot unwrap to a list");
String inputT = input.trim();
String inputYaml = null;
if (!inputT.startsWith("[") && !inputT.endsWith("]")) {
inputYaml = "[" + inputT + "]";
}
if (inputT.startsWith("[") && inputT.endsWith("]")) {
inputYaml = inputT;
}
if (inputYaml!=null) {
try {
Object r = Iterables.getOnlyElement( Yamls.parseAll(inputYaml) );
if (r instanceof List) {
@SuppressWarnings("unchecked")
List