lemval
2012-01-31 1c30dad2115fc513791d8a5b292ad0f7d7b85749
commit | author | age
93f0b1 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.utils;
17
18 import java.io.BufferedReader;
31abc2 19 import java.io.IOException;
93f0b1 20 import java.io.InputStream;
JM 21 import java.io.InputStreamReader;
22 import java.io.OutputStream;
23 import java.lang.reflect.Type;
24 import java.net.HttpURLConnection;
25 import java.net.URLConnection;
f146f2 26 import java.text.DateFormat;
JM 27 import java.text.ParseException;
28 import java.text.SimpleDateFormat;
93f0b1 29 import java.util.Collection;
f146f2 30 import java.util.Date;
JM 31 import java.util.Locale;
93f0b1 32 import java.util.Map;
f146f2 33 import java.util.TimeZone;
31abc2 34
JM 35 import com.gitblit.GitBlitException.ForbiddenException;
8b7636 36 import com.gitblit.GitBlitException.NotAllowedException;
31abc2 37 import com.gitblit.GitBlitException.UnauthorizedException;
b2fde8 38 import com.gitblit.GitBlitException.UnknownRequestException;
93f0b1 39 import com.gitblit.models.RepositoryModel;
JM 40 import com.gitblit.models.UserModel;
41 import com.google.gson.Gson;
42 import com.google.gson.GsonBuilder;
f146f2 43 import com.google.gson.JsonDeserializationContext;
JM 44 import com.google.gson.JsonDeserializer;
45 import com.google.gson.JsonElement;
46 import com.google.gson.JsonPrimitive;
47 import com.google.gson.JsonSerializationContext;
48 import com.google.gson.JsonSerializer;
49 import com.google.gson.JsonSyntaxException;
93f0b1 50 import com.google.gson.reflect.TypeToken;
JM 51
52 /**
31abc2 53  * Utility methods for json calls to a Gitblit server.
93f0b1 54  * 
JM 55  * @author James Moger
56  * 
57  */
58 public class JsonUtils {
59
60     public static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
61     }.getType();
62
63     public static final Type USERS_TYPE = new TypeToken<Collection<UserModel>>() {
64     }.getType();
65
66     /**
67      * Creates JSON from the specified object.
68      * 
69      * @param o
70      * @return json
71      */
72     public static String toJsonString(Object o) {
f146f2 73         String json = gson().toJson(o);
93f0b1 74         return json;
JM 75     }
76
77     /**
78      * Convert a json string to an object of the specified type.
79      * 
80      * @param json
81      * @param clazz
82      * @return an object
83      */
84     public static <X> X fromJsonString(String json, Class<X> clazz) {
f146f2 85         return gson().fromJson(json, clazz);
93f0b1 86     }
31abc2 87
93f0b1 88     /**
JM 89      * Convert a json string to an object of the specified type.
90      * 
91      * @param json
92      * @param clazz
93      * @return an object
94      */
95     public static <X> X fromJsonString(String json, Type type) {
f146f2 96         return gson().fromJson(json, type);
93f0b1 97     }
JM 98
99     /**
100      * Reads a gson object from the specified url.
101      * 
102      * @param url
103      * @param type
31abc2 104      * @return the deserialized object
JM 105      * @throws {@link IOException}
93f0b1 106      */
31abc2 107     public static <X> X retrieveJson(String url, Type type) throws IOException,
JM 108             UnauthorizedException {
109         return retrieveJson(url, type, null, null);
110     }
df162c 111     
JM 112     /**
113      * Reads a gson object from the specified url.
114      * 
115      * @param url
116      * @param type
117      * @return the deserialized object
118      * @throws {@link IOException}
119      */
120     public static <X> X retrieveJson(String url, Class<? extends X> clazz) throws IOException,
121             UnauthorizedException {
122         return retrieveJson(url, clazz, null, null);
123     }
31abc2 124
JM 125     /**
126      * Reads a gson object from the specified url.
127      * 
128      * @param url
129      * @param type
130      * @param username
131      * @param password
132      * @return the deserialized object
133      * @throws {@link IOException}
134      */
135     public static <X> X retrieveJson(String url, Type type, String username, char[] password)
136             throws IOException {
137         String json = retrieveJsonString(url, username, password);
93f0b1 138         if (StringUtils.isEmpty(json)) {
JM 139             return null;
140         }
f146f2 141         return gson().fromJson(json, type);
93f0b1 142     }
8b7636 143
da0269 144     /**
JM 145      * Reads a gson object from the specified url.
146      * 
147      * @param url
148      * @param clazz
149      * @param username
150      * @param password
151      * @return the deserialized object
152      * @throws {@link IOException}
153      */
154     public static <X> X retrieveJson(String url, Class<X> clazz, String username, char[] password)
155             throws IOException {
156         String json = retrieveJsonString(url, username, password);
157         if (StringUtils.isEmpty(json)) {
158             return null;
159         }
160         return gson().fromJson(json, clazz);
161     }
93f0b1 162
JM 163     /**
164      * Retrieves a JSON message.
165      * 
166      * @param url
167      * @return the JSON message as a string
31abc2 168      * @throws {@link IOException}
93f0b1 169      */
31abc2 170     public static String retrieveJsonString(String url, String username, char[] password)
JM 171             throws IOException {
565ee0 172         try {            
JM 173             URLConnection conn = ConnectionUtils.openReadConnection(url, username, password);
31abc2 174             InputStream is = conn.getInputStream();
565ee0 175             BufferedReader reader = new BufferedReader(new InputStreamReader(is, ConnectionUtils.CHARSET));
31abc2 176             StringBuilder json = new StringBuilder();
JM 177             char[] buffer = new char[4096];
178             int len = 0;
179             while ((len = reader.read(buffer)) > -1) {
180                 json.append(buffer, 0, len);
181             }
182             is.close();
183             return json.toString();
184         } catch (IOException e) {
185             if (e.getMessage().indexOf("401") > -1) {
186                 // unauthorized
187                 throw new UnauthorizedException(url);
188             } else if (e.getMessage().indexOf("403") > -1) {
189                 // requested url is forbidden by the requesting user
190                 throw new ForbiddenException(url);
8b7636 191             } else if (e.getMessage().indexOf("405") > -1) {
JM 192                 // requested url is not allowed by the server
193                 throw new NotAllowedException(url);
194             } else if (e.getMessage().indexOf("501") > -1) {
195                 // requested url is not recognized by the server
196                 throw new UnknownRequestException(url);
31abc2 197             }
JM 198             throw e;
93f0b1 199         }
JM 200     }
201
202     /**
203      * Sends a JSON message.
204      * 
205      * @param url
206      *            the url to write to
207      * @param json
208      *            the json message to send
209      * @return the http request result code
31abc2 210      * @throws {@link IOException}
93f0b1 211      */
31abc2 212     public static int sendJsonString(String url, String json) throws IOException {
JM 213         return sendJsonString(url, json, null, null);
214     }
215
216     /**
217      * Sends a JSON message.
218      * 
219      * @param url
220      *            the url to write to
221      * @param json
222      *            the json message to send
223      * @param username
224      * @param password
225      * @return the http request result code
226      * @throws {@link IOException}
227      */
228     public static int sendJsonString(String url, String json, String username, char[] password)
229             throws IOException {
230         try {
565ee0 231             byte[] jsonBytes = json.getBytes(ConnectionUtils.CHARSET);
JM 232             URLConnection conn = ConnectionUtils.openConnection(url, username, password);
233             conn.setRequestProperty("Content-Type", "text/plain;charset=" + ConnectionUtils.CHARSET);
31abc2 234             conn.setRequestProperty("Content-Length", "" + jsonBytes.length);
JM 235
236             // write json body
237             OutputStream os = conn.getOutputStream();
238             os.write(jsonBytes);
239             os.close();
240
241             int status = ((HttpURLConnection) conn).getResponseCode();
242             return status;
243         } catch (IOException e) {
244             if (e.getMessage().indexOf("401") > -1) {
245                 // unauthorized
246                 throw new UnauthorizedException(url);
247             } else if (e.getMessage().indexOf("403") > -1) {
248                 // requested url is forbidden by the requesting user
249                 throw new ForbiddenException(url);
8b7636 250             } else if (e.getMessage().indexOf("405") > -1) {
JM 251                 // requested url is not allowed by the server
252                 throw new NotAllowedException(url);
b2fde8 253             } else if (e.getMessage().indexOf("501") > -1) {
JM 254                 // requested url is not recognized by the server
255                 throw new UnknownRequestException(url);
31abc2 256             }
JM 257             throw e;
258         }
93f0b1 259     }
JM 260
f146f2 261     // build custom gson instance with GMT date serializer/deserializer
JM 262     // http://code.google.com/p/google-gson/issues/detail?id=281
263     private static Gson gson() {
264         GsonBuilder builder = new GsonBuilder();
265         builder.registerTypeAdapter(Date.class, new GmtDateTypeAdapter());
266         builder.setPrettyPrinting();
267         return builder.create();
268     }
269
270     private static class GmtDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
271         private final DateFormat dateFormat;
272
273         private GmtDateTypeAdapter() {
274             dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
275             dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
276         }
277
278         @Override
279         public synchronized JsonElement serialize(Date date, Type type,
280                 JsonSerializationContext jsonSerializationContext) {
281             synchronized (dateFormat) {
282                 String dateFormatAsString = dateFormat.format(date);
283                 return new JsonPrimitive(dateFormatAsString);
284             }
285         }
286
287         @Override
288         public synchronized Date deserialize(JsonElement jsonElement, Type type,
289                 JsonDeserializationContext jsonDeserializationContext) {
290             try {
291                 synchronized (dateFormat) {
292                     return dateFormat.parse(jsonElement.getAsString());
293                 }
294             } catch (ParseException e) {
295                 throw new JsonSyntaxException(jsonElement.getAsString(), e);
296             }
93f0b1 297         }
JM 298     }
299 }