Ville Saalo avatar Ville Saalo committed 548660c

Added a new method for sorting JSONArrays of JSONObjects according to multiple criteria.

Also added some Javadoc comments.

Comments (0)

Files changed (2)

src/com/saibotd/bitbeaker/Helper.java

 		return "";
 	}
 	
+	/**
+	 * Formats the given date string that's in the "yyyy-MM-dd HH:mm:ssZ" format
+	 * into a nicer date + time string according to the current locale.
+	 * @param utcdate_string Timestamp
+	 * @return Localized, nice version of the given timestamp
+	 */
 	public static String dateFormat(String utcdate_string){
 		try {
 			SimpleDateFormat source_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
 		return "";
 	}
 	
+	/**
+	 * Checks whether the given string is null, empty or
+	 * consists only of whitespace.
+	 * @param string The string to be examined
+	 * @return True if the string is null, empty or whitespace only
+	 */
 	public static boolean isEmpty(final String string) {
 		if( string == null ) return true;
 		return string.trim().equals("");
 	}
 	
+	/**
+	 * The same as {@link #isEmpty(String)} but also counts the string
+	 * "null" (with any amount of leading or trailing whitespace) as empty.
+	 * @param string The string to be examined
+	 * @return True if the string is null, "null", empty or whitespace only
+	 */
 	public static boolean isJsonEmpty(final String string) {
 		return isEmpty(string) || string.trim().equals("null");
 	}
 		return "<a href=\"" + url + "\">" + url + "</a>";
 	}
 
