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