Package siena

Source Code of siena.BaseQueryData

package siena;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import siena.core.QueryFilterEmbedded;
import siena.core.options.QueryOption;
import siena.core.options.QueryOptionFetchType;
import siena.core.options.QueryOptionOffset;
import siena.core.options.QueryOptionPage;
import siena.core.options.QueryOptionState;
import siena.embed.EmbeddedMap;

/**
* The base data container of Query<T>/QueryAsync<T> where T is the model being queried (not necessarily inheriting siena.Model)
*
* @author mandubian <pascal.voitot@mandubian.org>
*
* @param <T>
*/
@EmbeddedMap
public class BaseQueryData<T> implements QueryData<T> {
  private static final long serialVersionUID = -5112648712321740542L;

  protected Class<T> clazz;

  protected List<QueryFilter> filters;
  protected List<QueryOrder> orders;
  protected List<QueryFilterSearch> searches;
  protected List<QueryJoin> joins;
  protected List<QueryAggregated> aggregatees;
  protected List<QueryOwned> ownees;

  protected Map<Integer, QueryOption> options = defaultOptions();
 
  public static Map<Integer, QueryOption> defaultOptions() {
    return new HashMap<Integer, QueryOption>() {
      private static final long serialVersionUID = -7438657296637379900L;
      {
        put(QueryOptionPage.ID, new QueryOptionPage(0));
        put(QueryOptionOffset.ID, new QueryOptionOffset(0));
        put(QueryOptionState.ID, new QueryOptionState());
        //the fetch type is activated by default and set to NORMAL
        put(QueryOptionFetchType.ID, (new QueryOptionFetchType()).activate());
      }}
  }
 
  public BaseQueryData() {
    filters = new ArrayList<QueryFilter>();
    orders = new ArrayList<QueryOrder>();
    searches = new ArrayList<QueryFilterSearch>();
    joins = new ArrayList<QueryJoin>();
    aggregatees = new ArrayList<QueryAggregated>();
    ownees = new ArrayList<QueryOwned>();
  }
 
  public BaseQueryData(Class<T> clazz) {
    this.clazz = clazz;
   
    filters = new ArrayList<QueryFilter>();
    orders = new ArrayList<QueryOrder>();
    searches = new ArrayList<QueryFilterSearch>();
    joins = new ArrayList<QueryJoin>();
    aggregatees = new ArrayList<QueryAggregated>();
    ownees = new ArrayList<QueryOwned>();
  }
 
  public BaseQueryData(BaseQueryData<T> data) {
    this.clazz = data.clazz;   
   
    /* NO COPY TO KEEP DATA AND STATEFUL QUERIES
    this.filters = new ArrayList<QueryFilter>();
    this.orders = new ArrayList<QueryOrder>();
    this.searches = new ArrayList<QueryFilterSearch>();
    this.joins = new ArrayList<QueryJoin>();
   
    Collections.copy(this.filters, data.filters);
    Collections.copy(this.orders, data.orders);
    Collections.copy(this.searches, data.searches);
    Collections.copy(this.joins, data.joins);
   
    for(Integer key : data.options.keySet()){
      this.options.put(key, data.options.get(key).clone());
    }*/

    this.filters = data.filters;
    this.orders = data.orders;
    this.searches = data.searches;
    this.joins = data.joins;
    this.aggregatees = data.aggregatees;
    this.ownees = data.ownees;

    for(Integer key : data.options.keySet()){
      this.options.put(key, data.options.get(key));
    }
  }
 
  public Class<T> getQueriedClass(){
    return clazz;   
  }
 
  public List<QueryFilter> getFilters() {
    return filters;
  }

  public List<QueryOrder> getOrders() {
    return orders;
  }

  public List<QueryFilterSearch> getSearches() {
    return searches;
  }

  public List<QueryJoin> getJoins() {
    return joins;
  }

  public List<QueryAggregated> getAggregatees() {
    return aggregatees;
  }
 
  public List<QueryOwned> getOwnees() {
    return ownees;
  }

  public QueryOption option(int option) {
    return options.get(option);
  }
 