+	/**
+	 * Converts a map of key-value pairs into a string of parameters that
+	 * can be appended into an URL. For example, if the input is a map like
+	 * "[foo : bar, baz : zok]", then the output is "?foo=bar&baz=zok".
+	 * @param postParams Map of parameters and their values
+	 * @return A string that can be appended into an URL
+	 */
 	public static String convertMapToUrlParams(Map<String, String> postParams) {
 		if (postParams == null || postParams.isEmpty()) {
 			return "";
 	/**
 	 * Sorts a JSONArray that consists of JSONObjects. 
 	 * @param array A JSONArray that contains only JSONObjects
-	 * @param parameter The key to the value in the JSONObjects by which to sort
+	 * @param key The key to the value in the JSONObjects by which to sort
 	 * @param direction Whether to have an ascending (a...z) or descending (z...a) sort
 	 * @return A JSONArray with its contents sorted by the given parameters
 	 */
-	public static JSONArray getSortedJsonObjectArray(JSONArray array, String parameter, Sort direction) {
+	public static JSONArray getSortedJsonObjectArray(JSONArray array, String key, Sort direction) {
+		final String[] params = {key};
+		final Sort[] dirs = {direction};
+		return getSortedJsonObjectArray(array, params, dirs);
+	}
+	
+	/**
+	 * Sorts a JSONArray that consists of JSONObjects. Multiple sort keys can be defined.
+	 * @param array A JSONArray that contains only JSONObjects
+	 * @param keys The keys to the values by which to sort
+	 * @param directions The directions on how to sort by each of those aforementioned 
+	 *                   values: ascending or descending. If this array is shorter than
+	 *                   the array of keys, then the default sort order for the remaining
+	 *                   keys is ascending.
+	 * @return A JSONArray with its contents sorted by the given parameters
+	 */
+	public static JSONArray getSortedJsonObjectArray(JSONArray array, String[] keys, Sort[] directions) {
 		try {
 			List<JSONObject> list = getJsonArrayAsList(array);
 			
-			Collections.sort(list, new JSONObjectComparator(parameter, direction));
+			Collections.sort(list, new JSONObjectComparator(keys, directions));
 			
 			return getListAsJsonArray(list);
 		} catch (JSONException e) {
-			Log.d("Helper.getSortedJsonArray", "Fail: " + e);
+			Log.d("Helper.getSortedJsonObjectArray", "Fail: " + e);
 			return array;
 		}
 	}
 	
 	/**
-	 * A class that compares two JSONObjects by the values of the given key.
+	 * A class that compares two JSONObjects by the values of the given keys.
+	 * If there are more keys than sort directions, the default sorting 
+	 * direction is ascending.
 	 * To be used with, for example, the 
 	 * {@link java.util.Collections#sort(List, Comparator)} method. 
 	 */
 	private static class JSONObjectComparator implements Comparator<JSONObject> {
-		private final String parameter;
-		private final Sort direction;
-		
-		public JSONObjectComparator(String param, Sort dir) {
-			parameter = param;
-			direction = dir;
+		private final String[] parameters;
+		private final Sort[] directions;
+
+		public JSONObjectComparator(String[] params, Sort[] dirs) {
+			parameters = params;
+			directions = dirs;
 		}
 
 		@Override
 		public int compare(JSONObject a, JSONObject b) {
 			try {
-				return a.getString(parameter).compareTo(b.getString(parameter)) * direction.getFactor();
+				int result = 0;
+				for (int i = 0; i < parameters.length; i++) {
+					Sort dir = i < directions.length ? directions[i] : Sort.ASCENDING;
+					result = a.getString(parameters[i]).compareTo(b.getString(parameters[i])) * dir.getFactor();
+					if (result != 0) {
+						break;
+					}
+				}
+				return result;
 			} catch (JSONException e) {
 				Log.d("JSONObjectComparator", "Fail: " + e);
 				return 0;

src/com/saibotd/bitbeaker/tests/HelperTest.java

 		assertEquals("Finland becomes independent", result.getJSONObject(i++).get("event"));
 	}
 	
+	public void test_getSortedJsonObjectArray_with_two_sort_keys_and_directions() throws Exception {
+		final String[] keys = {"num", "txt"};
+		final Sort[] directions = {Sort.DESCENDING, Sort.ASCENDING};
+		JSONArray result = Helper.getSortedJsonObjectArray(getAnotherTestArray(), keys, directions);
+		
+		int i = 0;
+		assertEquals("300", result.getJSONObject(i).get("num"));
+		assertEquals("C", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("200", result.getJSONObject(i).get("num"));
+		assertEquals("A", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("200", result.getJSONObject(i).get("num"));
+		assertEquals("B", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("100", result.getJSONObject(i).get("num"));
+		assertEquals("D", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("100", result.getJSONObject(i).get("num"));
+		assertEquals("E", result.getJSONObject(i++).get("txt"));
+	}
+	
+	public void test_getSortedJsonObjectArray_with_two_sort_keys_and_directions_inverted() throws Exception {
+		final String[] keys = {"num", "txt"};
+		final Sort[] directions = {Sort.ASCENDING, Sort.DESCENDING};
+		JSONArray result = Helper.getSortedJsonObjectArray(getAnotherTestArray(), keys, directions);
+		
+		int i = 0;
+		assertEquals("100", result.getJSONObject(i).get("num"));
+		assertEquals("E", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("100", result.getJSONObject(i).get("num"));
+		assertEquals("D", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("200", result.getJSONObject(i).get("num"));
+		assertEquals("B", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("200", result.getJSONObject(i).get("num"));
+		assertEquals("A", result.getJSONObject(i++).get("txt"));
+		
+		assertEquals("300", result.getJSONObject(i).get("num"));
+		assertEquals("C", result.getJSONObject(i++).get("txt"));
+	}
+	
+	public void test_getSortedJsonObjectArray_with_two_sort_keys_but_just_one_direction() throws Exception {
+		final String[] keys = {"txt", "num"};
+		final Sort[] directions = {Sort.ASCENDING};
+		JSONArray result = Helper.getSortedJsonObjectArray(getAnotherTestArray(), keys, directions);
+		
+		int i = 0;
+		assertEquals("A", result.getJSONObject(i).get("txt"));
+		assertEquals("200", result.getJSONObject(i++).get("num"));
+		
+		assertEquals("B", result.getJSONObject(i).get("txt"));
+		assertEquals("200", result.getJSONObject(i++).get("num"));
+		
+		assertEquals("C", result.getJSONObject(i).get("txt"));
+		assertEquals("300", result.getJSONObject(i++).get("num"));
+		
+		assertEquals("D", result.getJSONObject(i).get("txt"));
+		assertEquals("100", result.getJSONObject(i++).get("num"));
+		
+		assertEquals("E", result.getJSONObject(i).get("txt"));
+		assertEquals("100", result.getJSONObject(i++).get("num"));
+	}
+	
 	private JSONArray getTestArray() throws Exception {
 		JSONArray array = new JSONArray();
 		JSONObject o1 = new JSONObject();
 		array.put(o2);
 		return array;
 	}
+	
+	private JSONArray getAnotherTestArray() throws Exception {
+		JSONArray array = new JSONArray();
+		JSONObject o1 = new JSONObject();
+		JSONObject o2 = new JSONObject();
+		JSONObject o3 = new JSONObject();
+		JSONObject o4 = new JSONObject();
+		JSONObject o5 = new JSONObject();
+		o1.put("num", "100"); o1.put("txt", "D");
+		o2.put("num", "100"); o2.put("txt", "E");
+		o3.put("num", "200"); o3.put("txt", "A");
+		o4.put("num", "200"); o4.put("txt", "B");
+		o5.put("num", "300"); o5.put("txt", "C");
+		array.put(o1);
+		array.put(o3);
+		array.put(o4);
+		array.put(o2);
+		array.put(o5);
+		return array;
+	}
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.