/** * (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others. * * 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 */ package org.jabylon.rest.api.json; import java.util.Collection; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.jabylon.properties.PropertyFile; import org.jabylon.properties.PropertyFileDescriptor; public class JSONEmitter { private PermissionCallback permissionCallback; public JSONEmitter(PermissionCallback permissionCallback) { super(); this.permissionCallback = permissionCallback; } public void serialize(EObject resolvable, StringBuilder result, int depth) { writeObject(resolvable, result, depth); } private void writeObject(EObject object, StringBuilder result, int depth) { if (depth == 0) return; result.append("{"); writeAttributes(object, result, depth); result.append("}"); } private void writeAttributes(EObject object, StringBuilder result, int depth) { EList<EStructuralFeature> eAllAttributes = object.eClass().getEAllStructuralFeatures(); boolean didWriteSeparator = false; for (EStructuralFeature eAttribute : eAllAttributes) { if (eAttribute.isTransient()) continue; if (!object.eIsSet(eAttribute)) continue; if (eAttribute instanceof EReference) { EReference ref = (EReference)eAttribute; if (!ref.isContainment()) continue; if (depth == 1) continue; } result.append("\""); result.append(eAttribute.getName()); result.append("\""); result.append(":"); if (eAttribute.isMany()) { writeMany(object, eAttribute, result, depth); didWriteSeparator = true; result.append(","); } else { if(writeSingle(object, eAttribute, result, depth)) { didWriteSeparator = true; result.append(","); } } } if (object instanceof PropertyFileDescriptor && depth>1) { PropertyFileDescriptor descriptor = (PropertyFileDescriptor)object; PropertyFile properties = descriptor.loadProperties(); if(!properties.getProperties().isEmpty()) { didWriteSeparator = false; result.append("\"propertyFile\":"); writeObject(properties, result, depth-1); } } if (didWriteSeparator) result.setLength(result.length() - 1); } private boolean writeSingle(EObject object, EStructuralFeature eAttribute, StringBuilder result, int depth) { return writeSingleValue(object.eGet(eAttribute), eAttribute, result, depth); } private boolean writeSingleValue(Object value, EStructuralFeature attribute, StringBuilder result, int depth) { if (value instanceof String) { String string = (String)value; result.append("\""); result.append(string); result.append("\""); return true; } else if (value instanceof Boolean) { result.append(value); return true; } else if (value instanceof Number) { result.append(value); return true; } else if (attribute instanceof EAttribute) { String newValue = attribute.getEContainingClass() .getEPackage() .getEFactoryInstance() .convertToString(((EAttribute)attribute).getEAttributeType(), value); result.append("\""); result.append(newValue); result.append("\""); return true; } else if (attribute instanceof EReference) { EReference ref = (EReference)attribute; if (!ref.isContainment()) return false; if (value instanceof EObject) { if(permissionCallback.isAuthorized((EObject) value)) { writeObject((EObject)value, result, depth - 1); return true; } } } return false; } @SuppressWarnings("rawtypes") private void writeMany(EObject object, EStructuralFeature eAttribute, StringBuilder result, int depth) { Object value = object.eGet(eAttribute); if (value instanceof Collection) { result.append("["); Collection values = (Collection)value; for (Object singleValue : values) { if(writeSingleValue(singleValue, eAttribute, result, depth)) result.append(","); } if (!values.isEmpty()) result.setLength(result.length() - 1); // remove the last ',' result.append("]"); } } }