FrontendMetadataGenerator.java
package eu.javaexperience.webgsdb.commons;
import hu.ddsi.java.database.FieldData;
import hu.ddsi.java.database.GenericStorageMappingData;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import eu.javaexperience.arrays.ArrayTools;
import eu.javaexperience.collection.CollectionTools;
import eu.javaexperience.gsdbrpc.RemoteGsdbTools;
import eu.javaexperience.gsdbrpc.WebDbModel;
import eu.javaexperience.gsdbrpc.WebGsdbTools;
import eu.javaexperience.gsdbrpc.annotations.CustomFieldManager;
import eu.javaexperience.gsdbrpc.annotations.RpcAttribute;
import eu.javaexperience.gsdbrpc.annotations.RpcAttributes;
import eu.javaexperience.gsdbrpc.annotations.InputType;
import eu.javaexperience.gsdbrpc.annotations.MayNotSee;
import eu.javaexperience.reflect.FieldSelectTools;
import eu.javaexperience.reflect.Mirror;
import eu.javaexperience.reflect.PrimitiveTools;
import eu.javaexperience.reflect.Mirror.ClassData;
import eu.javaexperience.rpc.JavaClassRpcCollector;
import eu.javaexperience.rpc.RpcFacility;
import eu.javaexperience.semantic.references.MayNotModified;
import eu.javaexperience.text.StringTools;
public abstract class FrontendMetadataGenerator
{
protected Appendable out;
protected Class<? extends WebDbModel>[] models;
public FrontendMetadataGenerator(Appendable out, Class<? extends WebDbModel>... models)
{
this.out = out;
this.models = models;
}
protected abstract String examineTranslationName(Field f);
protected void appendReflectionMetaData(Appendable sb, Class cls) throws IOException
{
ClassData cd = Mirror.getClassData(cls);
sb.append("\t\tWebGsdbTools.putFieldAttributes");
sb.append("\n\t\t(");
sb.append("\n\t\t\t"+cls.getCanonicalName()+".class,");
int i=0;
Map<String,Field> lastField = new HashMap<>();
for(Field f:cd.select(FieldSelectTools.SELECT_ALL_INSTANCE_FIELD))
{
lastField.put(f.getName(), f);
}
for(Entry<String,Field>kv:lastField.entrySet())
{
Field f = kv.getValue();
if(!Modifier.isPublic(f.getModifiers()))
{
continue;
}
if(++i > 1)
{
sb.append(",");
}
sb.append("\n\t\t\t");
sb.append("\"").append(f.getName()).append("\", new FieldExtraAttributes(");
sb.append(examineTranslationName(f));
sb.append(")");
if(null != f.getAnnotation(MayNotModified.class))
{
sb.append(".userCantModify()");
}
{
InputType it = f.getAnnotation(InputType.class);
if(null != it)
{
sb.append(".inputType(\"");
sb.append(it.type());
sb.append("\")");
}
}
{
MayNotSee it = f.getAnnotation(MayNotSee.class);
if(null != it)
{
sb.append(".userMayNotSee()");
}
}
{
String add = renderCallAddExtraAddributes(f);
if(null != add)
{
sb.append(add);
}
}
}
sb.append("\n\t\t);\n");
}
protected void appendModelFieldUrchin(Appendable sb, Class cls) throws InstantiationException, IllegalAccessException, IOException
{
String type = cls.getCanonicalName();
sb.append("\t\tif(TeaVmTools.isUrchin())\n\t\t{\n\t\t\t");
sb.append(type);
sb.append(" m = new ");
sb.append(type);
sb.append("();\n\t\t");
FieldData[] fds = GenericStorageMappingData.getOrCollectAllClassData(cls).allFd;
for(FieldData fd:fds)
{
if(!RemoteGsdbTools.isWebgsdbUseField(fd.f))
{
continue;
}
sb.append("\tm.");
sb.append(fd.f.getName());
sb.append(" = ");
Class<?> c = fd.f.getType();
c = PrimitiveTools.toObjectClassType(c, c);
if(c == Boolean.class)
{
sb.append("true");
}
else if(c == Byte.class)
{
sb.append("(byte) 1");
}
else if(c == Character.class)
{
sb.append("'c'");
}
else if(c == Short.class)
{
sb.append("(short) 1");
}
else if(c == Integer.class)
{
sb.append("1");
}
else if(c == Long.class)
{
sb.append("1l");
}
else if(c == Float.class)
{
sb.append("1.0f");
}
else if(c == Double.class)
{
sb.append("1.0d");
}
else
{
sb.append("null");
}
sb.append(";\n\t\t");
}
sb.append("}\n");
}
public void exportReflection() throws Throwable
{
//StringBuilder sb = new StringBuilder();
out.append("import eu.jvx.js.lib.TeaVmTools;\nimport eu.javaexperience.webgsdb.WebGsdbTools;\nimport eu.javaexperience.webgsdb.commons.FieldExtraAttributes;\n\n\n");
out.append("public class TeaVmMetadata\n{\n\tprotected static boolean init = false;\n\n\tpublic static void initTeaVmMetadata()\n\t{\n");
out.append("\t\tif(init){return;} init = true;\n");
for(Class<? extends WebDbModel> cls:models)
{
if(!cls.isInterface() && !Modifier.isAbstract(cls.getModifiers()))
{
appendReflectionMetaData(out, cls);
out.append("\n");
appendModelFieldUrchin(out, cls);
out.append("\n\n");
}
}
out.append("\n\t}");
out.append("\n}");
}
protected String renderCallAddExtraAddributes(Field f)
{
StringBuilder sb = new StringBuilder();
CustomFieldManager cfm = f.getAnnotation(CustomFieldManager.class);
if(null != cfm)
{
Class<? extends FrontendFieldManager<? extends WebDbModel>> cls = cfm.managerClass();
if(null != cls)
{
sb.append(".customFieldManager(");
sb.append(cls.getCanonicalName());
sb.append(".class)");
}
}
{
RpcAttribute fe = f.getAnnotation(RpcAttribute.class);
if(null != fe)
{
appendAttribute(sb, fe);
}
}
RpcAttributes fes = f.getAnnotation(RpcAttributes.class);
if(null != fes)
{
for(RpcAttribute fe:fes.attributes())
{
if(null != fe)
{
appendAttribute(sb, fe);
}
}
}
if(0 == sb.length())
{
return null;
}
return sb.toString();
}
public static Class<? extends WebDbModel>[] getClasses(List<RpcFacility> apis)
{
return (Class[]) CollectionTools.convert(Class.class, apis, (e)->((JavaClassRpcCollector)e).getWrappedClass());
}
public static String wrapString(String s)
{
if(null == s)
{
return null;
}
return "\""+StringTools.escapeToJavaString(s)+"\"";
}
public static void appendAttribute(StringBuilder sb, RpcAttribute fa)
{
sb.append(".attr(");
sb.append(wrapString(fa.key()));
sb.append(", ");
sb.append(wrapString(fa.value()));
sb.append(")");
}
}