EMMA Coverage Report (generated Wed Oct 26 13:47:17 EDT 2011)
[all classes][org.jclouds.util]

COVERAGE SUMMARY FOR SOURCE FILE [Strings2.java]

nameclass, %method, %block, %line, %
Strings2.java100% (1/1)71%  (10/14)56%  (191/343)58%  (37.4/64)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Strings2100% (1/1)71%  (10/14)56%  (191/343)58%  (37.4/64)
Strings2 (): void 0%   (0/1)0%   (0/3)0%   (0/1)
encodeString (String): byte [] 0%   (0/1)0%   (0/4)0%   (0/1)
encodeString (String, String): byte [] 0%   (0/1)0%   (0/23)0%   (0/4)
replaceAll (String, char, String): String 0%   (0/1)0%   (0/32)0%   (0/6)
urlDecode (String): String 100% (1/1)22%  (4/18)33%  (1/3)
toStringAndClose (InputStream): String 100% (1/1)38%  (15/40)30%  (2.4/8)
replaceTokens (String, Iterable): String 100% (1/1)61%  (25/41)68%  (4/6)
urlEncode (String, char []): String 100% (1/1)68%  (60/88)69%  (9/13)
replaceTokens (String, Map): String 100% (1/1)88%  (49/56)92%  (12/13)
<static initializer> 100% (1/1)100% (3/3)100% (1/1)
isUrlEncoded (String): boolean 100% (1/1)100% (5/5)100% (1/1)
replaceAll (String, Pattern, String): String 100% (1/1)100% (10/10)100% (3/3)
replaceAll (String, char, Pattern, String): String 100% (1/1)100% (13/13)100% (3/3)
toInputStream (String): InputStream 100% (1/1)100% (7/7)100% (1/1)

