/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.jdt; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.internal.compiler.env.ClassSignature; import org.eclipse.jdt.internal.compiler.env.EnumConstantSignature; import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair; import org.eclipse.jdt.internal.compiler.env.IBinaryField; import org.eclipse.jdt.internal.compiler.env.IBinaryMethod; import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.impl.Constant; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_JavaLangString; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_boolean; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_byte; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_char; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_double; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_float; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_int; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_long; import static org.eclipse.jdt.internal.compiler.lookup.TypeIds.T_short; /** * @author Evgen Vidolob */ //todo add support of java8 type annotations public class BinaryTypeConvector { private static final Gson gson = new GsonBuilder().disableHtmlEscaping().serializeNulls().create(); public static String toJsonBinaryType(IBinaryType type) { JsonObject object = new JsonObject(); object.add("annotations", toJsonAnnotations(type.getAnnotations())); object.add("enclosingMethod", type.getEnclosingMethod() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getEnclosingMethod()))); object.add("enclosingTypeName", type.getEnclosingTypeName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getEnclosingTypeName()))); object.add("fields", toJsonFields(type.getFields())); object.add("genericSignature", type.getGenericSignature() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getGenericSignature()))); object.add("interfaceNames", toJsonArrayString(type.getInterfaceNames())); object.add("memberTypes", toJsonMemberTypes(type.getMemberTypes())); object.add("methods", toJsonMethods(type.getMethods())); object.add("missingTypeNames", toJsonMissingTypeNames(type.getMissingTypeNames())); object.add("name", type.getName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getName()))); object.add("sourceName", type.getSourceName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getSourceName()))); object.add("superclassName", type.getSuperclassName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getSuperclassName()))); object.add("tagBits", new JsonPrimitive(String.valueOf(type.getTagBits()))); object.add("anonymous", new JsonPrimitive(type.isAnonymous())); object.add("local", new JsonPrimitive(type.isLocal())); object.add("member", new JsonPrimitive(type.isMember())); object.add("sourceFileName", type.sourceFileName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.sourceFileName()))); object.add("modifiers", new JsonPrimitive(type.getModifiers())); object.add("binaryType", new JsonPrimitive(type.isBinaryType())); object.add("fileName", type.getFileName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getFileName()))); return gson.toJson(object); } private static JsonElement toJsonMethods(IBinaryMethod[] methods) { if (methods == null) return JsonNull.INSTANCE; JsonArray jsonElements = new JsonArray(); for (IBinaryMethod method : methods) { jsonElements.add(toJsonMethod(method)); } return jsonElements; } private static JsonElement toJsonMethod(IBinaryMethod method) { JsonObject object = new JsonObject(); object.addProperty("modifiers", method.getModifiers()); object.addProperty("constructor", method.isConstructor()); object.add("argumentNames", toJsonArrayString(method.getArgumentNames())); object.add("annotations", toJsonAnnotations(method.getAnnotations())); object.add("defaultValue", toJsonDefaultValue(method.getDefaultValue())); object.add("exceptionTypeNames", toJsonArrayString(method.getExceptionTypeNames())); object.add("genericSignature", method.getGenericSignature() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(method.getGenericSignature()))); object.add("methodDescriptor", method.getMethodDescriptor() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(method.getMethodDescriptor()))); object.add("parameterAnnotations", toJsonParameterAnnotations(method)); object.add("selector", method.getSelector() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(method.getSelector()))); object.addProperty("tagBits", String.valueOf(method.getTagBits())); object.addProperty("clinit", method.isClinit()); return object; } private static JsonElement toJsonParameterAnnotations(IBinaryMethod method) { if (method.getAnnotatedParametersCount() != 0) { JsonArray array = new JsonArray(); int parameterCount = Signature.getParameterCount(method.getMethodDescriptor()); for (int i = 0; i < parameterCount; i++) { array.add(toJsonAnnotations(method.getParameterAnnotations(i))); } return array; } else return JsonNull.INSTANCE; } private static JsonElement toJsonFields(IBinaryField[] fields) { if (fields == null) return JsonNull.INSTANCE; JsonArray array = new JsonArray(); for (IBinaryField field : fields) { array.add(toJsonField(field)); } return array; } private static JsonElement toJsonField(IBinaryField field) { JsonObject object = new JsonObject(); object.addProperty("modifiers", field.getModifiers()); object.add("constant", toJsonConstant(field.getConstant())); object.add("genericSignature", field.getGenericSignature() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(field.getGenericSignature()))); object.add("name", field.getName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(field.getName()))); object.addProperty("tagBits", String.valueOf(field.getTagBits())); object.add("typeName", field.getTypeName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(field.getTypeName()))); object.add("annotations", toJsonAnnotations(field.getAnnotations())); return object; } public static JsonElement toJsonConstant(Constant constant) { if (constant == null) return JsonNull.INSTANCE; JsonObject con = new JsonObject(); con.addProperty("typeId", constant.typeID()); JsonElement val; switch (constant.typeID()) { case T_int: val = new JsonPrimitive(constant.intValue()); break; case T_byte: val = new JsonPrimitive(constant.byteValue()); break; case T_short: val = new JsonPrimitive(constant.shortValue()); break; case T_char: val = new JsonPrimitive(constant.charValue()); break; case T_float: val = new JsonPrimitive(String.valueOf(constant.floatValue())); break; case T_double: if (Constant.NotAConstant.equals(constant)) { val = new JsonPrimitive("NaN"); con.addProperty("NotAConstant", 1); } else { val = new JsonPrimitive(constant.stringValue()); } break; case T_boolean: val = new JsonPrimitive(constant.booleanValue()); break; case T_long: val = new JsonPrimitive(String.valueOf(constant.longValue())); break; case T_JavaLangString: val = new JsonPrimitive(constant.stringValue()); break; default: val = JsonNull.INSTANCE; } con.add("value", val); return con; } private static JsonElement toJsonAnnotations(IBinaryAnnotation[] annotations) { if (annotations == null) return JsonNull.INSTANCE; JsonArray array = new JsonArray(); for (IBinaryAnnotation annotation : annotations) { array.add(toJsonAnnotation(annotation)); } return array; } private static JsonElement toJsonAnnotation(IBinaryAnnotation annotation) { JsonObject object = new JsonObject(); object.add("typeName", annotation.getTypeName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(annotation.getTypeName()))); object.add("elementValuePairs", toJsonElementValuePairs(annotation.getElementValuePairs())); return object; } private static JsonElement toJsonElementValuePairs(IBinaryElementValuePair[] elementValuePairs) { if (elementValuePairs == null) return JsonNull.INSTANCE; JsonArray array = new JsonArray(); for (IBinaryElementValuePair pair : elementValuePairs) { array.add(toJsonElementValuePair(pair)); } return array; } private static JsonElement toJsonElementValuePair(IBinaryElementValuePair pair) { JsonObject object = new JsonObject(); object.add("name", pair.getName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(pair.getName()))); object.add("value", toJsonDefaultValue(pair.getValue())); return object; } private static JsonElement toJsonDefaultValue(Object defaultValue) { if (defaultValue == null) return JsonNull.INSTANCE; JsonObject object = new JsonObject(); if (defaultValue instanceof Constant) { object.add("constant", toJsonConstant((Constant)defaultValue)); } else if (defaultValue instanceof ClassSignature) { object.addProperty("class", new String(((ClassSignature)defaultValue).getTypeName())); } else if (defaultValue instanceof IBinaryAnnotation) { object.add("annotation", toJsonAnnotation((IBinaryAnnotation)defaultValue)); } else if (defaultValue instanceof EnumConstantSignature) { EnumConstantSignature signature = (EnumConstantSignature)defaultValue; JsonObject enumSignature = new JsonObject(); enumSignature.addProperty("typeName", new String(signature.getTypeName())); enumSignature.addProperty("constantName", new String(signature.getEnumConstantName())); object.add("enum", enumSignature); } else if (defaultValue instanceof Object[]) { JsonArray array = new JsonArray(); for (Object o : (Object[])defaultValue) { array.add(toJsonDefaultValue(o)); } object.add("array", array); } return object; } private static JsonElement toJsonMemberTypes(IBinaryNestedType[] memberTypes) { if (memberTypes == null) return JsonNull.INSTANCE; JsonArray array = new JsonArray(); for (IBinaryNestedType type : memberTypes) { array.add(toJsonMemberType(type)); } return array; } private static JsonElement toJsonMemberType(IBinaryNestedType type) { JsonObject object = new JsonObject(); object.add("enclosingTypeName", type.getEnclosingTypeName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getEnclosingTypeName()))); object.addProperty("modifiers", type.getModifiers()); object.add("name", type.getName() == null ? JsonNull.INSTANCE : new JsonPrimitive(new String(type.getName()))); return object; } private static JsonElement toJsonMissingTypeNames(char[][][] missingTypeNames) { if (missingTypeNames == null) return JsonNull.INSTANCE; JsonArray array = new JsonArray(); for (char[][] typeName : missingTypeNames) { array.add(toJsonArrayString(typeName)); } return array; } public static JsonElement toJsonArrayString(char[][] chars) { if (chars == null) return JsonNull.INSTANCE; JsonArray array = new JsonArray(); for (char[] aChar : chars) { array.add(new JsonPrimitive(new String(aChar))); } return array; } }