001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.gwt; 021 022 import com.google.gwt.core.client.JavaScriptException; 023 import com.google.gwt.core.client.JavaScriptObject; 024 import com.google.gwt.http.client.URL; 025 import com.google.gwt.i18n.client.DateTimeFormat; 026 import com.google.gwt.json.client.*; 027 028 import java.util.Date; 029 030 public final class JsonUtils { 031 private static int requestId = 0; 032 033 private JsonUtils() { 034 // only static methods 035 } 036 037 public interface JSONHandler { 038 void onResponse(JavaScriptObject obj); 039 040 void onTimeout(); 041 042 void onError(int errorCode, String errorMessage); 043 } 044 045 public static void requestJson(String url, JSONHandler handler) { 046 if (!url.endsWith("&") && !url.endsWith("?")) { 047 url += "&"; 048 } 049 if (!url.contains("format=json")) { 050 url += "format=json&"; 051 } 052 if (!url.contains("callback=")) { 053 // IMPORTANT : the url should ended with ?callback= or &callback= for JSONP calls 054 url += "callback="; 055 } 056 makeJSONRequest(requestId++, URL.encode(url), handler); 057 } 058 059 public static native void makeJSONRequest(int requestId, String url, JSONHandler handler) 060 /*-{ 061 var callback = "callback" + requestId; 062 063 // create SCRIPT tag, and set SRC attribute equal to JSON feed URL + callback function name 064 var script = document.createElement("script"); 065 script.setAttribute("src", url + callback); 066 script.setAttribute("type", "text/javascript"); 067 068 window[callback] = function(jsonObj) { 069 @org.sonar.gwt.JsonUtils::dispatchJSON(Lcom/google/gwt/core/client/JavaScriptObject;Lorg/sonar/gwt/JsonUtils$JSONHandler;)(jsonObj, handler); 070 window[callback + "done"] = true; 071 } 072 073 setTimeout(function() { 074 if (!window[callback + "done"]) { 075 handler.@org.sonar.gwt.JsonUtils.JSONHandler::onTimeout(); 076 } 077 078 // cleanup 079 document.body.removeChild(script); 080 if (window[callback]) { 081 delete window[callback]; 082 } 083 if (window[callback + "done"]) { 084 delete window[callback + "done"]; 085 } 086 }, 120000); 087 088 document.body.appendChild(script); 089 }-*/; 090 091 public static void dispatchJSON(JavaScriptObject jsonObj, JSONHandler handler) { 092 JSONObject obj = new JSONObject(jsonObj); 093 if (obj.isObject() != null) { 094 if (obj.containsKey("err_code")) { 095 handler.onError(new Double(obj.get("err_code").isNumber().doubleValue()).intValue(), 096 obj.get("err_msg").isString().stringValue()); 097 return; 098 } 099 } 100 handler.onResponse(jsonObj); 101 } 102 103 public static String getString(JSONObject json, String field) { 104 return getAsString(json.get(field)); 105 } 106 107 public static Date getDate(JSONObject json, String field) { 108 String date = getString(json, field); 109 if (date != null) { 110 return parseDateTime(date); 111 } 112 return null; 113 } 114 115 public static Boolean getBoolean(JSONObject json, String field) { 116 JSONValue jsonValue; 117 JSONBoolean jsonBoolean; 118 if ((jsonValue = json.get(field)) == null) { 119 return null; 120 } 121 if ((jsonBoolean = jsonValue.isBoolean()) == null) { 122 return null; 123 } 124 return jsonBoolean.booleanValue(); 125 } 126 127 public static Double getDouble(JSONObject json, String field) { 128 JSONValue jsonValue; 129 JSONNumber jsonNumber; 130 if ((jsonValue = json.get(field)) == null) { 131 return null; 132 } 133 if ((jsonNumber = jsonValue.isNumber()) == null) { 134 return null; 135 } 136 return jsonNumber.doubleValue(); 137 } 138 139 public static Integer getInteger(JSONObject json, String field) { 140 final Double d = getDouble(json, field); 141 if (d != null) { 142 return d.intValue(); 143 } 144 return null; 145 } 146 147 public static JSONObject getArray(JSONValue json, int i) { 148 if (json instanceof JSONArray) { 149 return ((JSONArray) json).get(i).isObject(); 150 } 151 if (json instanceof JSONObject) { 152 return ((JSONObject) json).get(Integer.toString(i)).isObject(); 153 } 154 throw new JavaScriptException("Not implemented"); 155 } 156 157 public static int getArraySize(JSONValue array) { 158 if (array instanceof JSONArray) { 159 return ((JSONArray) array).size(); 160 } 161 if (array instanceof JSONObject) { 162 return ((JSONObject) array).size(); 163 } 164 throw new JavaScriptException("Not implemented"); 165 } 166 167 public static String getAsString(JSONValue jsonValue) { 168 if (jsonValue == null) { 169 return null; 170 } 171 JSONString jsonString; 172 if ((jsonString = jsonValue.isString()) == null) { 173 JSONNumber jsonNumber = jsonValue.isNumber(); 174 return jsonNumber != null ? jsonNumber.toString() : null; 175 } 176 return jsonString.stringValue(); 177 } 178 179 public static Double getAsDouble(JSONValue jsonValue) { 180 if (jsonValue == null) { 181 return null; 182 } 183 JSONNumber jsonNumber; 184 if ((jsonNumber = jsonValue.isNumber()) == null) { 185 JSONString jsonString = jsonValue.isString(); 186 return jsonString != null ? Double.parseDouble(jsonString.toString()) : null; 187 } 188 return jsonNumber.doubleValue(); 189 } 190 191 /** 192 * @since 2.5 193 */ 194 public static Date parseDateTime(String dateTime) { 195 DateTimeFormat frmt = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ"); 196 if (dateTime.endsWith("Z") && dateTime.length() > 2) { 197 // see SONAR-1182 198 dateTime = dateTime.substring(0, dateTime.length() - 2) + "+0000"; 199 } 200 return frmt.parse(dateTime); 201 } 202 203 }