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

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

mercurial