package org.ebayopensource.turmeric.tools.codegen.fastserformat.protobuf.eproto; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import org.ebayopensource.turmeric.tools.codegen.builders.BaseCodeGenerator; import org.ebayopensource.turmeric.tools.codegen.exception.CodeGenFailedException; import org.ebayopensource.turmeric.tools.codegen.util.ContextClassLoaderUtil; public abstract class BaseEProtoGenerator extends BaseCodeGenerator{ /** * Populates the initial context based on the information obatined from the Proto Model generated * in the previous step. This is the carrier of data across theEProto generation * @throws CodeGenFailedException */ public EProtoContext getPojoInfo( String fullyQualifiedEProtoName, String complexTypeName, String fullyQualifiedJProtoName, String fullyQualifiedName) throws CodeGenFailedException{ EProtoContext info = new EProtoContext(); info.setFullyQualifiedName(fullyQualifiedName); info.setFullyQualifiedEProtoName(fullyQualifiedEProtoName); info.setComplexTypeName(complexTypeName); info.setBuilderClass(getBuilderClassName(complexTypeName, fullyQualifiedJProtoName)); info.setFullyQualifiedJProtoMessageName(fullyQualifiedJProtoName); Class<?> baseClass = ContextClassLoaderUtil.loadOptionalClass(fullyQualifiedName); getFields(baseClass, info); getMethods(baseClass, info); Class<?> superClass = baseClass.getSuperclass(); while(superClass != null && superClass.getName() != "java.lang.Object"){ getFields(superClass, info); getMethods(superClass, info); superClass = superClass.getSuperclass(); } return info; } /** * Gets all the Fields(java.lang.reflect.Field) defined in the base POJO class */ protected void getFields(Class<?> fullyQualifiedClass, EProtoContext info){ Field[] fields = fullyQualifiedClass.getDeclaredFields(); info.getDeclaredFields().addAll(Arrays.asList(fields)); } /** * Gets all the methods(java.lang.reflect.Method) defined in the base POJO class. And also helps in maintaining * a map of getters to fields (useful in making use of Google's FieldDesciptors APIs. */ protected void getMethods(Class<?> fullyQualifiedClass, EProtoContext info){ Method[] methods = fullyQualifiedClass.getDeclaredMethods(); for (Method singleMethod : methods) { String methodName = singleMethod.getName().toLowerCase(); // HACK just let MarketPlace extension types (xs:any) to go through(just ignore) and workaround // for field names using JAVA keywords for(Field fieldName : info.getDeclaredFields()){ String actualFieldName = fieldName.getName().toLowerCase(); if(actualFieldName.startsWith("_")) actualFieldName = actualFieldName.replace("_", ""); if(singleMethod != null && singleMethod.getParameterTypes().length == 0 && (singleMethod.getName().equalsIgnoreCase("get" + actualFieldName) || singleMethod.getName().equalsIgnoreCase("is" + actualFieldName)) && !("getAny".equals(singleMethod.getName()))){ info.getGetterToFields().put(singleMethod.getName(), fieldName.getName()); info.getMethods().add(singleMethod); break; } } } } protected static String getBuilderClassName(String complexTypename, String fullyQualifiedJProtoName){ StringBuilder builder = new StringBuilder( fullyQualifiedJProtoName); // StringBuilder builder = new StringBuilder(getJProtoMessageName(complexTypename, fullyQualifiedJProtoName)); builder.append("$Builder"); return builder.toString(); } /** * Mapping class to maintain mapping between a message and its corresponding names in * different technologies. This includes * 1) Fully Qualified EProto Class Name * 2) Complex Type name(message name) * 3) Fully Qualified JProto Class Name * 4) Fully Qualified POJO Class Name */ static class JAXB2EJProtoMapping{ String eprotoName; String complexTypeName; String jprotoName; String jaxbName; boolean isRootType; public String getJaxbName() { return jaxbName; } public void setJaxbName(String jaxbName) { this.jaxbName = jaxbName; } public String getComplexTypeName() { return complexTypeName; } public void setComplexTypeName(String complexTypeName) { this.complexTypeName = complexTypeName; } public String getJprotoName() { return jprotoName; } public void setJprotoName(String jprotoName) { this.jprotoName = jprotoName; } public String getEprotoName() { return eprotoName; } public void setEprotoName(String eprotoName) { this.eprotoName = eprotoName; } public boolean isRootType() { return isRootType; } public void setRootType(boolean isRootType) { this.isRootType = isRootType; } @Override public String toString() { return "JAXB2EJProtoMapping [complexTypeName=" + complexTypeName + ", eprotoName=" + eprotoName + ", isRootType=" + isRootType + ", jaxbName=" + jaxbName + ", jprotoName=" + jprotoName + "]"; } } }