package com.hundsun.ares.studio.core.model.util; import java.util.Collection; import java.util.Iterator; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.Enumerator; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.ecore.util.FeatureMap.Entry; import com.hundsun.ares.studio.core.model.CorePackage; import com.hundsun.ares.studio.core.model.UserExtensibleProperty; // JSON <--> Java //------------------ // string <--> java.lang.String // number <--> java.math.Number (BigDecimal) // object <--> java.util.Map (HashMap) // array <--> java.util.Collection (ArrayList) // true <--> java.lang.Boolean.TRUE // false <--> java.lang.Boolean.FALSE // null <--> null public class EMFJSONUtil { private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String NULL = "null"; //$NON-NLS-1$ // public static Object read(String jsonString) { // return parse(new StringCharacterIterator(jsonString)); // } public static String write(EObject jsonObject) { StringBuffer buffer = new StringBuffer(); writeValue(jsonObject, buffer); return buffer.toString(); } // private static RuntimeException error(String message, CharacterIterator it) { // return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$ // } private static RuntimeException error(String message) { return new IllegalStateException(message); } // private static Object parse(CharacterIterator it) { // parseWhitespace(it); // Object result = parseValue(it); // parseWhitespace(it); // // if (it.current() != CharacterIterator.DONE) // throw error("should be done", it); //$NON-NLS-1$ // return result; // } // // private static void parseWhitespace(CharacterIterator it) { // char c = it.current(); // while (Character.isWhitespace(c)) // c = it.next(); // } // // private static Object parseValue(CharacterIterator it) { // switch (it.current()) { // case '{' : // return parseObject(it); // case '[' : // return parseArray(it); // case '"' : // return parseString(it); // case '-' : // case '0' : // case '1' : // case '2' : // case '3' : // case '4' : // case '5' : // case '6' : // case '7' : // case '8' : // case '9' : // return parseNumber(it); // case 't' : // parseText(Boolean.TRUE.toString(), it); // return Boolean.TRUE; // case 'f' : // parseText(Boolean.FALSE.toString(), it); // return Boolean.FALSE; // case 'n' : // parseText(NULL, it); // return null; // } // throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$; // } // // private static Map parseObject(CharacterIterator it) { // it.next(); // parseWhitespace(it); // if (it.current() == '}') { // it.next(); // return Collections.EMPTY_MAP; // } // // Map map = new HashMap(); // while (true) { // if (it.current() != '"') // throw error("expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ // String key = parseString(it); // if (map.containsKey(key)) // throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$ // parseWhitespace(it); // if (it.current() != ':') // throw error("expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ // it.next(); // parseWhitespace(it); // Object value = parseValue(it); // map.put(key, value); // parseWhitespace(it); // if (it.current() == ',') { // it.next(); // parseWhitespace(it); // continue; // } // // if (it.current() != '}') // throw error("expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ // break; // } // it.next(); // return map; // } // // private static List parseArray(CharacterIterator it) { // it.next(); // parseWhitespace(it); // if (it.current() == ']') { // it.next(); // return Collections.EMPTY_LIST; // } // // List list = new ArrayList(); // while (true) { // Object value = parseValue(it); // list.add(value); // parseWhitespace(it); // if (it.current() == ',') { // it.next(); // parseWhitespace(it); // continue; // } // // if (it.current() != ']') // throw error("expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ // break; // } // it.next(); // return list; // } // // private static void parseText(String string, CharacterIterator it) { // int length = string.length(); // char c = it.current(); // for (int i = 0; i < length; i++) { // if (c != string.charAt(i)) // throw error("expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$; // c = it.next(); // } // } // // private static Object parseNumber(CharacterIterator it) { // StringBuffer buffer = new StringBuffer(); // char c = it.current(); // while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E') { // buffer.append(c); // c = it.next(); // } // try { // return new BigDecimal(buffer.toString()); // } catch (NumberFormatException e) { // throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$; // } // } // // private static String parseString(CharacterIterator it) { // char c = it.next(); // if (c == '"') { // it.next(); // return EMPTY_STRING; // } // StringBuffer buffer = new StringBuffer(); // while (c != '"') { // if (Character.isISOControl(c)) // throw error("illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$); // // if (c == '\\') { // c = it.next(); // switch (c) { // case '"' : // case '\\' : // case '/' : // buffer.append(c); // break; // case 'b' : // buffer.append('\b'); // break; // case 'f' : // buffer.append('\f'); // break; // case 'n' : // buffer.append('\n'); // break; // case 'r' : // buffer.append('\r'); // break; // case 't' : // buffer.append('\t'); // break; // case 'u' : // StringBuffer unicode = new StringBuffer(4); // for (int i = 0; i < 4; i++) { // unicode.append(it.next()); // } // try { // buffer.append((char) Integer.parseInt(unicode.toString(), 16)); // } catch (NumberFormatException e) { // throw error("expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);); // } // break; // default : // throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);); // } // } else // buffer.append(c); // // c = it.next(); // } // c = it.next(); // return buffer.toString(); // } private static void writeValue(Object value, StringBuffer buffer) { if (value == null){ buffer.append(NULL); } else if (value instanceof Enumerator){ //ö�� buffer.append(((Enumerator)value).getValue()); } else if (value instanceof EEnumLiteral){ //ö�� if(value instanceof EEnumLiteral){ buffer.append(((EEnumLiteral)value).getValue()); return; } } else if (value instanceof Boolean || value instanceof Number) buffer.append(value.toString()); else if (value instanceof String) writeString((String) value, buffer); else if (value instanceof FeatureMap) writeFeatureMap((FeatureMap) value, buffer); else if (value instanceof EObject) writeObject((EObject) value, buffer); else if (value instanceof Map) writeMap((Map) value, buffer); else if (value instanceof Collection) writeArray((Collection) value, buffer); else throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$);); } // private static void writeExtensibleModel(ExtensibleModel model, StringBuffer buffer) { // buffer.append('{'); // for (Iterator iterator = model.eClass().getEAllStructuralFeatures().iterator(); iterator.hasNext();) { // EStructuralFeature feature = (EStructuralFeature) iterator.next(); // writeString(feature.getName(), buffer); // buffer.append(':'); // writeValue(model.eGet(feature), buffer); // buffer.append(','); // } // if (buffer.charAt(buffer.length() - 1) == ',') // buffer.setCharAt(buffer.length() - 1, '}'); // else // buffer.append('}'); // } private static void writeObject(EObject eObject, StringBuffer buffer) { buffer.append('{'); for (Iterator iterator = eObject.eClass().getEAllStructuralFeatures().iterator(); iterator.hasNext();) { EStructuralFeature feature = (EStructuralFeature) iterator.next(); // 2012��3��29��15:38:19 gongyf // �����л������Ի��ǿ�����Ҫ����ȡ�� // if (feature.isTransient()) { // // �����л������Բ�ת�� // continue; // } if (feature instanceof EReference) { if (!((EReference) feature).isContainment()) { // �����л��������Ķ��� continue; } } // ������չģ�͵�data��data2��Ҫ���⴦�� if (feature.equals(CorePackage.Literals.EXTENSIBLE_MODEL__DATA)) { EMap<String, String> map = (EMap<String, String>) eObject.eGet(feature); for (java.util.Map.Entry<String, String> entry : map.entrySet()) { writeString(entry.getKey(), buffer); buffer.append(':'); writeValue(entry.getValue(), buffer); buffer.append(','); } } else if (feature.equals(CorePackage.Literals.EXTENSIBLE_MODEL__DATA2)) { EMap<String, EObject> map = (EMap<String, EObject>) eObject.eGet(feature); for (java.util.Map.Entry<String, EObject> entry : map.entrySet()) { //2013��5��24��10:40:56 ���ӿ�ָ���ж� if(null == entry) continue; if(null == entry.getValue()) continue; if (entry.getValue() instanceof UserExtensibleProperty) { EMap<String, String> userMap = ((UserExtensibleProperty)entry.getValue()).getMap(); for (java.util.Map.Entry<String, String> mapEntry : userMap.entrySet()) { writeString("user_" + mapEntry.getKey(), buffer); buffer.append(':'); writeValue(mapEntry.getValue(), buffer); buffer.append(','); } } else { for (Iterator iterator2 = entry.getValue().eClass().getEAllStructuralFeatures().iterator(); iterator2.hasNext();) { EStructuralFeature feature2 = (EStructuralFeature) iterator2.next(); writeString(entry.getKey() + "_" + feature2.getName(), buffer); buffer.append(':'); writeValue(entry.getValue().eGet(feature2), buffer); buffer.append(','); } } } } else { String name = feature.getName(); name = StringUtils.replace(name, ".", "_"); writeString(name, buffer); buffer.append(':'); writeValue(eObject.eGet(feature), buffer); buffer.append(','); } } if (buffer.charAt(buffer.length() - 1) == ',') buffer.setCharAt(buffer.length() - 1, '}'); else buffer.append('}'); } private static void writeFeatureMap(FeatureMap featureMap, StringBuffer buffer) { buffer.append('{'); for (Iterator iterator = featureMap.iterator(); iterator.hasNext();) { FeatureMap.Entry entry = (Entry) iterator.next(); writeString(entry.getEStructuralFeature().getName(), buffer); buffer.append(':'); writeValue(entry.getValue(), buffer); buffer.append(','); } if (buffer.charAt(buffer.length() - 1) == ',') buffer.setCharAt(buffer.length() - 1, '}'); else buffer.append('}'); } private static void writeMap(Map map, StringBuffer buffer) { buffer.append('{'); for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) { Object key = iterator.next(); if (!(key instanceof String)) throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$);); writeString((String) key, buffer); buffer.append(':'); writeValue(map.get(key), buffer); buffer.append(','); } if (buffer.charAt(buffer.length() - 1) == ',') buffer.setCharAt(buffer.length() - 1, '}'); else buffer.append('}'); } private static void writeArray(Collection collection, StringBuffer buffer) { buffer.append('['); for (Iterator iterator = collection.iterator(); iterator.hasNext();) { writeValue(iterator.next(), buffer); buffer.append(','); } if (buffer.charAt(buffer.length() - 1) == ',') buffer.setCharAt(buffer.length() - 1, ']'); else buffer.append(']'); } private static void writeString(String name, StringBuffer buffer) { buffer.append('"'); int length = name.length(); for (int i = 0; i < length; i++) { char c = name.charAt(i); switch (c) { case '"' : case '\\' : case '/' : buffer.append('\\'); buffer.append(c); break; case '\b' : buffer.append("\\b"); //$NON-NLS-1$ break; case '\f' : buffer.append("\\f"); //$NON-NLS-1$ break; case '\n' : buffer.append("\\n"); //$NON-NLS-1$ break; case '\r' : buffer.append("\\r"); //$NON-NLS-1$ break; case '\t' : buffer.append("\\t"); //$NON-NLS-1$ break; default : if (Character.isISOControl(c)) { buffer.append("\\u"); //$NON-NLS-1$ String hexString = Integer.toHexString(c); for (int j = hexString.length(); j < 4; j++) buffer.append('0'); buffer.append(hexString); } else buffer.append(c); } } buffer.append('"'); } }