1 package autotest.common; 2 3 import com.google.gwt.dom.client.Document; 4 import com.google.gwt.dom.client.Element; 5 import com.google.gwt.http.client.URL; 6 import com.google.gwt.i18n.client.NumberFormat; 7 import com.google.gwt.json.client.JSONArray; 8 import com.google.gwt.json.client.JSONNumber; 9 import com.google.gwt.json.client.JSONObject; 10 import com.google.gwt.json.client.JSONString; 11 import com.google.gwt.json.client.JSONValue; 12 import com.google.gwt.user.client.Window; 13 import com.google.gwt.user.client.ui.HTMLPanel; 14 15 import java.util.ArrayList; 16 import java.util.Collection; 17 import java.util.HashMap; 18 import java.util.List; 19 import java.util.Map; 20 21 public class Utils { 22 public static final String JSON_NULL = "<null>"; 23 public static final String RETRIEVE_LOGS_URL = "/tko/retrieve_logs.cgi"; 24 25 private static final String[][] escapeMappings = { 26 {"&", "&"}, 27 {">", ">"}, 28 {"<", "<"}, 29 {"\"", """}, 30 {"'", "'"}, 31 }; 32 33 /** 34 * Converts a collection of Java <code>String</code>s into a <code>JSONArray 35 * </code> of <code>JSONString</code>s. 36 */ 37 public static JSONArray stringsToJSON(Collection<String> strings) { 38 JSONArray result = new JSONArray(); 39 for(String s : strings) { 40 result.set(result.size(), new JSONString(s)); 41 } 42 return result; 43 } 44 45 /** 46 * Converts a collection of Java <code>Integers</code>s into a <code>JSONArray 47 * </code> of <code>JSONNumber</code>s. 48 */ 49 public static JSONArray integersToJSON(Collection<Integer> integers) { 50 JSONArray result = new JSONArray(); 51 for(Integer i : integers) { 52 result.set(result.size(), new JSONNumber(i)); 53 } 54 return result; 55 } 56 57 /** 58 * Converts a <code>JSONArray</code> of <code>JSONStrings</code> to an 59 * array of Java <code>Strings</code>. 60 */ 61 public static String[] JSONtoStrings(JSONArray strings) { 62 String[] result = new String[strings.size()]; 63 for (int i = 0; i < strings.size(); i++) { 64 result[i] = jsonToString(strings.get(i)); 65 } 66 return result; 67 } 68 69 /** 70 * Converts a <code>JSONArray</code> of <code>JSONObjects</code> to an 71 * array of Java <code>Strings</code> by grabbing the specified field from 72 * each object. 73 */ 74 public static String[] JSONObjectsToStrings(JSONArray objects, String field) { 75 String[] result = new String[objects.size()]; 76 for (int i = 0; i < objects.size(); i++) { 77 JSONValue fieldValue = objects.get(i).isObject().get(field); 78 result[i] = jsonToString(fieldValue); 79 } 80 return result; 81 } 82 83 public static JSONObject mapToJsonObject(Map<String, String> map) { 84 JSONObject result = new JSONObject(); 85 for (Map.Entry<String, String> entry : map.entrySet()) { 86 result.put(entry.getKey(), new JSONString(entry.getValue())); 87 } 88 return result; 89 } 90 91 public static Map<String, String> jsonObjectToMap(JSONObject object) { 92 Map<String, String> result = new HashMap<String, String>(); 93 for (String key : object.keySet()) { 94 result.put(key, jsonToString(object.get(key))); 95 } 96 return result; 97 } 98 99 /** 100 * Get a value out of a JSONObject list of size 1. 101 * @return list[0] 102 * @throws IllegalArgumentException if the list is not of size 1 103 */ 104 public static JSONObject getSingleObjectFromList(List<JSONObject> list) { 105 if(list.size() != 1) { 106 throw new IllegalArgumentException("List is not of size 1"); 107 } 108 return list.get(0); 109 } 110 111 public static JSONObject getSingleObjectFromArray(JSONArray array) { 112 return getSingleObjectFromList(new JSONArrayList<JSONObject>(array)); 113 } 114 115 public static JSONObject copyJSONObject(JSONObject source) { 116 JSONObject dest = new JSONObject(); 117 for(String key : source.keySet()) { 118 dest.put(key, source.get(key)); 119 } 120 return dest; 121 } 122 123 public static String escape(String text) { 124 for (String[] mapping : escapeMappings) { 125 text = text.replace(mapping[0], mapping[1]); 126 } 127 return text; 128 } 129 130 public static String unescape(String text) { 131 // must iterate in reverse order 132 for (int i = escapeMappings.length - 1; i >= 0; i--) { 133 text = text.replace(escapeMappings[i][1], escapeMappings[i][0]); 134 } 135 return text; 136 } 137 138 public static <T> List<T> wrapObjectWithList(T object) { 139 List<T> list = new ArrayList<T>(); 140 list.add(object); 141 return list; 142 } 143 144 public static <T> String joinStrings(String joiner, List<T> objects, boolean wantBlanks) { 145 StringBuilder result = new StringBuilder(); 146 boolean first = true; 147 for (T object : objects) { 148 String piece = object.toString(); 149 if (piece.equals("") && !wantBlanks) { 150 continue; 151 } 152 if (first) { 153 first = false; 154 } else { 155 result.append(joiner); 156 } 157 result.append(piece); 158 } 159 return result.toString(); 160 } 161 162 public static <T> String joinStrings(String joiner, List<T> objects) { 163 return joinStrings(joiner, objects, false); 164 } 165 166 public static Map<String,String> decodeUrlArguments(String urlArguments, 167 Map<String, String> arguments) { 168 String[] components = urlArguments.split("&"); 169 for (String component : components) { 170 String[] parts = component.split("="); 171 if (parts.length > 2) { 172 throw new IllegalArgumentException(); 173 } 174 String key = decodeComponent(parts[0]); 175 String value = ""; 176 if (parts.length == 2) { 177 value = URL.decodeComponent(parts[1]); 178 } 179 arguments.put(key, value); 180 } 181 return arguments; 182 } 183 184 private static String decodeComponent(String component) { 185 return URL.decodeComponent(component.replace("%27", "'")); 186 } 187 188 public static String encodeUrlArguments(Map<String, String> arguments) { 189 List<String> components = new ArrayList<String>(); 190 for (Map.Entry<String, String> entry : arguments.entrySet()) { 191 String key = encodeComponent(entry.getKey()); 192 String value = encodeComponent(entry.getValue()); 193 components.add(key + "=" + value); 194 } 195 return joinStrings("&", components); 196 } 197 198 private static String encodeComponent(String component) { 199 return URL.encodeComponent(component).replace("'", "%27"); 200 } 201 202 /** 203 * @param path should be of the form "123-showard/status.log" or just "123-showard" 204 */ 205 public static String getLogsUrl(String path) { 206 return "/results/" + path; 207 } 208 209 public static String getRetrieveLogsUrl(String path) { 210 String logUrl = URL.encode(getLogsUrl(path)); 211 return RETRIEVE_LOGS_URL + "?job=" + logUrl; 212 } 213 214 public static String jsonToString(JSONValue value) { 215 JSONString string; 216 JSONNumber number; 217 assert value != null; 218 if ((string = value.isString()) != null) { 219 return string.stringValue(); 220 } 221 if ((number = value.isNumber()) != null) { 222 double doubleValue = number.doubleValue(); 223 if (doubleValue == (int) doubleValue) { 224 return Integer.toString((int) doubleValue); 225 } 226 return Double.toString(doubleValue); 227 228 } 229 if (value.isNull() != null) { 230 return JSON_NULL; 231 } 232 return value.toString(); 233 } 234 235 public static String setDefaultValue(Map<String, String> map, String key, String defaultValue) { 236 if (map.containsKey(key)) { 237 return map.get(key); 238 } 239 map.put(key, defaultValue); 240 return defaultValue; 241 } 242 243 public static JSONValue setDefaultValue(JSONObject object, String key, JSONValue defaultValue) { 244 if (object.containsKey(key)) { 245 return object.get(key); 246 } 247 object.put(key, defaultValue); 248 return defaultValue; 249 } 250 251 public static List<String> splitList(String list, String splitRegex) { 252 String[] parts = list.split(splitRegex); 253 List<String> finalParts = new ArrayList<String>(); 254 for (String part : parts) { 255 if (!part.equals("")) { 256 finalParts.add(part); 257 } 258 } 259 return finalParts; 260 } 261 262 public static List<String> splitList(String list) { 263 return splitList(list, ","); 264 } 265 266 public static List<String> splitListWithSpaces(String list) { 267 return splitList(list, "[,\\s]+"); 268 } 269 270 public static void updateObject(JSONObject destination, JSONObject source) { 271 if (source == null) { 272 return; 273 } 274 for (String key : source.keySet()) { 275 destination.put(key, source.get(key)); 276 } 277 } 278 279 public static void openUrlInNewWindow(String url) { 280 Window.open(url, "_blank", ""); 281 } 282 283 public static HTMLPanel divToPanel(String elementId) { 284 Element divElement = Document.get().getElementById(elementId); 285 divElement.getParentElement().removeChild(divElement); 286 return new HTMLPanel(divElement.getInnerHTML()); 287 } 288 289 public static void setElementVisible(String elementId, boolean visible) { 290 String display = visible ? "block" : "none"; 291 Document.get().getElementById(elementId).getStyle().setProperty("display", display); 292 } 293 294 public static String percentage(int num, int total) { 295 if (total == 0) { 296 return "N/A"; 297 } 298 NumberFormat format = NumberFormat.getFormat("##0.#%"); 299 return format.format(num / (double) total); 300 } 301 302 public static String numberAndPercentage(int num, int total) { 303 return num + " (" + percentage(num, total) + ")"; 304 } 305 306 public static interface JsonObjectFactory<T> { 307 public T fromJsonObject(JSONObject object); 308 } 309 310 public static <T> List<T> createList(JSONArray objects, JsonObjectFactory<T> factory) { 311 List<T> list = new ArrayList<T>(); 312 for (JSONObject object : new JSONArrayList<JSONObject>(objects)) { 313 list.add(factory.fromJsonObject(object)); 314 } 315 return list; 316 } 317 318 public static String getBaseUrl() { 319 return Window.Location.getProtocol() + "//" + Window.Location.getHost(); 320 } 321 } 322