/*******************************************************************************
 * Copyright (c) 2010 Robert "Unlogic" Olofsson (unlogic@unlogic.se).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v3
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-3.0-standalone.html
 ******************************************************************************/
package se.unlogic.standardutils.dao;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * This class represents a SQL query and is used together with a AnnotatedDAO typed with a matching type.<p>
 *
 * A high level abstracts away all and also verifies that the query parameters and order by criterias are of the correct type to avoid SQL exceptions.<p>
 *
 * @param <T> The type of bean this query is supposed to return
 *
 * @author Robert "Unlogic" Olofsson (unlogic@unlogic.se)
 */
public class HighLevelQuery<T> extends RelationQuery{

   private List<QueryParameter<T,?>> parameters;
   private List<OrderByCriteria<T>> orderByCriterias;

   public HighLevelQuery() {}

   public HighLevelQuery(final List<QueryParameter<T, ?>> parameters, final List<OrderByCriteria<T>> orderByCriterias) {

      super();
      this.parameters = parameters;
      this.orderByCriterias = orderByCriterias;
   }

   public HighLevelQuery(final Field... relations) {

      this.addRelations(relations);
   }

   public HighLevelQuery(final QueryParameter<T, ?> parameter, final Field... relations) {

      this.addParameter(parameter);
      this.addRelations(relations);
   }

   public HighLevelQuery(final QueryParameter<T, ?>... queryParameters) {

      this.addParameter(queryParameters);
   }

   public void setParameters(List<QueryParameter<T,?>> parameters) {

      this.parameters = parameters;
   }

   public synchronized void addParameter(QueryParameter<T,?> parameter){

      if(this.parameters == null){

         this.parameters = new ArrayList<QueryParameter<T,?>>();
      }

      this.parameters.add(parameter);
   }

   public synchronized void addParameter(QueryParameter<T,?>... parameters){

      if(this.parameters == null){

         this.parameters = new ArrayList<QueryParameter<T,?>>();
      }

      this.parameters.addAll(Arrays.asList(parameters));
   }


   public List<OrderByCriteria<T>> getOrderByCriterias() {

      return orderByCriterias;
   }


   public void setOrderByCriterias(List<OrderByCriteria<T>> orderByCriterias) {

      this.orderByCriterias = orderByCriterias;
   }


   public List<QueryParameter<T, ?>> getParameters() {

      return parameters;
   }

   public synchronized void addOrderByCriteria(OrderByCriteria<T> criteria){

      if(this.orderByCriterias == null){

         this.orderByCriterias = new ArrayList<OrderByCriteria<T>>();
      }

      this.orderByCriterias.add(criteria);
   }

   public synchronized void addOrderByCriteria(OrderByCriteria<T>... criterias){

      if(this.orderByCriterias == null){

         this.orderByCriterias = new ArrayList<OrderByCriteria<T>>();
      }

      this.orderByCriterias.addAll(Arrays.asList(criterias));
   }
}