  public Map<Integer, QueryOption> options() {
    return options;
  }


/*
* PROTECTED FUNCTIONS AVAILABLE FOR BASEQUERY 
*/
  protected void addFilter(String fieldName, Object value, String[] supportedOperators) {
    String op = "=";
    for (String s : supportedOperators) {
      if(fieldName.endsWith(s)) {
        op = s;
        fieldName = fieldName.substring(0, fieldName.length() - op.length());;
        break;
      }
    }
    fieldName = fieldName.trim();
   
    // an embedded field can be a field containing "." or ":"
    if(fieldName.contains(".")){
      String[] parts = fieldName.split("\\.");
      if(parts.length == 0) {
        throw new SienaException("Filter field cannot have 0 fields to filter");
      }
     
      List<Field> fields = new ArrayList<Field>();
      Class<?> cl = clazz;
      for(int i=0; i<parts.length; i++) {
        String fName = parts[i];
        Field f = Util.getField(cl, fName);
        if(f==null) {
          throw new SienaException("Filter field '"+fName+"' not found");
        }
       
        fields.add(f);
        cl = f.getType();
      }
           
      filters.add(new QueryFilterEmbedded(fields, op, ".", value));
    }else if(fieldName.contains(":")) {
      String[] parts = fieldName.split("\\.");
      if(parts.length == 0) {
        throw new SienaException("Filter field cannot have 0 fields to filter");
      }
     
      List<Field> fields = new ArrayList<Field>();
      Class<?> cl = clazz;
      for(int i=0; i<parts.length; i++) {
        String fName = parts[i];
        Field f = Util.getField(cl, fName);
        if(f==null) {
          throw new SienaException("Filter field '"+fName+"' not found");
        }
       
        fields.add(f);
        cl = f.getType();
      }
           
      filters.add(new QueryFilterEmbedded(fields, op, ".", value));
    }else {
      Field field = Util.getField(clazz, fieldName);
      if(field==null) {
        throw new SienaException("Filter field '"+fieldName+"' not found");
      }
      filters.add(new QueryFilterSimple(field, op, value));
    }
  }
 
  protected void addOrder(String fieldName) {
    boolean ascending = true;
   
    if(fieldName.startsWith("-")) {
      fieldName = fieldName.substring(1);
      ascending = false;
    }
    Field field = Util.getField(clazz, fieldName);
    if(field==null) {
      throw new SienaException("Order field '"+fieldName+"' not found");
    }
    orders.add(new QueryOrder(field, ascending));
  }
 
  protected void addSearch(String match, String... fields) {
    QueryFilterSearch q = new QueryFilterSearch(match, fields);
    filters.add(q);
    searches.add(q);
  }
 
  protected void addSearch(String match, QueryOption opt, String... fields) {
    QueryFilterSearch q = new QueryFilterSearch(match, opt, fields);
    filters.add(q);
    searches.add(q);
  }
 
  protected void addJoin(String fieldName, String... sortFields) {
    try {
      Field field = Util.getField(clazz, fieldName);
      joins.add(new QueryJoin(field, sortFields));
      // add immediately orders to keep order of orders
      // sets joined field as parent field to manage order on the right joined table for ex
      for(String sortFieldName: sortFields){
        boolean ascending = true;
       
        if(sortFieldName.startsWith("-")) {
          sortFieldName = sortFieldName.substring(1);
          ascending = false;
        }
        try {
          Field sortField = field.getType().getField(sortFieldName);
          orders.add(new QueryOrder(sortField, ascending, field));
        } catch(NoSuchFieldException ex){
          throw new SienaException("Join not possible: join sort field "+sortFieldName+" is not a known field of "+fieldName, ex);
        }
      }
    } catch(Exception e) {
      throw new SienaException(e);
    }
  }
 
  protected void addAggregated(Object aggregator, String fieldName){
    Field field = Util.getField(aggregator.getClass(), fieldName);
    // removes existing aggregatee (not very nice I know :) )
    if(!aggregatees.isEmpty()) aggregatees.remove(0);
    aggregatees.add(0, new QueryAggregated(aggregator, field));
  }
 
  protected void addAggregated(Object aggregator, Field field){
    if(!aggregatees.isEmpty()) aggregatees.remove(0);
    aggregatees.add(0, new QueryAggregated(aggregator, field));
  }
 
