1/* 2 * Copyright (C) 2010 Google Inc. 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 17package com.android.i18n.addressinput; 18 19import org.json.JSONArray; 20import org.json.JSONException; 21import org.json.JSONObject; 22import org.json.JSONTokener; 23 24import java.util.ArrayList; 25import java.util.Iterator; 26 27/** 28 * Compatibility methods on top of the JSON data. 29 */ 30class JsoMap extends JSONObject { 31 32 /** 33 * Construct a JsoMap object given some json text. This method directly evaluates the String 34 * that you pass in; no error or safety checking is performed, so be very careful about the 35 * source of your data. 36 * 37 * @param json JSON text describing an address format 38 * @return a JsoMap object made from the supplied JSON. 39 */ 40 static JsoMap buildJsoMap(String json) throws JSONException { 41 return new JsoMap(new JSONTokener(json)); 42 } 43 44 /** 45 * Construct an empty JsoMap. 46 * 47 * @return the empty object. 48 */ 49 static JsoMap createEmptyJsoMap() { 50 return new JsoMap(); 51 } 52 53 /** 54 * constructor. 55 */ 56 protected JsoMap() { 57 } 58 59 private JsoMap(JSONTokener readFrom) throws JSONException { 60 super(readFrom); 61 } 62 63 private JsoMap(JSONObject copyFrom, String[] names) throws JSONException { 64 super(copyFrom, names); 65 } 66 67 /** 68 * Remove the specified key. 69 * 70 * @param key key name. 71 */ 72 void delKey(String key) { 73 super.remove(key); 74 } 75 76 /** 77 * Retrieve the string value for specified key. 78 * 79 * @param key key name. 80 * @return string value. 81 * @throws ClassCastException, IllegalArgumentException. 82 */ 83 @Override 84 public String get(String key) { // throws ClassCastException, IllegalArgumentException 85 try { 86 Object o = super.get(key); 87 if (o instanceof String) { 88 return (String) o; 89 } else if (o instanceof Integer) { 90 throw new IllegalArgumentException(); 91 } else { 92 throw new ClassCastException(); 93 } 94 } catch (JSONException e) { 95 return null; 96 } 97 } 98 99 /** 100 * Access JSONObject.get(String) which is shadowed by JsoMap.get(String). 101 * 102 * @param name A key string. 103 * @return The object associated with the key. 104 * @throws JSONException if the key is not found. 105 */ 106 private Object getObject(String name) throws JSONException { 107 return super.get(name); 108 } 109 110 /** 111 * Retrieves the integer value for specified key. 112 * 113 * @return integer value or -1 if value is undefined. 114 */ 115 @Override 116 public int getInt(String key) { 117 try { 118 Object o = super.get(key); 119 if (o instanceof Integer) { 120 return ((Integer) o).intValue(); 121 } else { 122 throw new RuntimeException("Something other than an int was returned"); 123 } 124 } catch (JSONException e) { 125 return -1; 126 } 127 } 128 129 /** 130 * Collect all the keys and return as a JSONArray. 131 * 132 * @return A JSONArray that contains all the keys. 133 */ 134 JSONArray getKeys() { 135 return super.names(); 136 } 137 138 /** 139 * Retrieve the JsoMap object for specified key. 140 * 141 * @param key key name. 142 * @return JsoMap object. 143 * @throws ClassCastException, IllegalArgumentException. 144 */ 145 @SuppressWarnings("unchecked") 146 // JSONObject.keys() has no type information. 147 JsoMap getObj(String key) 148 throws ClassCastException, IllegalArgumentException { 149 try { 150 Object o = super.get(key); 151 if (o instanceof JSONObject) { 152 JSONObject value = (JSONObject) o; 153 ArrayList<String> keys = new ArrayList<String>(value.length()); 154 for (Iterator<String> it = value.keys(); it.hasNext();) { 155 keys.add(it.next()); 156 } 157 String[] names = new String[keys.size()]; 158 return new JsoMap(value, keys.toArray(names)); 159 } else if (o instanceof Integer) { 160 throw new IllegalArgumentException(); 161 } else { 162 throw new ClassCastException(); 163 } 164 } catch (JSONException e) { 165 return null; 166 } 167 } 168 169 /** 170 * Check if the object has specified key. 171 * 172 * @param key The key name to be checked. 173 * @return true if key can be found. 174 */ 175 boolean containsKey(String key) { 176 return super.has(key); 177 } 178 179 /** 180 * Merge those keys not found in this object from specified object. 181 * 182 * @param obj The other object to be merged. 183 */ 184 void mergeData(JsoMap obj) { 185 if (obj == null) { 186 return; 187 } 188 189 JSONArray names = obj.names(); 190 if (names == null) { 191 return; 192 } 193 194 for (int i = 0; i < names.length(); i++) { 195 try { 196 String name = names.getString(i); 197 try { 198 if (!super.has(name)) { 199 super.put(name, obj.getObject(name)); 200 } 201 } catch (JSONException e) { 202 throw new RuntimeException(e); 203 } 204 } catch (JSONException e) { 205 // Ignored. 206 } 207 } 208 } 209 210 /** 211 * Save a string to string mapping into this map. 212 * 213 * @param key the string key. 214 * @param value the String value. 215 */ 216 void put(String key, String value) { 217 try { 218 super.put(key, value); 219 } catch (JSONException e) { 220 throw new RuntimeException(e); 221 } 222 } 223 224 /** 225 * Save a string to integer mapping into this map. 226 * 227 * @param key the string key. 228 * @param value the integer value. 229 */ 230 void putInt(String key, int value) { 231 try { 232 super.put(key, value); 233 } catch (JSONException e) { 234 throw new RuntimeException(e); 235 } 236 } 237 238 /** 239 * Save a string to JSONObject mapping into this map. 240 * 241 * @param key the string key. 242 * @param value a JSONObject as value. 243 */ 244 void putObj(String key, JSONObject value) { 245 try { 246 super.put(key, value); 247 } catch (JSONException e) { 248 throw new RuntimeException(e); 249 } 250 } 251 252 String string() throws ClassCastException, IllegalArgumentException { 253 StringBuilder sb = new StringBuilder("JsoMap[\n"); 254 JSONArray keys = getKeys(); 255 for (int i = 0; i < keys.length(); i++) { 256 String key; 257 try { 258 key = keys.getString(i); 259 } catch (JSONException e) { 260 throw new RuntimeException(e); 261 } 262 sb.append('(').append(key).append(':').append(get(key)).append(')').append('\n'); 263 } 264 sb.append(']'); 265 return sb.toString(); 266 } 267 268 String map() throws ClassCastException, IllegalArgumentException { 269 StringBuilder sb = new StringBuilder("JsoMap[\n"); 270 JSONArray keys = getKeys(); 271 for (int i = 0; i < keys.length(); i++) { 272 String key; 273 try { 274 key = keys.getString(i); 275 } catch (JSONException e) { 276 throw new RuntimeException(e); 277 } 278 sb.append('(').append(key).append(':').append(getObj(key).string()).append(')') 279 .append('\n'); 280 } 281 sb.append(']'); 282 return sb.toString(); 283 } 284} 285