/* * 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.tools.database.queries.metadata.jpql; import com.megatim.fdxcommons.model.enumeration.Operateur; import com.megatim.fdxcommons.model.search.EnumValue; import com.megatim.fdxcommons.tools.database.exceptions.BadQueryCriteriaException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.sql.Timestamp; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author ASUS */ public class JpqlParsedQueryCriterion { private final JpqlQueryCriterion queryCriterion; private final Class classe; public JpqlParsedQueryCriterion(JpqlQueryCriterion queryCriterion, Class classe) { this.queryCriterion = queryCriterion; this.classe = classe; } public JpqlQueryCriterion parsedCriterion() throws Exception { return queryCriterion != null ? parsedCriterion(queryCriterion) : null; } private JpqlQueryCriterion parsedCriterion(JpqlQueryCriterion criterion) throws Exception { if (criterion.getSubCriteria() != null && !criterion.getSubCriteria().isEmpty() && criterion.getCriteriaLogicConnector() != null) { List subCriteria = new ArrayList<>(); for (JpqlQueryCriterion qc : criterion.getSubCriteria()) { JpqlQueryCriterion parsedCriterion = parsedCriterion(qc); if (parsedCriterion != null) { subCriteria.add(parsedCriterion); } } if (!subCriteria.isEmpty()) { return new JpqlQueryCriterion(null, null, null, criterion.getCriteriaLogicConnector(), subCriteria, criterion.isEndOfTheDay() ); } } else if ((criterion.getSubCriteria() == null || criterion.getSubCriteria().isEmpty()) && criterion.getNomColonne() != null && !criterion.getNomColonne().isEmpty() && criterion.getOperateur() != null) { Class clazz = columnType(criterion.getNomColonne()); if (clazz != null) { Object correctValue = correctValue(clazz, criterion); if (isUnaryOperator(criterion.getOperateur()) || (correctValue != null && !correctValue.toString().isEmpty())) { return new JpqlQueryCriterion(criterion.getNomColonne(), correctValue, criterion.getOperateur(), null, Arrays.asList(), criterion.isEndOfTheDay() ); } } } return null; } private Class columnType(String nomColonne) { Field[] fields = classe.getDeclaredFields(); String[] fieldPath = nomColonne.split("\\."); try { return columnType(fieldPath, fields); } catch (BadQueryCriteriaException ex) { Logger.getLogger(JpqlParsedQueryCriterion.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); return null; } } private Class columnType(String[] fieldPath, Field[] fields) throws BadQueryCriteriaException { Optional optField = Arrays.asList(fields).stream().filter(f -> f.getName().equals(fieldPath[0])).findFirst(); if (optField.isPresent()) { if (fieldPath.length == 1) { return optField.get().getType(); } else { return columnType(Arrays.copyOfRange(fieldPath, 1, fieldPath.length), optField.get().getType().getDeclaredFields()); } } else { throw new BadQueryCriteriaException("Colonne " + fields[0] + " introuvable dans la classe " + optField.get().getDeclaringClass().getName()); } } private Object correctValue(Class clazz, JpqlQueryCriterion criterion) throws IllegalAccessException, BadQueryCriteriaException, IllegalArgumentException, InvocationTargetException { Object criteriaValue = criterion.getCriteriaValue(); if (criteriaValue == null) { return null; } if (clazz.isEnum()) { Method[] methods = clazz.getMethods(); Optional optionalMethod = Arrays.asList(methods) .stream() .filter(m -> m.getAnnotation(EnumValue.class) != null && Modifier.isStatic(m.getModifiers())).findFirst(); if (optionalMethod.isPresent()) { Method method = optionalMethod.get(); return method.invoke(null, criteriaValue.toString()); } return criteriaValue; } else if (clazz.isAssignableFrom(LocalDateTime.class)) { return dateTimeValue(criteriaValue.toString(), criterion.isEndOfTheDay()); } else { return clazz.cast(criteriaValue); } } private Object dateTimeValue(String criteriaValue, boolean endOfTheDay) { ZonedDateTime zonedDateTime = ZonedDateTime.parse(criteriaValue, DateTimeFormatter.ISO_DATE_TIME); LocalDateTime date = Timestamp.from(zonedDateTime.toInstant()).toLocalDateTime(); return endOfTheDay ? date.toLocalDate().atTime(LocalTime.MAX) : date.toLocalDate().atTime(LocalTime.MIN); } private boolean isUnaryOperator(Operateur operateur) { return operateur.equals(Operateur.IS_NOT_NULL) || operateur.equals(Operateur.IS_NULL); } }