Java tutorial
/******************************************************************************* * Copyright (c) 2014 Joachim Tessmer. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Joachim Tessmer - initial API and implementation ******************************************************************************/ package de.instantouch.model.io; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import org.eclipse.core.runtime.Platform; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import org.json.simple.parser.ParseException; import org.osgi.framework.Bundle; import de.instantouch.model.base.SnakeType; import de.instantouch.model.base.ref.SnakeReference; import de.instantouch.model.collections.SnakeEntity; import de.instantouch.model.collections.SnakeList; import de.instantouch.model.collections.SnakeMap; import de.instantouch.model.exception.SnakeModelException; import de.instantouch.model.exception.SnakeNotFoundException; import de.instantouch.model.exception.SnakeNotInitializedException; import de.instantouch.model.exception.SnakeWrongTypeException; import de.instantouch.model.log.SnakeLog; public class SnakeJSONReader { protected String content = null; protected Reader reader = null; protected InputStream input = null; public SnakeJSONReader(String jsonStr) { this.content = jsonStr; } public SnakeJSONReader(InputStream input) { this.input = input; this.reader = new InputStreamReader(input); } public Object parse() throws IOException, SnakeModelException { Object jsonObject = null; try { if (content != null) { jsonObject = JSONValue.parseWithException(content); } else if (reader != null) { jsonObject = JSONValue.parseWithException(reader); } } catch (ParseException e) { throw new SnakeModelException(e); } return jsonObject; } public void read(SnakeType type, Object value) throws SnakeModelException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException { if (type.hasReference()) { SnakeReference ref = type.getReference(); if (ref == null) { throw new SnakeNotInitializedException("reference is not initialized"); } SnakeType key = ref.getKey(); if (key == null) { throw new SnakeNotInitializedException("no reference key container os given"); } read(key, value); } else { if (type instanceof SnakeEntity) { readEntity((SnakeEntity) type, value); } else if (type instanceof SnakeList) { readList((SnakeList) type, value); } else if (type instanceof SnakeMap) { readMap((SnakeMap) type, value); } else if (value == null) { type.setNull(); } else if (value instanceof String) { type.set(value.toString()); } else if (value instanceof Boolean) { type.set(value.toString()); } else if (value instanceof Number) { Number number = (Number) value; if (value instanceof Double) { type.set(number.doubleValue()); } else if (value instanceof Float) { type.set(number.floatValue()); } else if (value instanceof Byte) { type.set(number.byteValue()); } else if (value instanceof Short) { type.set(number.shortValue()); } else if (value instanceof Integer) { type.set(number.intValue()); } else if (value instanceof Long) { type.set(number.longValue()); } } } } public void readEntity(SnakeEntity entity, Object value) throws SnakeModelException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException { if (!(value instanceof JSONObject)) { throw new SnakeWrongTypeException( "wrong type for entity: " + entity.getName() + " candidate: " + value); } JSONObject jsonObject = (JSONObject) value; for (SnakeType member : entity.getChildren()) { Object object = jsonObject.get(member.getName()); if (object != null) { read(member, object); } } // dynamic members for (Object key : jsonObject.keySet()) { String name = key.toString(); SnakeType member = entity.findByName(name); if (member == null) { Object obj = jsonObject.get(key); if (obj instanceof JSONObject) { JSONObject inner = (JSONObject) obj; Object classInfo = inner.get("entityClass"); Object bundleInfo = inner.get("bundle"); Bundle bundle = Platform.getBundle(bundleInfo.toString()); SnakeEntity child = (SnakeEntity) bundle.loadClass(classInfo.toString()).newInstance(); child.setName(name); readEntity(child, inner); entity.replace(name, child); } } } } public void readList(SnakeList<SnakeType> myList, Object value) throws SnakeModelException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { if (!(value instanceof JSONArray)) { throw new SnakeWrongTypeException( "couldn't extract list: " + myList.getName() + " from json object:" + value); } JSONArray jsonArray = (JSONArray) value; myList.clear(); for (int i = 0; i < jsonArray.size(); i++) { Object object = jsonArray.get(i); SnakeType child = myList.newElement(); if (child == null) { SnakeLog.error( "couldn't read list data: " + object + "for: " + myList.getClass().getCanonicalName()); break; } child.setParent(myList); read(child, object); myList.add(child); } } public void readMap(SnakeMap<SnakeType, SnakeType> myMap, Object jsonObject) throws SnakeModelException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException { if (!(jsonObject instanceof JSONArray)) { throw new SnakeWrongTypeException( "wrong type for map: " + myMap.getName() + " candidate: " + jsonObject); } myMap.clear(); JSONArray jsonMap = (JSONArray) jsonObject; for (Object obj : jsonMap) { if (!(obj instanceof JSONObject)) { throw new SnakeWrongTypeException( "wrong element for map: " + myMap.getName() + " candidate: " + obj); } JSONObject single = (JSONObject) obj; Object key = single.get("key"); if (key == null) { throw new SnakeNotFoundException( "couldn't extract key from entry: " + single + " for map: " + myMap.getName()); } SnakeType newKey = myMap.newKey(); read(newKey, key); Object value = single.get("value"); if (value == null) { throw new SnakeNotFoundException( "couldn't extract value from entry: " + single + " for map: " + myMap.getName()); } SnakeType newValue = myMap.newValue(); read(newValue, value); myMap.put(newKey, newValue); } } public void parseFor(SnakeType type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SnakeModelException, IOException { Object jsonObject = parse(); read(type, jsonObject); } public SnakeEntity parseEntity() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SnakeModelException, IOException { Object value = parse(); if (!(value instanceof JSONObject)) { throw new SnakeWrongTypeException("wrong type for entity"); } JSONObject jsonObject = (JSONObject) value; Object classInfo = jsonObject.get("entityClass"); Object bundleInfo = jsonObject.get("bundle"); Bundle bundle = Platform.getBundle(bundleInfo.toString()); SnakeEntity entity = (SnakeEntity) bundle.loadClass(classInfo.toString()).newInstance(); readEntity(entity, jsonObject); return entity; } public void close() { if (reader != null) { try { reader.close(); } catch (IOException e) { SnakeLog.log(e); } } if (input != null) { try { input.close(); } catch (IOException e) { SnakeLog.log(e); } } } }