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