1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.jclouds.util;
20 
21import static com.google.common.base.Preconditions.checkNotNull;
22import static com.google.common.io.ByteStreams.toByteArray;
23import static com.google.common.io.Closeables.closeQuietly;
24import static org.jclouds.util.Patterns.CHAR_TO_ENCODED_PATTERN;
25import static org.jclouds.util.Patterns.CHAR_TO_PATTERN;
26import static org.jclouds.util.Patterns.PLUS_PATTERN;
27import static org.jclouds.util.Patterns.STAR_PATTERN;
28import static org.jclouds.util.Patterns.TOKEN_TO_PATTERN;
29import static org.jclouds.util.Patterns.URL_ENCODED_PATTERN;
30import static org.jclouds.util.Patterns._7E_PATTERN;
31 
32import java.io.ByteArrayInputStream;
33import java.io.IOException;
34import java.io.InputStream;
35import java.io.UnsupportedEncodingException;
36import java.net.URLDecoder;
37import java.net.URLEncoder;
38import java.util.Map;
39import java.util.Map.Entry;
40import java.util.concurrent.ExecutionException;
41import java.util.regex.Matcher;
42import java.util.regex.Pattern;
43 
44import javax.annotation.Resource;
45 
46import org.jclouds.logging.Logger;
47 
48import com.google.common.base.Charsets;
49 
50/**
51 * 
52 * 
53 * @author Adrian Cole
54 */
55public class Strings2 {
56 
57   /**
58    * Web browsers do not always handle '+' characters well, use the well-supported '%20' instead.
59    */
60   public static String urlEncode(String in, char... skipEncode) {
61      if (isUrlEncoded(in))
62         return in;
63      try {
64         String returnVal = URLEncoder.encode(in, "UTF-8");
65         returnVal = Strings2.replaceAll(returnVal, '+', PLUS_PATTERN, "%20");
66         returnVal = Strings2.replaceAll(returnVal, '*', STAR_PATTERN, "%2A");
67         returnVal = Strings2.replaceAll(returnVal, _7E_PATTERN, "~");
68         for (char c : skipEncode) {
69            returnVal = Strings2.replaceAll(returnVal, CHAR_TO_ENCODED_PATTERN.get(c), c + "");
70         }
71         return returnVal;
72      } catch (UnsupportedEncodingException e) {
73         throw new IllegalStateException("Bad encoding on input: " + in, e);
74      } catch (ExecutionException e) {
75         throw new IllegalStateException("error creating pattern: " + in, e);
76      }
77   }
78 
79   public static boolean isUrlEncoded(String in) {
80      return URL_ENCODED_PATTERN.matcher(in).matches();
81   }
82 
83   public static String urlDecode(String in) {
84      try {
85         return URLDecoder.decode(in, "UTF-8");
86      } catch (UnsupportedEncodingException e) {
87         throw new IllegalStateException("Bad encoding on input: " + in, e);
88      }
89   }
90 
91   public static String replaceTokens(String value, Iterable<Entry<String, String>> tokenValues) {
92      for (Entry<String, String> tokenValue : tokenValues) {
93         try {
94            value = Strings2.replaceAll(value, TOKEN_TO_PATTERN.get(tokenValue.getKey()), tokenValue.getValue());
95         } catch (ExecutionException e) {
96            throw new IllegalStateException("error creating pattern: " + tokenValue.getKey(), e);
97         }
98      }
99      return value;
100   }
101 
102   public static String replaceAll(String returnVal, Pattern pattern, String replace) {
103      Matcher m = pattern.matcher(returnVal);
104      returnVal = m.replaceAll(replace);
105      return returnVal;
106   }
107 
108   public static String replaceAll(String input, char ifMatch, Pattern pattern, String replacement) {
109      if (input.indexOf(ifMatch) != -1) {
110         input = pattern.matcher(input).replaceAll(replacement);
111      }
112      return input;
113   }
114 
115   public static String replaceAll(String input, char match, String replacement) {
116      if (input.indexOf(match) != -1) {
117         try {
118            input = CHAR_TO_PATTERN.get(match).matcher(input).replaceAll(replacement);
119         } catch (ExecutionException e) {
120            throw new IllegalStateException("error creating pattern: " + match, e);
121         }
122      }
123      return input;
124   }
125 
126   public static final String UTF8_ENCODING = "UTF-8";
127 
128   public static String toStringAndClose(InputStream input) throws IOException {
129      checkNotNull(input, "input");
130      try {
131         return new String(toByteArray(input), Charsets.UTF_8);
132      } catch (IOException e) {
133         logger.warn(e, "Failed to read from stream");
134         return null;
135      } catch (NullPointerException e) {
136         return null;
137      } finally {
138         closeQuietly(input);
139      }
140   }
141 
142   public static InputStream toInputStream(String in) {
143      return new ByteArrayInputStream(in.getBytes(Charsets.UTF_8));
144   }
145 
146   /**
147    * Encode the given string with the given encoding, if possible. If the encoding fails with
148    * {@link UnsupportedEncodingException}, log a warning and fall back to the system's default
149    * encoding.
150    * 
151    * @param str
152    *           what to encode
153    * @param charsetName
154    *           the name of a supported {@link java.nio.charset.Charset </code>charset<code>}
155    * @return properly encoded String.
156    */
157   public static byte[] encodeString(String str, String charsetName) {
158      try {
159         return str.getBytes(charsetName);
160      } catch (UnsupportedEncodingException e) {
161         logger.warn(e, "Failed to encode string to bytes with encoding " + charsetName
162               + ". Falling back to system's default encoding");
163         return str.getBytes();
164      }
165   }
166 
167   @Resource
168   private static Logger logger = Logger.NULL;
169 
170   /**
171    * Encode the given string with the UTF-8 encoding, the sane default. In the very unlikely event
172    * the encoding fails with {@link UnsupportedEncodingException}, log a warning and fall back to
173    * the system's default encoding.
174    * 
175    * @param str
176    *           what to encode
177    * @return properly encoded String.
178    */
179   public static byte[] encodeString(String str) {
180      return encodeString(str, UTF8_ENCODING);
181   }
182 
183   /**
184    * replaces tokens that are expressed as <code>{token}</code>
185    * 
186    * <p/>
187    * ex. if input is "hello {where}"<br/>
188    * and replacements is "where" -> "world" <br/>
189    * then replaceTokens returns "hello world"
190    * 
191    * @param input
192    *           source to replace
193    * @param replacements
194    *           token/value pairs
195    */
196   public static String replaceTokens(String input, Map<String, String> replacements) {
197      Matcher matcher = Patterns.TOKEN_PATTERN.matcher(input);
198      StringBuilder builder = new StringBuilder();
199      int i = 0;
200      while (matcher.find()) {
201         String replacement = replacements.get(matcher.group(1));
202         builder.append(input.substring(i, matcher.start()));
203         if (replacement == null)
204            builder.append(matcher.group(0));
205         else
206            builder.append(replacement);
207         i = matcher.end();
208      }
209      builder.append(input.substring(i, input.length()));
210      return builder.toString();
211   }
212 
213}

[all classes][org.jclouds.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov