From f66e89662c091e082bd1d2feb6ac91513ccff273 Mon Sep 17 00:00:00 2001
From: Rafael Cavazin <rafaelcavazin@gmail.com>
Date: Sun, 21 Jul 2013 09:59:00 -0400
Subject: [PATCH] Merge branch 'master' of https://github.com/gitblit/gitblit

---
 src/main/java/com/gitblit/utils/JsonUtils.java |  345 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 345 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/gitblit/utils/JsonUtils.java b/src/main/java/com/gitblit/utils/JsonUtils.java
new file mode 100644
index 0000000..e924182
--- /dev/null
+++ b/src/main/java/com/gitblit/utils/JsonUtils.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.reflect.Type;
+import java.net.HttpURLConnection;
+import java.net.URLConnection;
+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 com.gitblit.Constants.AccessPermission;
+import com.gitblit.GitBlitException.ForbiddenException;
+import com.gitblit.GitBlitException.NotAllowedException;
+import com.gitblit.GitBlitException.UnauthorizedException;
+import com.gitblit.GitBlitException.UnknownRequestException;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.UserModel;
+import com.google.gson.ExclusionStrategy;
+import com.google.gson.FieldAttributes;
+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 json calls to a Gitblit server.
+ * 
+ * @author James Moger
+ * 
+ */
+public class JsonUtils {
+
+	public static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
+	}.getType();
+
+	public static final Type USERS_TYPE = new TypeToken<Collection<UserModel>>() {
+	}.getType();
+
+	/**
+	 * Creates JSON from the specified object.
+	 * 
+	 * @param o
+	 * @return json
+	 */
+	public static String toJsonString(Object o) {
+		String json = gson().toJson(o);
+		return json;
+	}
+
+	/**
+	 * Convert a json string to an object of the specified type.
+	 * 
+	 * @param json
+	 * @param clazz
+	 * @return an object
+	 */
+	public static <X> X fromJsonString(String json, Class<X> clazz) {
+		return gson().fromJson(json, clazz);
+	}
+
+	/**
+	 * Convert a json string to an object of the specified type.
+	 * 
+	 * @param json
+	 * @param clazz
+	 * @return an object
+	 */
+	public static <X> X fromJsonString(String json, Type type) {
+		return gson().fromJson(json, type);
+	}
+
+	/**
+	 * Reads a gson object from the specified url.
+	 * 
+	 * @param url
+	 * @param type
+	 * @return the deserialized object
+	 * @throws {@link IOException}
+	 */
+	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
+	 * @return the deserialized object
+	 * @throws {@link IOException}
+	 */
+	public static <X> X retrieveJson(String url, Class<? extends X> clazz) throws IOException,
+			UnauthorizedException {
+		return retrieveJson(url, clazz, 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;
+		}
+		return gson().fromJson(json, type);
+	}
+
+	/**
+	 * Reads a gson object from the specified url.
+	 * 
+	 * @param url
+	 * @param clazz
+	 * @param username
+	 * @param password
+	 * @return the deserialized object
+	 * @throws {@link IOException}
+	 */
+	public static <X> X retrieveJson(String url, Class<X> clazz, String username, char[] password)
+			throws IOException {
+		String json = retrieveJsonString(url, username, password);
+		if (StringUtils.isEmpty(json)) {
+			return null;
+		}
+		return gson().fromJson(json, clazz);
+	}
+
+	/**
+	 * Retrieves a JSON message.
+	 * 
+	 * @param url
+	 * @return the JSON message as a string
+	 * @throws {@link IOException}
+	 */
+	public static String retrieveJsonString(String url, String username, char[] password)
+			throws IOException {
+		try {
+			URLConnection conn = ConnectionUtils.openReadConnection(url, username, password);
+			InputStream is = conn.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(is,
+					ConnectionUtils.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);
+			} else if (e.getMessage().indexOf("405") > -1) {
+				// requested url is not allowed by the server
+				throw new NotAllowedException(url);
+			} else if (e.getMessage().indexOf("501") > -1) {
+				// requested url is not recognized by the server
+				throw new UnknownRequestException(url);
+			}
+			throw e;
+		}
+	}
+
+	/**
+	 * Sends a JSON message.
+	 * 
+	 * @param url
+	 *            the url to write to
+	 * @param json
+	 *            the json message to send
+	 * @return the http request result code
+	 * @throws {@link IOException}
+	 */
+	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(ConnectionUtils.CHARSET);
+			URLConnection conn = ConnectionUtils.openConnection(url, username, password);
+			conn.setRequestProperty("Content-Type", "text/plain;charset=" + ConnectionUtils.CHARSET);
+			conn.setRequestProperty("Content-Length", "" + jsonBytes.length);
+
+			// 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);
+			} else if (e.getMessage().indexOf("405") > -1) {
+				// requested url is not allowed by the server
+				throw new NotAllowedException(url);
+			} else if (e.getMessage().indexOf("501") > -1) {
+				// requested url is not recognized by the server
+				throw new UnknownRequestException(url);
+			}
+			throw e;
+		}
+	}
+
+	// build custom gson instance with GMT date serializer/deserializer
+	// http://code.google.com/p/google-gson/issues/detail?id=281
+	public static Gson gson(ExclusionStrategy... strategies) {
+		GsonBuilder builder = new GsonBuilder();
+		builder.registerTypeAdapter(Date.class, new GmtDateTypeAdapter());
+		builder.registerTypeAdapter(AccessPermission.class, new AccessPermissionTypeAdapter());
+		if (!ArrayUtils.isEmpty(strategies)) {
+			builder.setExclusionStrategies(strategies);
+		}
+		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"));
+		}
+
+		@Override
+		public synchronized JsonElement serialize(Date date, Type type,
+				JsonSerializationContext jsonSerializationContext) {
+			synchronized (dateFormat) {
+				String dateFormatAsString = dateFormat.format(date);
+				return new JsonPrimitive(dateFormatAsString);
+			}
+		}
+
+		@Override
+		public synchronized Date deserialize(JsonElement jsonElement, Type type,
+				JsonDeserializationContext jsonDeserializationContext) {
+			try {
+				synchronized (dateFormat) {
+					Date date = dateFormat.parse(jsonElement.getAsString());					
+					return new Date((date.getTime() / 1000) * 1000);
+				}
+			} catch (ParseException e) {
+				throw new JsonSyntaxException(jsonElement.getAsString(), e);
+			}
+		}
+	}
+	
+	private static class AccessPermissionTypeAdapter implements JsonSerializer<AccessPermission>, JsonDeserializer<AccessPermission> {
+
+		private AccessPermissionTypeAdapter() {
+		}
+
+		@Override
+		public synchronized JsonElement serialize(AccessPermission permission, Type type,
+				JsonSerializationContext jsonSerializationContext) {
+			return new JsonPrimitive(permission.code);
+		}
+
+		@Override
+		public synchronized AccessPermission deserialize(JsonElement jsonElement, Type type,
+				JsonDeserializationContext jsonDeserializationContext) {
+			return AccessPermission.fromCode(jsonElement.getAsString());					
+		}
+	}
+
+	public static class ExcludeField implements ExclusionStrategy {
+
+		private Class<?> c;
+		private String fieldName;
+
+		public ExcludeField(String fqfn) throws SecurityException, NoSuchFieldException,
+				ClassNotFoundException {
+			this.c = Class.forName(fqfn.substring(0, fqfn.lastIndexOf(".")));
+			this.fieldName = fqfn.substring(fqfn.lastIndexOf(".") + 1);
+		}
+
+		public boolean shouldSkipClass(Class<?> arg0) {
+			return false;
+		}
+
+		public boolean shouldSkipField(FieldAttributes f) {
+			return (f.getDeclaringClass() == c && f.getName().equals(fieldName));
+		}
+	}
+}

--
Gitblit v1.9.1