All Downloads are FREE. Search and download functionalities are using the official Maven repository.

br.eti.clairton.repository.http.QueryParser Maven / Gradle / Ivy

package br.eti.clairton.repository.http;

import static br.eti.clairton.repository.Comparators.EQUAL;
import static br.eti.clairton.repository.Comparators.LIKE;
import static br.eti.clairton.repository.Order.Direction.ASC;
import static br.eti.clairton.repository.Order.Direction.byString;
import static br.eti.clairton.repository.http.Param.DIRECTION;
import static br.eti.clairton.repository.http.Param.PAGE;
import static br.eti.clairton.repository.http.Param.PER_PAGE;
import static br.eti.clairton.repository.http.Param.SORT;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Stream.concat;
import static org.apache.logging.log4j.LogManager.getLogger;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.Type;

import org.apache.logging.log4j.Logger;

import br.eti.clairton.repository.http.AttributeBuilder;
import br.eti.clairton.repository.Comparator;
import br.eti.clairton.repository.Order;
import br.eti.clairton.repository.Order.Direction;
import br.eti.clairton.repository.Predicate;

@Dependent
public class QueryParser {
	private static final Logger logger = getLogger(QueryParser.class);

	private final List query = asList(SORT, PAGE, PER_PAGE, DIRECTION);

	private final AttributeBuilder builder;

	@Deprecated
	protected QueryParser() {
		this(null);
	}

	@Inject
	public QueryParser(final AttributeBuilder builder) {
		super();
		this.builder = builder;
	}

	public Collection parse(final Map params, final Class modelType) {
		final Collection predicates = new ArrayList();
		final String ids = idsKey(modelType);
		final String id = idKey(modelType);
		if (params.containsKey(ids)) {
			final String[] values;
			if(params.containsKey(id)){
				values = concat(stream(params.get(id)), stream(params.get(ids))).toArray(String[]::new);
			}else{				
				values = params.get(ids);
			}
			params.put(id, values);
			params.remove(ids);
		}
		final Set keys = params.keySet();
		for (final String field : keys) {
			if (query.contains(field) || "format".equals(field)) {
				continue;
			}
			final Collection predicate;
			final Attribute[] attrs = builder.with(modelType, field);
			if (attrs.length == 1 && attrs[0] == null) {
				logger.warn("Attribute {}#{} not found", modelType, field);
				continue;
			}
			final String[] values = params.get(field);
			predicate = to(attrs, values);
			predicates.addAll(predicate);
		}
		return predicates;
	}

	public List order(final Map params, final Class modelType) {
		final List orders = new ArrayList();
		if (params == null) {
			return orders;
		}
		final String[] sort;
		final String[] orderBy;
		if (params.containsKey(DIRECTION)) {
			sort = params.get(DIRECTION);
		} else {
			sort = new String[] { "asc" };
		}
		if (params.containsKey(SORT)) {
			orderBy = params.get(SORT);
		} else {
			orderBy = new String[] {idKey(modelType)};
		}
		for (int i = 0, j = orderBy.length; i < j; i++) {
			final String field = orderBy[i];
			final Attribute[] attrs = builder.with(modelType, field);
			Direction type;
			try {
				type = byString(sort[i]);
			} catch (final ArrayIndexOutOfBoundsException e) {
				type = ASC;
			}
			final Order order = new Order(type, attrs);
			orders.add(order);
		}
		return orders;
	}

	public Page paginate(final Map params, final Class modelType) {
		if (params == null) {
			return new Page(0, 0);
		}
		final Integer page;
		final Integer perPage;
		if (params.containsKey(PAGE)) {
			page = Integer.valueOf(params.get(PAGE)[0]);
		} else {
			page = 0;
		}
		if (params.containsKey(PER_PAGE)) {
			perPage = Integer.valueOf(params.get(PER_PAGE)[0]);
		} else {
			perPage = 0;
		}
		return new Page(page, perPage);
	}

	protected Record to(final String value) {
		return Record.valueOf(value);
	}

	protected Record to(final String[] values) {
		return Record.valueOf(values);
	}

	protected  Predicate to(final Attribute[] attrs, final String value) {
		final Record record = to(value);
		final Attribute attr = attrs[attrs.length - 1];
		final Class javaType;
		if(attr.isCollection()){
			final PluralAttribute pa = (PluralAttribute) attr;
			final Type type = pa.getElementType();
			javaType = type.getJavaType();			
		} else {
			javaType = attr.getJavaType();
		}
		final Object object;
		if(javaType.isEnum()){
			object = parseEnum(record.value, javaType);
		} else if(javaType.isAssignableFrom(Boolean.class)){
			object = parseBoolean(record.value);			
		} else if(javaType.isAssignableFrom(LocalDate.class)){
			object = parseLocalDate(record.value);			
		} else {
			object = record.value.toString();			
		}
		final Comparator comparator = record.comparator;
		final Predicate predicate = new Predicate(object, comparator, attrs);
		return predicate;
	}

	protected  Collection to(final Attribute[] attrs, final String[] value) {
		if (value.length > 1) {
			final List predicates = new ArrayList<>();
			for (final String s : value) {
				final Predicate predicate = to(attrs, s);
				predicates.add(predicate);
			}
			// verificar se todas as comparações são iguais, significa que deve
			// ser um like
			if (predicates.stream().filter(p -> p.getComparator().equals(EQUAL)).count() == Long.valueOf(predicates.size())) {
				final Attribute[] attributes = predicates.get(0).getAttributes();
				final List values = predicates.stream().map(p -> p.getValue()).collect(toList());
				final Comparator comparator = LIKE;
				final Predicate predicate = new Predicate(values, comparator, attributes);
				return asList(predicate);
			}
			return predicates;
		} else {
			final Predicate predicate = to(attrs, value[0]);
			return asList(predicate);
		}
	}
	
	protected String idsKey(final Class modelType){
		return "ids[]";
	}
	
	protected String idKey(final Class modelType){
		return "id";
	}
	
	protected Boolean parseBoolean(final Object object){
		return Boolean.valueOf(object.toString());
	}
	
	protected LocalDate parseLocalDate(final Object object){
		final String[] values = object.toString().split(dateSeparator());
		return LocalDate.of(Integer.valueOf(values[0]), Integer.valueOf(values[1]), Integer.valueOf(values[2]));
	}
	
	protected String dateFormat(){
		return "yyyy-mm-dd";
	}
	
	protected String dateSeparator(){
		return "-";
	}
	
	protected Enum parseEnum(final Object object, @SuppressWarnings("rawtypes") final Class type){
		@SuppressWarnings("unchecked")
		final Object e = Enum.valueOf(type, object.toString());
		return (Enum) e;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy