001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 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 var callback = "callback" + requestId; 061 062 // create SCRIPT tag, and set SRC attribute equal to JSON feed URL + callback function name 063 var script = document.createElement("script"); 064 script.setAttribute("src", url + callback); 065 script.setAttribute("type", "text/javascript"); 066 067 window[callback] = function(jsonObj) { 068 @org.sonar.gwt.JsonUtils::dispatchJSON(Lcom/google/gwt/core/client/JavaScriptObject;Lorg/sonar/gwt/JsonUtils$JSONHandler;)(jsonObj, handler); 069 window[callback + "done"] = true; 070 } 071 072 setTimeout(function() { 073 if (!window[callback + "done"]) { 074 handler.@org.sonar.gwt.JsonUtils.JSONHandler::onTimeout(); 075 } 076 077 // cleanup 078 document.body.removeChild(script); 079 if (window[callback]) { 080 delete window[callback]; 081 } 082 if (window[callback + "done"]) { 083 delete window[callback + "done"]; 084 } 085 }, 120000); 086 087 document.body.appendChild(script); 088 }-*/; 089 090 public static void dispatchJSON(JavaScriptObject jsonObj, JSONHandler handler) { 091 JSONObject obj = new JSONObject(jsonObj); 092 if (obj.isObject() != null) { 093 if (obj.containsKey("err_code")) { 094 handler.onError(new Double(obj.get("err_code").isNumber().doubleValue()).intValue(), 095 obj.get("err_msg").isString().stringValue()); 096 return; 097 } 098 } 099 handler.onResponse(jsonObj); 100 } 101 102 public static String getString(JSONObject json, String field) { 103 JSONValue jsonValue; 104 JSONString jsonString; 105 if ((jsonValue = json.get(field)) == null) { 106 return null; 107 } 108 if ((jsonString = jsonValue.isString()) == null) { 109 JSONNumber jsonNumber = jsonValue.isNumber(); 110 return jsonNumber != null ? jsonNumber.toString() : null; 111 } 112 return jsonString.stringValue(); 113 } 114 115 public static Date getDate(JSONObject json, String field) { 116 String date = getString(json, field); 117 if (date != null) { 118 DateTimeFormat frmt = DateTimeFormat.getFormat("yyyy-MM-dd'T'HH:mm:ssZ"); 119 if (date.endsWith("Z") && date.length() > 2) { 120 // see SONAR-1182 121 date = date.substring(0, date.length() - 2) + "+0000"; 122 } 123 return frmt.parse(date); 124 } 125 return null; 126 } 127 128 public static Boolean getBoolean(JSONObject json, String field) { 129 JSONValue jsonValue; 130 JSONBoolean jsonBoolean; 131 if ((jsonValue = json.get(field)) == null) { 132 return null; 133 } 134 if ((jsonBoolean = jsonValue.isBoolean()) == null) { 135 return null; 136 } 137 return jsonBoolean.booleanValue(); 138 } 139 140 public static Double getDouble(JSONObject json, String field) { 141 JSONValue jsonValue; 142 JSONNumber jsonNumber; 143 if ((jsonValue = json.get(field)) == null) { 144 return null; 145 } 146 if ((jsonNumber = jsonValue.isNumber()) == null) { 147 return null; 148 } 149 return jsonNumber.doubleValue(); 150 } 151 152 public static Integer getInteger(JSONObject json, String field) { 153 final Double d = getDouble(json, field); 154 if (d != null) { 155 return d.intValue(); 156 } 157 return null; 158 } 159 160 public static JSONObject getArray(JSONValue json, int i) { 161 if (json instanceof JSONArray) { 162 return ((JSONArray) json).get(i).isObject(); 163 } 164 if (json instanceof JSONObject) { 165 return ((JSONObject) json).get(Integer.toString(i)).isObject(); 166 } 167 throw new JavaScriptException("Not implemented"); 168 } 169 170 public static int getArraySize(JSONValue array) { 171 if (array instanceof JSONArray) { 172 return ((JSONArray) array).size(); 173 } 174 if (array instanceof JSONObject) { 175 return ((JSONObject) array).size(); 176 } 177 throw new JavaScriptException("Not implemented"); 178 } 179 180 } 181