package com.cmeza.sdgenerator.support.maker; import com.cmeza.sdgenerator.support.maker.builder.ObjectBuilder; import com.cmeza.sdgenerator.support.maker.builder.ObjectStructure; import com.cmeza.sdgenerator.support.maker.values.ObjectTypeValues; import com.cmeza.sdgenerator.support.maker.values.ScopeValues; import com.cmeza.sdgenerator.util.*; import javax.persistence.EmbeddedId; import javax.persistence.Id; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Created by carlos on 08/04/17. */ public class RepositoryStructure { private CustomResourceLoader loader; private ObjectBuilder objectBuilder; private Integer error = 0; private final static Map<Class<?>, Class<?>> mapConvert = new HashMap<>(); static { mapConvert.put(boolean.class, Boolean.class); mapConvert.put(byte.class, Byte.class); mapConvert.put(short.class, Short.class); mapConvert.put(char.class, Character.class); mapConvert.put(int.class, Integer.class); mapConvert.put(long.class, Long.class); mapConvert.put(float.class, Float.class); mapConvert.put(double.class, Double.class); } public RepositoryStructure(String repositoryPackage, String entityName, String entityClass, String postfix, CustomResourceLoader loader, Set<String> additionalExtends) { this.loader = loader; String repositoryName = entityName + postfix; Tuple<String, Boolean> entityId = getEntityId(entityClass); if(entityId != null) { ObjectStructure objectStructure = new ObjectStructure(repositoryPackage, ScopeValues.PUBLIC, ObjectTypeValues.INTERFACE, repositoryName) .addImport(entityClass) .addImport("org.springframework.data.jpa.repository.JpaRepository") .addImport("org.springframework.data.jpa.repository.JpaSpecificationExecutor") .addImport("org.springframework.stereotype.Repository") .addImport(entityId.right() ? entityId.left() : "") .addAnnotation("Repository") .addExtend("JpaRepository", entityName, GeneratorUtils.getSimpleClassName(entityId.left())) .addExtend("JpaSpecificationExecutor", entityName); if (additionalExtends != null) { for(String additionalExtend : additionalExtends) { objectStructure.addImport(additionalExtend); objectStructure.addExtend(GeneratorUtils.getSimpleClassName(additionalExtend), entityName); } } this.objectBuilder = new ObjectBuilder(objectStructure); } } @SuppressWarnings("unchecked") private Tuple<String, Boolean> getEntityId(String entityClass){ try { Class<?> entity; if (loader == null) { entity = Class.forName(entityClass); } else { entity = loader.getUrlClassLoader().loadClass(entityClass); } while (entity != null){ for (Field field : entity.getDeclaredFields()) { if (field.isAnnotationPresent(Id.class) || field.isAnnotationPresent(EmbeddedId.class)) { Class<?> dataType = field.getType(); if (field.getType().isPrimitive()) { dataType = this.primitiveToObject(field.getType()); } return new Tuple<>(dataType.getName(), this.isCustomType(dataType)); } } for (Method method : entity.getDeclaredMethods()) { if (!method.getReturnType().equals(Void.TYPE) && (method.isAnnotationPresent(Id.class) || method.isAnnotationPresent(EmbeddedId.class))) { Class<?> dataType = method.getReturnType(); if (method.getReturnType().isPrimitive()) { dataType = this.primitiveToObject(method.getReturnType()); } return new Tuple<>(dataType.getName(), this.isCustomType(dataType)); } } entity = entity.getSuperclass(); } error = SDLogger.addError("Repository Error: Primary key not found in " + GeneratorUtils.getSimpleClassName(entityClass) + ".java"); return null; } catch (GeneratorException ex) { error = SDLogger.addError(ex.getMessage()); return null; } catch (Exception e) { error = SDLogger.addError("Repository Error: Failed to access entity " + GeneratorUtils.getSimpleClassName(entityClass) + ".java"); return null; } } public Tuple<String, Integer> build(){ return new Tuple<>(objectBuilder == null ? null : objectBuilder.build(), error); } private boolean isCustomType(Class<?> clazz) { return !clazz.isAssignableFrom(Boolean.class) && !clazz.isAssignableFrom(Byte.class) && !clazz.isAssignableFrom(String.class) && !clazz.isAssignableFrom(Integer.class) && !clazz.isAssignableFrom(Long.class) && !clazz.isAssignableFrom(Float.class) && !clazz.isAssignableFrom(Double.class); } private Class<?> primitiveToObject(Class<?> clazz) { Class<?> convertResult = mapConvert.get(clazz); if (convertResult == null) { throw new GeneratorException("Type parameter '" + clazz.getName() + "' is incorrect"); } return convertResult; } }