  protected void addOwned(Object owner, String fieldName){
    Field field = Util.getField(this.getQueriedClass(), fieldName);
    // removes existing ownee (not very nice I know :) )
    if(!ownees.isEmpty()) ownees.remove(0);
    ownees.add(0, new QueryOwned(owner, field));
  }
 
  protected void addOwned(Object owner, Field field){
    // removes existing ownee (not very nice I know :) )
    if(!ownees.isEmpty()) ownees.remove(0);
    ownees.add(0, new QueryOwned(owner, field));
  }
 
  protected void optionPaginate(int pageSize) {
    // sets the pagination
    QueryOptionPage opt = (QueryOptionPage)(options.get(QueryOptionPage.ID));
    QueryOptionOffset offOpt = (QueryOptionOffset)options.get(QueryOptionOffset.ID);
    //QueryOptionState stateOpt = (QueryOptionState)(options.get(QueryOptionState.ID)).activate();
    // can't change pagination after it has been initialized because it breaks all the cursor mechanism
   
    /*if(opt.isActive() && opt.isPaginating()){
      throw new SienaException("Can't change pagination after it has been initialized...");
    }*/
   
    opt.activate();
    opt.pageSize=pageSize;
    opt.pageType = QueryOptionPage.PageType.PAGINATING;
   
    // resets offset to be sure nothing changes the pagination mechanism
    offOpt.offsetType = QueryOptionOffset.OffsetType.PAGINATING;
    //offOpt.offset = 0;
   
    /*if(stateOpt.isStateful()){
      offOpt.passivate();
    }else {
      offOpt.activate();
    }*/
  }
 
  protected void optionLimit(int limit) {
    // sets the pagination
    QueryOptionPage pagOpt = (QueryOptionPage)(options.get(QueryOptionPage.ID));
    //QueryOptionOffset offOpt = (QueryOptionOffset)options.get(QueryOptionOffset.ID);
    //QueryOptionState stateOpt = (QueryOptionState)(options.get(QueryOptionState.ID));
   
    pagOpt.activate();
    pagOpt.pageSize = limit;
    pagOpt.pageType = QueryOptionPage.PageType.MANUAL;
   
    // in stateless mode, we must reset the offset as we don't want it to be stateful
    //if(stateOpt.isStateless() && !offOpt.isManual()){
    //  offOpt.offset = 0;
    //}
  }
 
  protected void optionOffset(int offset) {
    QueryOptionPage pagOpt = (QueryOptionPage)(options.get(QueryOptionPage.ID));
    QueryOptionOffset offOpt = (QueryOptionOffset)options.get(QueryOptionOffset.ID);
    //QueryOptionState stateOpt = (QueryOptionState)(options.get(QueryOptionState.ID));
   
    offOpt.activate();
    offOpt.offsetType = QueryOptionOffset.OffsetType.MANUAL;
    offOpt.offset = offset;
   
    // deactivates the pagination in any case
    pagOpt.pageType = QueryOptionPage.PageType.MANUAL;
   
    //if(offset!=0){
      // if stateful mode, adds the offset to current offset
      //if(stateOpt.isStateful()){
      //  offOpt.offset += offset;
      //}
      // if stateless mode, simply replaces the offset
      //  else {
      //  offOpt.offset = offset;
        //if(!pagOpt.isManual()){
        //  pagOpt.pageSize = 0;
        //}
      //}
    //}
  }
 
  protected void optionStateful() {
    QueryOptionState opt = (QueryOptionState)(options.get(QueryOptionState.ID)).activate();
    opt.lifeCycle = QueryOptionState.LifeCycle.STATEFUL;
  }
 
  protected void optionStateless() {
    QueryOptionState opt = (QueryOptionState)(options.get(QueryOptionState.ID)).activate();
    opt.lifeCycle = QueryOptionState.LifeCycle.STATELESS;
  }
 
  protected void addOptions(QueryOption... options) {
    for(QueryOption option: options){
      this.options.put(option.type, option);
    }
  }

  protected void reset() {
    options.clear();
    filters.clear();
    orders.clear();
    searches.clear();
    joins.clear();
    aggregatees.clear();
    ownees.clear();
    options = defaultOptions();
  }
 
  public void resetOptions() {
    options = defaultOptions();
  }

}
TOP

Related Classes of siena.BaseQueryData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.