src/net/fortuna/ical4j/util/Strings.java

Tue, 10 Feb 2015 18:12:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 10 Feb 2015 18:12:00 +0100
changeset 0
fb9019fb1bf7
permissions
-rw-r--r--

Import initial revisions of existing project AndroidCaldavSyncAdapater,
forked from upstream repository at 27e8a0f8495c92e0780d450bdf0c7cec77a03a55.

michael@0 1 /**
michael@0 2 * Copyright (c) 2012, Ben Fortuna
michael@0 3 * All rights reserved.
michael@0 4 *
michael@0 5 * Redistribution and use in source and binary forms, with or without
michael@0 6 * modification, are permitted provided that the following conditions
michael@0 7 * are met:
michael@0 8 *
michael@0 9 * o Redistributions of source code must retain the above copyright
michael@0 10 * notice, this list of conditions and the following disclaimer.
michael@0 11 *
michael@0 12 * o Redistributions in binary form must reproduce the above copyright
michael@0 13 * notice, this list of conditions and the following disclaimer in the
michael@0 14 * documentation and/or other materials provided with the distribution.
michael@0 15 *
michael@0 16 * o Neither the name of Ben Fortuna nor the names of any other contributors
michael@0 17 * may be used to endorse or promote products derived from this software
michael@0 18 * without specific prior written permission.
michael@0 19 *
michael@0 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
michael@0 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
michael@0 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
michael@0 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
michael@0 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
michael@0 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
michael@0 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
michael@0 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 31 */
michael@0 32 package net.fortuna.ical4j.util;
michael@0 33
michael@0 34 import java.util.regex.Pattern;
michael@0 35
michael@0 36 /**
michael@0 37 * $Id$ [23-Apr-2004]
michael@0 38 *
michael@0 39 * Utility methods for working with parameters.
michael@0 40 * @author Ben Fortuna
michael@0 41 * <pre>
michael@0 42 * 4.3.11 Text
michael@0 43 *
michael@0 44 * Value Name: TEXT
michael@0 45 *
michael@0 46 * Purpose This value type is used to identify values that contain human
michael@0 47 * readable text.
michael@0 48 *
michael@0 49 * Formal Definition: The character sets supported by this revision of
michael@0 50 * iCalendar are UTF-8 and US ASCII thereof. The applicability to other
michael@0 51 * character sets is for future work. The value type is defined by the
michael@0 52 * following notation.
michael@0 53 *
michael@0 54 * text = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR)
michael@0 55 * ; Folded according to description above
michael@0 56 *
michael@0 57 * ESCAPED-CHAR = "\\" / "\;" / "\," / "\N" / "\n")
michael@0 58 * ; \\ encodes \, \N or \n encodes newline
michael@0 59 * ; \; encodes ;, \, encodes ,
michael@0 60 *
michael@0 61 * TSAFE-CHAR = %x20-21 / %x23-2B / %x2D-39 / %x3C-5B
michael@0 62 * %x5D-7E / NON-US-ASCII
michael@0 63 * ; Any character except CTLs not needed by the current
michael@0 64 * ; character set, DQUOTE, ";", ":", "\", ","
michael@0 65 *
michael@0 66 * Note: Certain other character sets may require modification of the
michael@0 67 * above definitions, but this is beyond the scope of this document.
michael@0 68 *
michael@0 69 * Description: If the property permits, multiple "text" values are
michael@0 70 * specified by a COMMA character (US-ASCII decimal 44) separated list
michael@0 71 * of values.
michael@0 72 *
michael@0 73 * The language in which the text is represented can be controlled by
michael@0 74 * the "LANGUAGE" property parameter.
michael@0 75 *
michael@0 76 * An intentional formatted text line break MUST only be included in a
michael@0 77 * "TEXT" property value by representing the line break with the
michael@0 78 * character sequence of BACKSLASH (US-ASCII decimal 92), followed by a
michael@0 79 * LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER
michael@0 80 * N (US-ASCII decimal 78), that is "\n" or "\N".
michael@0 81 *
michael@0 82 * The "TEXT" property values may also contain special characters that
michael@0 83 * are used to signify delimiters, such as a COMMA character for lists
michael@0 84 * of values or a SEMICOLON character for structured values. In order to
michael@0 85 * support the inclusion of these special characters in "TEXT" property
michael@0 86 * values, they MUST be escaped with a BACKSLASH character. A BACKSLASH
michael@0 87 * character (US-ASCII decimal 92) in a "TEXT" property value MUST be
michael@0 88 * escaped with another BACKSLASH character. A COMMA character in a
michael@0 89 * "TEXT" property value MUST be escaped with a BACKSLASH character
michael@0 90 * (US-ASCII decimal 92). A SEMICOLON character in a "TEXT" property
michael@0 91 * value MUST be escaped with a BACKSLASH character (US-ASCII decimal
michael@0 92 * 92). However, a COLON character in a "TEXT" property value SHALL NOT
michael@0 93 * be escaped with a BACKSLASH character.Example: A multiple line value
michael@0 94 * of:
michael@0 95 *
michael@0 96 * Project XYZ Final Review
michael@0 97 * Conference Room - 3B
michael@0 98 * Come Prepared.
michael@0 99 *
michael@0 100 * would be represented as:
michael@0 101 *
michael@0 102 * Project XYZ Final Review\nConference Room - 3B\nCome Prepared.
michael@0 103 * </pre>
michael@0 104 */
michael@0 105 public final class Strings {
michael@0 106
michael@0 107 /**
michael@0 108 * Defines a regular expression representing all parameter strings that
michael@0 109 * should be quoted.
michael@0 110 */
michael@0 111 public static final Pattern PARAM_QUOTE_PATTERN = Pattern.compile("[:;,]|[^\\p{ASCII}]");
michael@0 112
michael@0 113 private static final Pattern ESCAPE_PUNCTUATION_PATTERN = Pattern.compile("([,;])");
michael@0 114 private static final Pattern UNESCAPE_PUNCTUATION_PATTERN = Pattern.compile("\\\\([,;\"])");
michael@0 115
michael@0 116 private static final Pattern ESCAPE_NEWLINE_PATTERN = Pattern.compile("\r?\n");
michael@0 117 private static final Pattern UNESCAPE_NEWLINE_PATTERN = Pattern.compile("(?<!\\\\)\\\\n");
michael@0 118
michael@0 119 private static final Pattern ESCAPE_BACKSLASH_PATTERN = Pattern.compile("\\\\");
michael@0 120 private static final Pattern UNESCAPE_BACKSLASH_PATTERN = Pattern.compile("\\\\\\\\");
michael@0 121
michael@0 122
michael@0 123
michael@0 124 /**
michael@0 125 * A string used to denote the start (and end) of iCalendar content lines.
michael@0 126 */
michael@0 127 public static final String LINE_SEPARATOR = "\r\n";
michael@0 128
michael@0 129 /**
michael@0 130 * Constructor made private to prevent instantiation.
michael@0 131 */
michael@0 132 private Strings() {
michael@0 133 }
michael@0 134
michael@0 135 /**
michael@0 136 * Convenience method for adding quotes. The specified
michael@0 137 * object is converted to a string representation by
michael@0 138 * calling its <code>toString()</code> method.
michael@0 139 * @param aValue an object to quote
michael@0 140 * @return a quoted string
michael@0 141 */
michael@0 142 public static String quote(final Object aValue) {
michael@0 143 if (aValue != null) {
michael@0 144 return "\"" + aValue + "\"";
michael@0 145 }
michael@0 146 return "\"\"";
michael@0 147 }
michael@0 148
michael@0 149 /**
michael@0 150 * Convenience method for removing surrounding quotes
michael@0 151 * from a string value.
michael@0 152 * @param aValue a string to remove quotes from
michael@0 153 * @return an un-quoted string
michael@0 154 */
michael@0 155 public static String unquote(final String aValue) {
michael@0 156 if (aValue != null && aValue.startsWith("\"") && aValue.endsWith("\"")) {
michael@0 157 return aValue.substring(0, aValue.length() - 1).substring(1);
michael@0 158 }
michael@0 159 return aValue;
michael@0 160 }
michael@0 161
michael@0 162 /**
michael@0 163 * Convenience method for escaping special characters.
michael@0 164 * @param aValue a string value to escape
michael@0 165 * @return an escaped representation of the specified
michael@0 166 * string
michael@0 167 */
michael@0 168 public static String escape(final String aValue) {
michael@0 169 return escapePunctuation(escapeNewline(escapeBackslash(aValue)));
michael@0 170 }
michael@0 171
michael@0 172 /**
michael@0 173 * Convenience method for replacing escaped special characters
michael@0 174 * with their original form.
michael@0 175 * @param aValue a string value to unescape
michael@0 176 * @return a string representation of the specified
michael@0 177 * string with escaped characters replaced with their
michael@0 178 * original form
michael@0 179 */
michael@0 180 public static String unescape(final String aValue) {
michael@0 181 return unescapeBackslash(unescapeNewline(unescapePunctuation(aValue)));
michael@0 182 }
michael@0 183
michael@0 184 private static String escapePunctuation(String value) {
michael@0 185 if (value != null) {
michael@0 186 return ESCAPE_PUNCTUATION_PATTERN.matcher(value).replaceAll("\\\\$1");
michael@0 187 }
michael@0 188 return value;
michael@0 189 }
michael@0 190
michael@0 191 private static String unescapePunctuation(String value) {
michael@0 192 if (value != null) {
michael@0 193 return UNESCAPE_PUNCTUATION_PATTERN.matcher(value).replaceAll("$1");
michael@0 194 }
michael@0 195 return value;
michael@0 196 }
michael@0 197
michael@0 198 public static String escapeNewline(String value) {
michael@0 199 if (value != null) {
michael@0 200 return ESCAPE_NEWLINE_PATTERN.matcher(value).replaceAll("\\\\n");
michael@0 201 }
michael@0 202 return value;
michael@0 203 }
michael@0 204
michael@0 205 private static String unescapeNewline(String value) {
michael@0 206 if (value != null) {
michael@0 207 return UNESCAPE_NEWLINE_PATTERN.matcher(value).replaceAll("\n");
michael@0 208 }
michael@0 209 return value;
michael@0 210 }
michael@0 211
michael@0 212 private static String escapeBackslash(String value) {
michael@0 213 if (value != null) {
michael@0 214 return ESCAPE_BACKSLASH_PATTERN.matcher(value).replaceAll("\\\\\\\\");
michael@0 215 }
michael@0 216 return value;
michael@0 217 }
michael@0 218
michael@0 219 private static String unescapeBackslash(String value) {
michael@0 220 if (value != null) {
michael@0 221 return UNESCAPE_BACKSLASH_PATTERN.matcher(value).replaceAll("\\\\");
michael@0 222 }
michael@0 223 return value;
michael@0 224 }
michael@0 225
michael@0 226 /**
michael@0 227 * Wraps <code>java.lang.String.valueOf()</code> to return an empty string
michael@0 228 * where the specified object is null.
michael@0 229 * @param object an object instance
michael@0 230 * @return a string representation of the object
michael@0 231 */
michael@0 232 public static String valueOf(final Object object) {
michael@0 233 if (object == null) {
michael@0 234 return "";
michael@0 235 }
michael@0 236 return object.toString();
michael@0 237 }
michael@0 238 }

mercurial