From f762b160efd5cafd919a6fd7f9587f578eceb454 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Sun, 02 Oct 2011 16:59:44 -0400 Subject: [PATCH] Merge branch 'master' into rpc --- src/com/gitblit/utils/JsonUtils.java | 228 +++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 174 insertions(+), 54 deletions(-) diff --git a/src/com/gitblit/utils/JsonUtils.java b/src/com/gitblit/utils/JsonUtils.java index a697b7a..3834c8e 100644 --- a/src/com/gitblit/utils/JsonUtils.java +++ b/src/com/gitblit/utils/JsonUtils.java @@ -16,6 +16,7 @@ package com.gitblit.utils; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; @@ -26,8 +27,14 @@ import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; +import java.util.Locale; import java.util.Map; +import java.util.TimeZone; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -36,14 +43,25 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import org.eclipse.jgit.util.Base64; + +import com.gitblit.GitBlitException.ForbiddenException; +import com.gitblit.GitBlitException.UnauthorizedException; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; /** - * Utility methods for gson calls to a Gitblit server. + * Utility methods for json calls to a Gitblit server. * * @author James Moger * @@ -82,8 +100,7 @@ * @return json */ public static String toJsonString(Object o) { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String json = gson.toJson(o); + String json = gson().toJson(o); return json; } @@ -95,10 +112,9 @@ * @return an object */ public static <X> X fromJsonString(String json, Class<X> clazz) { - Gson gson = new Gson(); - return gson.fromJson(json, clazz); + return gson().fromJson(json, clazz); } - + /** * Convert a json string to an object of the specified type. * @@ -107,8 +123,7 @@ * @return an object */ public static <X> X fromJsonString(String json, Type type) { - Gson gson = new Gson(); - return gson.fromJson(json, type); + return gson().fromJson(json, type); } /** @@ -116,16 +131,31 @@ * * @param url * @param type - * @return - * @throws Exception + * @return the deserialized object + * @throws {@link IOException} */ - public static <X> X retrieveJson(String url, Type type) throws Exception { - String json = retrieveJsonString(url); + public static <X> X retrieveJson(String url, Type type) throws IOException, + UnauthorizedException { + return retrieveJson(url, type, null, null); + } + + /** + * Reads a gson object from the specified url. + * + * @param url + * @param type + * @param username + * @param password + * @return the deserialized object + * @throws {@link IOException} + */ + public static <X> X retrieveJson(String url, Type type, String username, char[] password) + throws IOException { + String json = retrieveJsonString(url, username, password); if (StringUtils.isEmpty(json)) { return null; } - Gson gson = new Gson(); - return gson.fromJson(json, type); + return gson().fromJson(json, type); } /** @@ -133,29 +163,42 @@ * * @param url * @return the JSON message as a string - * @throws Exception + * @throws {@link IOException} */ - public static String retrieveJsonString(String url) throws Exception { - URL urlObject = new URL(url); - URLConnection conn = urlObject.openConnection(); - conn.setRequestProperty("Accept-Charset", CHARSET); - conn.setUseCaches(false); - conn.setDoInput(true); - if (conn instanceof HttpsURLConnection) { - HttpsURLConnection secureConn = (HttpsURLConnection) conn; - secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory()); - secureConn.setHostnameVerifier(HOSTNAME_VERIFIER); + public static String retrieveJsonString(String url, String username, char[] password) + throws IOException { + try { + URL urlObject = new URL(url); + URLConnection conn = urlObject.openConnection(); + conn.setRequestProperty("Accept-Charset", CHARSET); + setAuthorization(conn, username, password); + conn.setUseCaches(false); + conn.setDoInput(true); + if (conn instanceof HttpsURLConnection) { + HttpsURLConnection secureConn = (HttpsURLConnection) conn; + secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory()); + secureConn.setHostnameVerifier(HOSTNAME_VERIFIER); + } + InputStream is = conn.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is, CHARSET)); + StringBuilder json = new StringBuilder(); + char[] buffer = new char[4096]; + int len = 0; + while ((len = reader.read(buffer)) > -1) { + json.append(buffer, 0, len); + } + is.close(); + return json.toString(); + } catch (IOException e) { + if (e.getMessage().indexOf("401") > -1) { + // unauthorized + throw new UnauthorizedException(url); + } else if (e.getMessage().indexOf("403") > -1) { + // requested url is forbidden by the requesting user + throw new ForbiddenException(url); + } + throw e; } - InputStream is = conn.getInputStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(is, CHARSET)); - StringBuilder json = new StringBuilder(); - char[] buffer = new char[4096]; - int len = 0; - while ((len = reader.read(buffer)) > -1) { - json.append(buffer, 0, len); - } - is.close(); - return json.toString(); } /** @@ -166,29 +209,106 @@ * @param json * the json message to send * @return the http request result code - * @throws Exception + * @throws {@link IOException} */ - public static int sendJsonString(String url, String json) throws Exception { - byte[] jsonBytes = json.getBytes(CHARSET); - URL urlObject = new URL(url); - URLConnection conn = urlObject.openConnection(); - conn.setRequestProperty("Content-Type", "text/plain;charset=" + CHARSET); - conn.setRequestProperty("Content-Length", "" + jsonBytes.length); - conn.setUseCaches(false); - conn.setDoOutput(true); - if (conn instanceof HttpsURLConnection) { - HttpsURLConnection secureConn = (HttpsURLConnection) conn; - secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory()); - secureConn.setHostnameVerifier(HOSTNAME_VERIFIER); + public static int sendJsonString(String url, String json) throws IOException { + return sendJsonString(url, json, null, null); + } + + /** + * Sends a JSON message. + * + * @param url + * the url to write to + * @param json + * the json message to send + * @param username + * @param password + * @return the http request result code + * @throws {@link IOException} + */ + public static int sendJsonString(String url, String json, String username, char[] password) + throws IOException { + try { + byte[] jsonBytes = json.getBytes(CHARSET); + URL urlObject = new URL(url); + URLConnection conn = urlObject.openConnection(); + conn.setRequestProperty("Content-Type", "text/plain;charset=" + CHARSET); + conn.setRequestProperty("Content-Length", "" + jsonBytes.length); + setAuthorization(conn, username, password); + conn.setUseCaches(false); + conn.setDoOutput(true); + if (conn instanceof HttpsURLConnection) { + HttpsURLConnection secureConn = (HttpsURLConnection) conn; + secureConn.setSSLSocketFactory(SSL_CONTEXT.getSocketFactory()); + secureConn.setHostnameVerifier(HOSTNAME_VERIFIER); + } + + // write json body + OutputStream os = conn.getOutputStream(); + os.write(jsonBytes); + os.close(); + + int status = ((HttpURLConnection) conn).getResponseCode(); + return status; + } catch (IOException e) { + if (e.getMessage().indexOf("401") > -1) { + // unauthorized + throw new UnauthorizedException(url); + } else if (e.getMessage().indexOf("403") > -1) { + // requested url is forbidden by the requesting user + throw new ForbiddenException(url); + } + throw e; + } + } + + private static void setAuthorization(URLConnection conn, String username, char[] password) { + if (!StringUtils.isEmpty(username) && (password != null && password.length > 0)) { + conn.setRequestProperty( + "Authorization", + "Basic " + + Base64.encodeBytes((username + ":" + new String(password)).getBytes())); + } + } + + // build custom gson instance with GMT date serializer/deserializer + // http://code.google.com/p/google-gson/issues/detail?id=281 + private static Gson gson() { + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapter(Date.class, new GmtDateTypeAdapter()); + builder.setPrettyPrinting(); + return builder.create(); + } + + private static class GmtDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> { + private final DateFormat dateFormat; + + private GmtDateTypeAdapter() { + dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } - // write json body - OutputStream os = conn.getOutputStream(); - os.write(jsonBytes); - os.close(); + @Override + public synchronized JsonElement serialize(Date date, Type type, + JsonSerializationContext jsonSerializationContext) { + synchronized (dateFormat) { + String dateFormatAsString = dateFormat.format(date); + return new JsonPrimitive(dateFormatAsString); + } + } - int status = ((HttpURLConnection) conn).getResponseCode(); - return status; + @Override + public synchronized Date deserialize(JsonElement jsonElement, Type type, + JsonDeserializationContext jsonDeserializationContext) { + try { + synchronized (dateFormat) { + return dateFormat.parse(jsonElement.getAsString()); + } + } catch (ParseException e) { + throw new JsonSyntaxException(jsonElement.getAsString(), e); + } + } } /** -- Gitblit v1.9.1