/*
|
* 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.fdxcommons.dao.ifaces.utils;
|
|
import com.megatim.fdxcommons.model.enumeration.NumberOperator;
|
import com.megatim.fdxcommons.model.enumeration.SearchAnnotationOperateur;
|
import com.megatim.fdxcommons.model.search.Search;
|
import com.megatim.fdxcommons.model.search.SearchCriteria;
|
import java.beans.IntrospectionException;
|
import java.beans.PropertyDescriptor;
|
import java.lang.reflect.Field;
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
import javax.persistence.criteria.From;
|
import javax.persistence.criteria.Join;
|
import javax.persistence.criteria.Root;
|
|
/**
|
*
|
* @author ASUS
|
*/
|
public class SearchCriteriaBuilderUtil {
|
|
private SearchCriteriaBuilderUtil() {
|
}
|
|
public static <T, U> List<SearchCriteria> getSearchCriterias(U searchEntity, Class<T> entityClass, Root<?> root, List<SearchCriteria> externalSearchCriterias) {
|
Field[] entityFields = entityClass.getDeclaredFields();
|
List<SearchCriteria> searchCriterias = new ArrayList<>();
|
|
if (externalSearchCriterias != null) {
|
searchCriterias.addAll(externalSearchCriterias);
|
}
|
|
if (searchEntity == null) {
|
return searchCriterias;
|
}
|
|
Field[] searchEntityFields = searchEntity.getClass().getDeclaredFields();
|
for (Field searchEntityField : searchEntityFields) {
|
Search searchAnnotation = searchEntityField.getAnnotation(Search.class);
|
|
if (searchAnnotation != null && searchAnnotation.fieldName() != null && !searchAnnotation.fieldName().isEmpty()) {
|
String[] fieldPath = searchAnnotation.fieldName().split("\\.");
|
if (fieldPath.length == 1) {
|
if (isSearchFieldDescriptionCorrect(searchAnnotation.fieldName(), searchEntityField, entityFields)) {
|
searchCriterias.add(createSearchCriteria(searchAnnotation, searchAnnotation.fieldName(), searchEntityField, searchEntity, root));
|
}
|
} else if (fieldPath.length > 1) {
|
Join<Object, Object> join = null;
|
String fieldName = fieldPath[fieldPath.length - 1];
|
for (int i = 0; i < fieldPath.length - 1; i++) {
|
if (i == 0) {
|
join = root.join(fieldPath[i]);
|
} else {
|
if (join != null) {
|
join = join.join(fieldPath[i]);
|
}
|
}
|
}
|
if (isSearchHierarchicalFieldDescriptionCorrect(fieldPath, searchEntityField, entityFields)) {
|
searchCriterias.add(createSearchCriteria(searchAnnotation, fieldName, searchEntityField, searchEntity, join));
|
}
|
}
|
}
|
|
}
|
return searchCriterias;
|
}
|
|
private static SearchCriteria createSearchCriteria(Search searchAnnotation, String fieldName, Field searchEntityField, Object searchEntity, From<?, ?> from) {
|
SearchCriteria searchCriteria = new SearchCriteria();
|
searchCriteria.setFrom(from);
|
searchCriteria.setFieldName(fieldName);
|
searchCriteria.setOperateur(searchAnnotation.operateur());
|
searchCriteria.setFieldType(searchEntityField.getType());
|
Object fieldValue = getFieldValue(searchEntityField, searchEntity);
|
searchCriteria.setFieldValue(fieldValue);
|
|
if (searchAnnotation.operateur().equals(SearchAnnotationOperateur.NUMBER_OPERATOR)) {
|
try {
|
searchCriteria.setNumberOperator(getNumberOperatorFieldValue(searchAnnotation.operatorFieldName(), searchEntity));
|
} catch (IntrospectionException ex) {
|
}
|
}
|
return searchCriteria;
|
}
|
|
private static Object getFieldValue(Field field, Object searchEntity) {
|
Object value = null;
|
field.setAccessible(true);
|
try {
|
Method method = new PropertyDescriptor(field.getName(), searchEntity.getClass()).getReadMethod();
|
value = (Comparable<?>) method.invoke(searchEntity);
|
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException | java.beans.IntrospectionException ex) {
|
}
|
return value;
|
}
|
|
private static NumberOperator getNumberOperatorFieldValue(String operatorFieldName, Object searchEntity) throws java.beans.IntrospectionException {
|
NumberOperator numberOperator = NumberOperator.UNKNOW;
|
Field[] fields = searchEntity.getClass().getDeclaredFields();
|
for (Field field : fields) {
|
if (field.getName().equals(operatorFieldName)) {
|
field.setAccessible(true);
|
try {
|
Method method = new PropertyDescriptor(field.getName(), searchEntity.getClass()).getReadMethod();
|
Object value = method.invoke(searchEntity);
|
if (value instanceof NumberOperator) {
|
numberOperator = (NumberOperator) value;
|
}
|
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException ex) {
|
}
|
}
|
}
|
return numberOperator;
|
}
|
|
private static boolean isSearchHierarchicalFieldDescriptionCorrect(String[] fieldPath, Field searchEntityField, Field[] entityFields) {
|
String fieldName = fieldPath[0];
|
if (fieldPath.length == 1) {
|
return isSearchFieldDescriptionCorrect(fieldName, searchEntityField, entityFields);
|
} else {
|
|
Class<?> clazz = getFieldClass(fieldName, entityFields);
|
if (clazz != null) {
|
Field[] subFields = clazz.getDeclaredFields();
|
String[] subFieldPath = Arrays.copyOfRange(fieldPath, 1, fieldPath.length);
|
return isSearchHierarchicalFieldDescriptionCorrect(subFieldPath, searchEntityField, subFields);
|
} else {
|
return false;
|
}
|
}
|
|
}
|
|
private static Class<?> getFieldClass(String fieldName, Field[] entityFields) {
|
int index = getIndex(fieldName, entityFields);
|
return (index != -1) ? entityFields[index].getType() : null;
|
}
|
|
private static boolean isSearchFieldDescriptionCorrect(String fieldName, Field searchEntityField, Field[] entityFields) {
|
int index = getIndex(fieldName, entityFields);
|
return (index != -1) && isFieldTypeEquals(searchEntityField, entityFields[index]);
|
}
|
|
private static int getIndex(String fieldName, Field[] entityFields) {
|
int index = 0;
|
for (Field field : entityFields) {
|
if (fieldName.equals(field.getName())) {
|
return index;
|
}
|
index++;
|
}
|
return -1;
|
}
|
|
private static boolean isFieldTypeEquals(Field searchEntityField, Field entityField) {
|
return searchEntityField.getType().equals(entityField.getType());
|
}
|
}
|