package org.amc.dao.parsers;

import org.amc.model.WorkEntity;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

public abstract class AbstractWFSearchToQuery implements WebFormSearchToQuery {
    
    private CriteriaBuilder cb;
    
    public AbstractWFSearchToQuery(EntityManager entityManager) {
        cb = entityManager.getCriteriaBuilder();
    }
    
    CriteriaBuilder getCriteriaBuilder() {
        return cb;
    }
    
    static class QueryBuilder {
        private Root<? extends WorkEntity> root;
        private List<Predicate> predicates;
        private CriteriaBuilder cb;
        
        public QueryBuilder(CriteriaBuilder cb, Root<? extends WorkEntity> root) {
            this.cb = cb;
            this.root = root;
            predicates = new ArrayList<Predicate>();
        }
        
        public void likeStringField(String value, String... fields) {
            if(value != null) {
                predicates.add(cb.like(getExprStr(root, fields), value));
            }
        }
        
        public void equalStringField(String value, String... fields) {
            if(value != null) {
                predicates.add(cb.equal(getExprStr(root, fields), value));
            }
        }
        
        public void equalField(Object value, Class<?> clazz, String... fields) {
            if(value != null) {
                predicates.add(cb.equal(getExpr(root, clazz, fields), value));
            }
        }
        
        public void betweenDates(Date startDate, Date endDate, String... fields) {
            predicates.add(cb.between(getExprDate(root, fields), startDate, endDate));
            
        }
        
        public List<Predicate> getPredicateList() {
            return this.predicates;
        }
        
        public Predicate[] getArrayOfPredicates() {
            return predicates.toArray(new Predicate[predicates.size()]);
        }
        
        Expression<String> getExprStr(Root<? extends WorkEntity> process, String... fields) {
            return getPath(process, fields).as(String.class);
        }
        
        Expression<Date> getExprDate(Root<? extends WorkEntity> process, String... fields) {
            return getPath(process, fields).as(Date.class);
        }
        
        Expression<?> getExpr(Root<? extends WorkEntity> process, Class<?> clazz, String... fields) {
            return getPath(process, fields).as(clazz);
        }
        
        Path<Object> getPath(Root<? extends WorkEntity> process, String... fields) {
            Path<Object> path = null;
            for(String field : fields) {
                if(path == null) {
                    path = process.get(field);
                } else {
                    path = path.get(field);
                }
            }
            return path;
        }
    }
}

@@ -393,16 +393,62 @@
 ia.Root;
+%0Aimport javax.persistence.metamodel.Metamodel;
 %0A%0Apublic
@@ -758,24 +758,171 @@
 %0A    %7D%0A    %0A
+    /**%0A     * A Builder that helps to create a Criteria Query without a %7B@link Metamodel%7D%0A     * %0A     * @author Adrian Mclaughlin%0A     *%0A     */%0A
     static c
@@ -1282,32 +1282,230 @@
      %7D%0A        %0A
+        /**%0A         * Create a JPA like expression and adds it a List%0A         * @param value String value to use%0A         * @param fields String array relating to JPA model field name%0A         */%0A
         public v
@@ -1689,32 +1689,239 @@
      %7D%0A        %0A
+        /**%0A         * Create a JPA equal expression and adds it a %7B@link List%7D%0A         * @param value String value to use%0A         * @param fields String array relating to JPA model field name%0A         */%0A
         public v
@@ -2127,224 +2127,760 @@
     
-public void equalField(Object value, Class%3C?%3E clazz, String... fields) %7B%0A            if(value != null) %7B%0A                predicates.add(cb.equal(getExpr(root, clazz, fields), value));%0A            %7D%0A        %7D%0A        
+/**%0A         * Create a JPA equal expression and adds it a %7B@link List%7D%0A         * @param value Object value to use%0A         * @param clazz Class type to cast the expression to%0A         * @param fields String array relating to JPA model field name%0A         */%0A        public void equalField(Object value, Class%3C?%3E clazz, String... fields) %7B%0A            if(value != null) %7B%0A                predicates.add(cb.equal(getExpr(root, clazz, fields), value));%0A            %7D%0A        %7D%0A        %0A        /**%0A         * Create a JPA between expression for Dates and adds it a %7B@link List%7D%0A         * %0A         * @param startDate Date lower bound%0A         * @param endDate Date upper bound%0A         * @param fields String array JPA model date field name%0A         */
 %0A   
@@ -3177,32 +3177,132 @@
      %7D%0A        %0A
+        /**%0A         * gets an array of Predicates%0A         * @return a Predicate array%0A         */%0A
         public P

add comments to AbstractWFSearchToQuery#QueryBuilder