/* * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template */ package com.megatim.dynamicjsonparser.extender; import com.megatim.dynamicjsonparser.pojo.JsonField; import java.io.Serializable; import java.lang.reflect.Modifier; import java.time.LocalDate; import java.util.List; import org.burningwave.core.Virtual; import org.burningwave.core.assembler.ComponentContainer; import org.burningwave.core.assembler.ComponentSupplier; import org.burningwave.core.classes.AnnotationSourceGenerator; import org.burningwave.core.classes.ClassFactory; import org.burningwave.core.classes.ClassSourceGenerator; import org.burningwave.core.classes.FunctionSourceGenerator; import org.burningwave.core.classes.GenericSourceGenerator; import org.burningwave.core.classes.TypeDeclarationSourceGenerator; import org.burningwave.core.classes.UnitSourceGenerator; import org.burningwave.core.classes.VariableSourceGenerator; /** * * @author ASUS */ public class RuntimeClassBuilder { /** * Méthode qui crée dynamiquement une classe Java * @param packagename : nom du package de la classe * @param fields : liste des chmaps de la classe * @param classPathFolder : chemin où sera stocké la classe sur le disque * @return */ public static UnitSourceGenerator createRuntimeClass(final String packagename, List fields,String classPathFolder) { final String className = fields.get(0).getClassName(); //Ajout modificateur d'accès de la classe ClassSourceGenerator clazz = ClassSourceGenerator .create(TypeDeclarationSourceGenerator.create(className)) .addModifier(Modifier.PUBLIC); //Ajout des interfaces à implémenter clazz.addConcretizedType(Serializable.class) .addConcretizedType(Virtual.class); //Déclaration des champs de la classe fields.forEach(f -> { //Si le type du champ est encore à construire if (f.getDynamicFields() != null && !f.getDynamicFields().isEmpty()) { //Appel récursif afin de construire le sous-type UnitSourceGenerator subUnitSG = createRuntimeClass(packagename, f.getDynamicFields(),classPathFolder); ComponentSupplier componentSupplier = ComponentContainer.getInstance(); ClassFactory classFactory = componentSupplier.getClassFactory(); try ( ClassFactory.ClassRetriever classRetriever = classFactory.loadOrBuildAndDefine(subUnitSG)) { Class classOfField = classRetriever.get(packagename + "." + f.getDynamicFields().get(0).getClassName()); f.setClazz(classOfField); } } //Si le type du champ est connu if (f.getClazz() != null) { if (f.isCollection()) { clazz.addField(VariableSourceGenerator.create(TypeDeclarationSourceGenerator.create(List.class).addGeneric(GenericSourceGenerator.create(f.getClazz())), f.getName()) .addModifier(Modifier.PRIVATE)); } else { Class realClass = f.getClazz().equals(LocalDate.class) ? String.class : f.getClazz(); clazz.addField( VariableSourceGenerator.create(realClass, f.getName()) .addModifier(Modifier.PRIVATE) ); } } }); //Déclaration du constructeur sans argument clazz.addConstructor(FunctionSourceGenerator.create().addModifier(Modifier.PUBLIC).addBodyCodeLine()); fields.forEach(f -> { String fieldName = String.valueOf(f.getName().charAt(0)).toUpperCase() + f.getName().substring(1); if (f.getClazz() != null) { //Déclaration du getter de chaque attribut FunctionSourceGenerator getter = FunctionSourceGenerator.create("get" + fieldName) .addModifier(Modifier.PUBLIC) .addBodyCodeLine("return this." + f.getName() + ";"); Class realClass = f.getClazz().equals(LocalDate.class) ? String.class : f.getClazz(); if(f.isCollection()) { getter.setReturnType(TypeDeclarationSourceGenerator.create(List.class).addGeneric(GenericSourceGenerator.create(realClass))); } else { getter.setReturnType(realClass); } clazz.addMethod(getter); //Déclaration du setter de chaque attribut FunctionSourceGenerator setter = FunctionSourceGenerator.create("set" + fieldName) .addModifier(Modifier.PUBLIC) .setReturnType(void.class) .addBodyCodeLine("this." + f.getName() + " = " + f.getName() + ";"); if(f.isCollection()) { setter.addParameter(VariableSourceGenerator.create(TypeDeclarationSourceGenerator.create(List.class).addGeneric(GenericSourceGenerator.create(realClass)), f.getName())); } else { setter.addParameter(VariableSourceGenerator.create(realClass, f.getName())); } clazz.addMethod(setter); } }); //Définition de la valeur de retour de la méthode toString() StringBuilder toString = new StringBuilder(); for (JsonField f : fields) { toString.append("this.").append(f.getName()).append("+").append("\",\"").append("+"); } //Retirer les caractères +","+ toString.replace(toString.length() - 5, toString.length(), ""); //Déclaration de la méthode toString clazz.addMethod( FunctionSourceGenerator.create("toString") .addAnnotation(AnnotationSourceGenerator.create(Override.class)) .addModifier(Modifier.PUBLIC) .setReturnType(String.class) .addBodyCodeLine("return " + toString + ";") ); UnitSourceGenerator unitSG = UnitSourceGenerator.create(packagename).addClass(clazz); unitSG.make(); //Enregistre la classe sur le disque if(classPathFolder != null && !classPathFolder.isEmpty()) { unitSG.storeToClassPath(classPathFolder); } return unitSG; } }