1 package json; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.LinkedHashMap; 6 import java.util.Map.Entry; 7 8 import structures.ByteBuilder; 9 10 public class JsonObject { 11 main(String[] args)12 public static void main(String[] args){ 13 JsonObject bob=new JsonObject("name", "bob"); 14 JsonObject joe=new JsonObject("name", "joe"); 15 JsonObject sue=new JsonObject("name", "sue"); 16 JsonObject dan=new JsonObject("name", "dan"); 17 bob.add("joe", joe, true); 18 bob.add("sue", sue, true); 19 joe.add("dan", dan, true); 20 bob.add("a",1, true); 21 bob.add("b",2, true); 22 bob.add("c","3", true); 23 bob.add("a","4", true); 24 dan.add("e",5, true); 25 dan.add("f","6", true); 26 sue.add("g","7", true); 27 28 System.out.println("dan:\n"+dan); 29 System.out.println("sue:\n"+sue); 30 System.out.println("joe:\n"+joe); 31 System.out.println("bob:\n"+bob); 32 33 ArrayList<JsonObject> list=new ArrayList<JsonObject>(); 34 list.add(joe); 35 list.add(sue); 36 list.add(dan); 37 System.out.println("list:\n"+toString(list)); 38 } 39 JsonObject()40 public JsonObject(){} 41 JsonObject(String key, Object value)42 public JsonObject(String key, Object value){ 43 add(key, value, true); 44 } 45 46 // public JsonObject(String name_){ 47 // name=name_; 48 // } 49 // 50 // public JsonObject(String name_, String key, Object value){ 51 // name=name_; 52 // add(key, value); 53 // } 54 55 /** Adds a formatted value with specified decimal places */ addLiteral(String key0, double value, int decimals)56 public void addLiteral(String key0, double value, int decimals){ 57 if(omap==null){omap=new LinkedHashMap<String, Object>(8);} 58 omap.put(key0, new JsonLiteral(value, decimals)); 59 } 60 61 /** Does not add quotes for strings. 62 * This method should be used with caution as it can produce incorrectly formatted files. */ addLiteral(String key0, String value)63 public void addLiteral(String key0, String value){ 64 if(omap==null){omap=new LinkedHashMap<String, Object>(8);} 65 omap.put(key0, new JsonLiteral(value)); 66 } 67 add(String key0, Object value)68 public void add(String key0, Object value){add(key0, value, true);} addAndRename(String key0, Object value)69 public void addAndRename(String key0, Object value){add(key0, value, false);} 70 add(String key0, Object value, boolean replace)71 private void add(String key0, Object value, boolean replace){ 72 if(value!=null && value.getClass()==JsonObject.class){ 73 add(key0, (JsonObject)value, replace); 74 return; 75 } 76 int x=2; 77 String key=key0; 78 if(omap==null){omap=new LinkedHashMap<String, Object>(8);} 79 while(!replace && omap.containsKey(key)){ 80 key=key0+" "+x; 81 x++; 82 } 83 omap.put(key, value); 84 } 85 add(String key0, JsonObject value)86 public void add(String key0, JsonObject value){add(key0, value, true);} addAndRename(String key0, JsonObject value)87 public void addAndRename(String key0, JsonObject value){add(key0, value, false);} 88 add(final String key0, JsonObject value, boolean replace)89 private void add(final String key0, JsonObject value, boolean replace){ 90 int x=2; 91 String key=key0; 92 if(jmap==null){jmap=new LinkedHashMap<String, JsonObject>(8);} 93 while(!replace && jmap.containsKey(key)){ 94 key=key0+" "+x; 95 x++; 96 } 97 jmap.put(key, value); 98 } 99 toString(ArrayList<JsonObject> list)100 public static String toString(ArrayList<JsonObject> list) { 101 ByteBuilder sb=new ByteBuilder(); 102 int commas=list.size()-1; 103 for(JsonObject j : list){ 104 j.append(0, sb, false); 105 if(commas>0){ 106 sb.append(",\n"); 107 } 108 commas--; 109 } 110 return sb.toString(); 111 } 112 toText()113 public ByteBuilder toText(){ 114 return toText(null, 0, false); 115 } 116 toText(ByteBuilder sb, int level, boolean inArray)117 public ByteBuilder toText(ByteBuilder sb, int level, boolean inArray){ 118 if(sb==null){sb=new ByteBuilder();} 119 append(level, sb, inArray); 120 return sb; 121 } 122 toString(String name)123 public String toString(String name){ 124 ByteBuilder sb=new ByteBuilder(); 125 sb.append('{').append('\n'); 126 for(int i=0; i<padmult; i++){sb.append(' ');} 127 sb.append('"').append(name).append('"').append(':').append(' '); 128 toText(sb, 1, false); 129 sb.append('\n').append('}'); 130 return sb.toString(); 131 } 132 toString(Object[] array)133 public static String toString(Object[] array){ 134 ByteBuilder sb=new ByteBuilder(); 135 appendArray(sb, array, 0); 136 return sb.toString(); 137 } 138 139 @Override toString()140 public String toString(){ 141 return toText(null, 0, false).toString(); 142 } 143 toStringln()144 public String toStringln(){ 145 return toText(null, 0, false).nl().toString(); 146 } 147 append(int level, ByteBuilder sb, boolean inArray)148 public void append(int level, ByteBuilder sb, boolean inArray){ 149 int pad=padmult*level; 150 int pad2=padmult*(level+1); 151 152 sb.append('{'); 153 if(!inArray){sb.append('\n');} 154 155 int commas=(omap==null ? 0 : omap.size())+(jmap==null ? 0 : jmap.size())-1; 156 157 if(omap!=null){ 158 for(Entry<String, Object> e : omap.entrySet()){ 159 String key=e.getKey(); 160 Object value=e.getValue(); 161 if(!inArray){for(int i=0; i<pad2; i++){sb.append(' ');}} 162 163 appendEntry(sb, key, value, level, inArray); 164 165 if(commas>0){sb.append(',');} 166 if(!inArray){sb.append('\n');} 167 commas--; 168 } 169 } 170 171 if(jmap!=null){ 172 for(Entry<String, JsonObject> e : jmap.entrySet()){ 173 String key=e.getKey(); 174 JsonObject value=e.getValue(); 175 if(!inArray){for(int i=0; i<pad2; i++){sb.append(' ');}} 176 appendKey(sb, key); 177 178 value.append(level+(inArray ? 0 : 1), sb, inArray); 179 if(commas>0){sb.append(',');} 180 if(!inArray){sb.append('\n');} 181 commas--; 182 } 183 } 184 185 if(!inArray){for(int i=0; i<pad; i++){sb.append(' ');}} 186 sb.append('}'); 187 } 188 appendEntry(ByteBuilder sb, String key, Object value, int level, boolean inArray)189 private static void appendEntry(ByteBuilder sb, String key, Object value, int level, boolean inArray){ 190 appendKey(sb, key); 191 appendValue(sb, value, level, inArray); 192 } 193 appendKey(ByteBuilder sb, String key)194 private static void appendKey(ByteBuilder sb, String key){ 195 sb.append('"').append(key).append("\": "); 196 } 197 appendValue(ByteBuilder sb, Object value, int level, boolean inArray)198 private static void appendValue(ByteBuilder sb, Object value, int level, boolean inArray){ 199 final Class<?> c=(value==null ? null : value.getClass()); 200 if(c==null || value==null){ 201 sb.append("null"); 202 }else if(c==String.class){ 203 sb.append("\"").append(value.toString()).append('"'); 204 }else if(c==JsonLiteral.class){ 205 sb.append(((JsonLiteral)value).toString()); 206 }else if(c==Double.class && restictDecimals>=0){ 207 sb.append(((Double)value).doubleValue(), restictDecimals); 208 }else if(c==Float.class && restictDecimals>=0){ 209 sb.append(((Float)value).floatValue(), restictDecimals); 210 }else if(c==JsonObject.class){ 211 ((JsonObject)value).append(level+(inArray ? 0 : 1), sb, inArray); 212 }else if(c.isArray()){ 213 appendArray(sb, (Object[])value, level); 214 }else if(c==Boolean.class || value instanceof Number){//long, int, boolean 215 sb.append(value.toString()); 216 }else if(value instanceof Collection){ 217 appendCollection(sb, (Collection<?>)value, level); 218 }else{//Default behavior for unhandled classes 219 sb.append("\"").append(value.toString()).append('"'); 220 } 221 } 222 appendArray(ByteBuilder sb, Object[] array, int level)223 private static void appendArray(ByteBuilder sb, Object[] array, int level){ 224 int commas=(array==null ? 0 : array.length)-1; 225 sb.append('['); 226 if(array!=null){ 227 for(Object value : array){ 228 appendValue(sb, value, level, noNewlinesInArrays); 229 if(commas>0){sb.append(',').append(' ');} 230 commas--; 231 } 232 } 233 sb.append(']'); 234 } 235 appendCollection(ByteBuilder sb, Collection<?> stuff, int level)236 private static void appendCollection(ByteBuilder sb, Collection<?> stuff, int level){ 237 int commas=(stuff==null ? 0 : stuff.size())-1; 238 sb.append('['); 239 if(stuff!=null){ 240 for(Object value : stuff){ 241 appendValue(sb, value, level, noNewlinesInArrays); 242 if(commas>0){sb.append(',').append(' ');} 243 commas--; 244 } 245 } 246 sb.append(']'); 247 } 248 getString(String key)249 public String getString(String key){ 250 if(omap==null){return null;} 251 Object o=omap.get(key); 252 if(o==null){return null;} 253 assert(o.getClass()==String.class) : "Wrong class: "+o.getClass()+"\n"+o; 254 return (String)o; 255 } 256 getLong(String key)257 public Long getLong(String key){ 258 if(omap==null){return null;} 259 Object o=omap.get(key); 260 if(o==null){return null;} 261 assert(o.getClass()==Long.class) : "Wrong class: "+o.getClass()+"\n"+o; 262 return (Long)o; 263 } 264 getInt(String key)265 public Integer getInt(String key){ 266 assert(omap!=null); 267 Object o=omap.get(key); 268 // assert(o!=null); 269 assert(o==null || o.getClass()==Integer.class) : "Wrong class: "+o.getClass()+"\n"+o; 270 // long x=((Long)o).longValue(); 271 // assert(x>=Integer.MIN_VALUE && x<=Integer.MAX_VALUE); 272 // return (int)x; 273 return (Integer)o; 274 } 275 containsKey(String key)276 public boolean containsKey(String key){ 277 if(omap!=null && omap.containsKey(key)){return true;} 278 if(jmap!=null && jmap.containsKey(key)){return true;} 279 return false; 280 } 281 282 // public Double getDouble(String key){ 283 // if(smap==null){return null;} 284 // Object o=smap.get(key); 285 // if(o==null){return null;} 286 // assert(o.getClass()==Double.class) : "Wrong class: "+o.getClass()+"\n"+o; 287 // return (Double)o; 288 // } 289 getDouble(String key)290 public Double getDouble(String key){ 291 if(omap==null){return null;} 292 Object o=omap.get(key); 293 if(o==null){return null;} 294 if(o.getClass()==Long.class){ 295 return ((Long)o).doubleValue(); 296 } 297 assert(o.getClass()==Double.class) : "Wrong class: "+o.getClass()+"\n"+o; 298 return (Double)o; 299 } 300 getNumber(String key)301 public Number getNumber(String key){ 302 if(omap==null){return null;} 303 Object o=omap.get(key); 304 if(o==null){return null;} 305 Class<?> c=o.getClass(); 306 assert(c==Double.class || c==Long.class || c==Integer.class || c==Float.class) : "Wrong class: "+c+"\n"+o; 307 return (Number)o; 308 } 309 getArray(String key)310 public Object[] getArray(String key){ 311 if(omap==null){return null;} 312 Object o=omap.get(key); 313 if(o==null){return null;} 314 assert(o.getClass()==Object[].class) : "Wrong class: "+o.getClass()+"\n"+o; 315 return (Object[])o; 316 } 317 getJson(String key)318 public JsonObject getJson(String key){ 319 if(jmap==null){return null;} 320 return jmap.get(key); 321 } 322 removeJson(String key)323 public JsonObject removeJson(String key){ 324 if(jmap==null){return null;} 325 return jmap.remove(key); 326 } 327 removeObject(String key)328 public Object removeObject(String key){ 329 if(omap==null){return null;} 330 return omap.remove(key); 331 } 332 clearJson()333 public void clearJson(){ 334 jmap=null; 335 } 336 clearOmap()337 public void clearOmap(){ 338 omap=null; 339 } 340 toJmapArray()341 public Object[] toJmapArray() { 342 if(jmap==null){return null;} 343 Object[] array=new Object[jmapSize()]; 344 int i=0; 345 for(Entry<String, JsonObject> e : jmap.entrySet()){ 346 array[i]=e.getValue(); 347 i++; 348 } 349 return array; 350 } 351 jmapSize()352 public int jmapSize(){return jmap==null ? 0 : jmap.size();} omapSize()353 public int omapSize(){return omap==null ? 0 : omap.size();} 354 355 // public String name; 356 public LinkedHashMap<String, Object> omap; 357 public LinkedHashMap<String, JsonObject> jmap; 358 359 private static int restictDecimals=-1; 360 private static String decimalFormat="%."+restictDecimals+"f"; setDecimals(int d)361 public static synchronized void setDecimals(int d){ 362 if(d!=restictDecimals){ 363 d=restictDecimals; 364 decimalFormat="%."+restictDecimals+"f"; 365 } 366 } 367 368 public static final int padmult=3; 369 public static boolean noNewlinesInArrays=false; 370 371 } 372