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         {"&", "&amp;"},
28         {">", "&gt;"},
29         {"<", "&lt;"},
30         {"\"", "&quot;"},
31         {"'", "&apos;"},
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