package com.openfeint.internal.request; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.google.api.client.escape.PercentEscaper; public class OrderedArgList { ArrayList<NameValuePair> mArgs; public OrderedArgList() { mArgs = new ArrayList<NameValuePair>(); } public NameValuePair remove(String key) { for (NameValuePair p : mArgs) { if (p.getName().equals(key)) { mArgs.remove(p); return p; } } return null; } public OrderedArgList(Map<String,Object> args) { mArgs = new ArrayList<NameValuePair>(); accumulate(args, null); } public OrderedArgList(JSONObject j) { mArgs = new ArrayList<NameValuePair>(); try { accumulate(j, null); } catch (JSONException e) { } } public OrderedArgList(OrderedArgList rhs) { mArgs = new ArrayList<NameValuePair>(); mArgs.addAll(rhs.getArgs()); } public List<NameValuePair> getArgs() { return mArgs; } public List<NameValuePair> getArgsSorted() { List<NameValuePair> s = new ArrayList<NameValuePair>(); s.addAll(mArgs); Collections.sort(s, new NVPComparator()); return s; } public void put(String k, String v) { mArgs.add(new BasicNameValuePair(k,v)); } public String getArgString() { return getArgString(getArgs()); } public String getArgStringSorted() { return getArgString(getArgsSorted()); } private static String getArgString(List<NameValuePair> pairs) { StringBuilder accumulator = null; PercentEscaper escaper = new PercentEscaper(PercentEscaper.SAFECHARS_URLENCODER, true); for (NameValuePair nvp : pairs) { if (accumulator == null) { accumulator = new StringBuilder(); } else { accumulator.append('&'); } accumulator.append(escaper.escape(nvp.getName())); accumulator.append('='); if (nvp.getValue() != null) { accumulator.append(escaper.escape(nvp.getValue())); } } return accumulator == null ? null : accumulator.toString(); } private void accumulate(final JSONArray jsonArray, final String fieldName) throws JSONException { final int size = jsonArray.length(); for (int arrayIndex=0; arrayIndex<size; ++arrayIndex) { Object arrayEntry = jsonArray.get(arrayIndex); if (arrayEntry instanceof JSONObject) { accumulate((JSONObject)arrayEntry, fieldName); } else if (arrayEntry instanceof JSONArray) { accumulate((JSONArray)arrayEntry, fieldName); } else { put(fieldName, arrayEntry.toString()); } } } private void accumulate(final JSONObject jsonObject, final String prefix) throws JSONException { final Iterable<String> objectIteratable = new Iterable<String>() { @SuppressWarnings("unchecked") public Iterator<String> iterator() { return jsonObject.keys(); } }; for (String fieldName : objectIteratable) { Object fieldObject = jsonObject.get(fieldName); String subKey = prefix == null ? fieldName : prefix + "[" + fieldName + "]"; if (fieldObject instanceof JSONObject) { accumulate((JSONObject)fieldObject, subKey); } else if (fieldObject instanceof JSONArray) { accumulate((JSONArray)fieldObject, subKey); } else { put(subKey, fieldObject.toString()); } } } private void accumulate(final Map<String, Object> args, final String prefix) { for (Map.Entry<String,Object> me : args.entrySet()) { final String k = me.getKey(); final Object v = me.getValue(); // not handling arrays right now. String subKey = prefix == null ? k : prefix + "[" + k + "]"; if (v instanceof Map<?,?>) { accumulate(stringObjectMap(v), subKey); } else { put(subKey, v.toString()); } } } @SuppressWarnings("unchecked") final private Map<String, Object> stringObjectMap(final Object v) { return (Map<String,Object>)v; } static class NVPComparator implements Comparator<NameValuePair> { public int compare(NameValuePair a, NameValuePair b) { int r = a.getName().compareTo(b.getName()); if (r == 0) { return a.getValue().compareTo(b.getValue()); } return r; } } };