Package siena.sdb

Source Code of siena.sdb.SdbSienaIterable

package siena.sdb;

import java.lang.reflect.Field;
import java.util.Iterator;

import siena.ClassInfo;
import siena.Query;
import siena.Util;
import siena.core.options.QueryOptionFetchType;
import siena.core.options.QueryOptionOffset;
import siena.core.options.QueryOptionPage;
import siena.core.options.QueryOptionState;

import com.amazonaws.services.simpledb.model.Item;

/**
* @author mandubian <pascal.voitot@mandubian.org>
*
* A Siena Iterable<Model> encapsulating a GAE Iterable<Entity> with its Iterator<Model>...
*/
public class SdbSienaIterable<Model> implements Iterable<Model> {
  protected Iterable<Item> items;
  protected Query<Model> query;
  protected SdbPersistenceManager pm;

  SdbSienaIterable(SdbPersistenceManager pm, Iterable<Item> items, Query<Model> query) {
    this.pm = pm;
    this.items = items;
    this.query = query;
  }

  public Iterator<Model> iterator() {
    return new SdbSienaIterator<Model>(query, items);
  }

  public class SdbSienaIterator<T> implements Iterator<T> {
    Field id;
    Query<T> query;
    Iterator<Item> it;
    int idx = 0; //used to count when in pagination

    QueryOptionPage pag;
    QueryOptionSdbContext sdbCtx;
    QueryOptionState state;
    QueryOptionOffset off;

    SdbSienaIterator(Query<T> query, Iterable<Item> items) {
      this.query = query;
      this.id = ClassInfo.getIdField(query.getQueriedClass());
      this.it = items.iterator();
     
      // if paginating and 0 results then no more data else resets noMoreDataAfter
      pag = (QueryOptionPage)query.option(QueryOptionPage.ID);
      sdbCtx = (QueryOptionSdbContext)query.option(QueryOptionSdbContext.ID);
      state = (QueryOptionState)query.option(QueryOptionState.ID);

      // if has offset, advances in the iterator
      off = (QueryOptionOffset)query.option(QueryOptionOffset.ID);
      if(off!=null && off.offset != 0){
        for(int i=0; i<off.offset; i++){
          if(it.hasNext()){
            it.next();
          }
        }
       
        // moves real offset if not paginating
        //if(!pag.isPaginating())
        //  sdbCtx.realOffset += off.offset;
      }
     
      if(pag.isPaginating()){
        if(!it.hasNext()){
          sdbCtx.noMoreDataAfter = true;
        }else {
          sdbCtx.noMoreDataAfter = false;
        }
      }
     
    }

    public boolean hasNext() {
      boolean n = it.hasNext();
      if(!n){
        //pm.postMapping(query);
       
        int pageSize = sdbCtx.realPageSize-idx;
        if(!pag.isPaginating()){
          // not paginating = we get current token as the move has already been done
          // tries to fetch new items if has a live token
          String token = null;
          if(state.isStateful()){
            token = sdbCtx.currentToken();
         
            if(!pag.isActive()){
              pageSize = Integer.MAX_VALUE;
            }
          }
          else {
            token = sdbCtx.nextToken();     
            if(pag.isActive()){
              pag.passivate();
              pag.pageSize = 0;
            }else {
              pageSize = Integer.MAX_VALUE;
            }
            if(off.isActive()){
              off.passivate();
              off.offset = 0;
            }
          }
         
          if(token != null && pageSize > 0){
            SdbSienaIterable<Model> iter =
              (SdbSienaIterable<Model>)pm.doFetchIterable(query, pageSize, 0, true);
            items = iter.items;
            it = items.iterator();
            idx = 0;
            return it.hasNext();
          }else if(token == null){
            sdbCtx.noMoreDataAfter = true;
          }
        }else {
          // paginating = if has next token & not already at the last element of the page
          // moves to next token (but not before verifying it has next token)
          boolean b = sdbCtx.hasNextToken();
          if(b && pageSize > 0){
            sdbCtx.nextToken();
            SdbSienaIterable<Model> iter =
              (SdbSienaIterable<Model>)pm.doFetchIterable(query, pageSize, 0, true);
            items = iter.items;
            it = items.iterator();
            idx = 0;
           
            return it.hasNext();
          }else if(!b){
            sdbCtx.noMoreDataAfter = true;
          }
        }
       
        return false;
      }
      return true;
    }

    public T next() {
      Item item = it.next();
      idx++;
     
      // moves realoffset if not paginating
      //if(!pag.isPaginating()){
      //  sdbCtx.realOffset++;
      //}
     
     
      Class<T> clazz = query.getQueriedClass();
      QueryOptionFetchType fetchType = (QueryOptionFetchType)query.option(QueryOptionFetchType.ID);

      T obj = Util.createObjectInstance(clazz);
     
      switch(fetchType.fetchType){
      case KEYS_ONLY:
        SdbMappingUtils.fillModelKeysOnly(item, clazz, ClassInfo.getClassInfo(clazz), obj);
      case NORMAL:
      default:
        SdbMappingUtils.fillModel(item, clazz, ClassInfo.getClassInfo(clazz), obj);
       
        // join management
        if(!query.getJoins().isEmpty()
            || !ClassInfo.getClassInfo(query.getQueriedClass()).joinFields.isEmpty())
          pm.mapJoins(query, obj);
      }     
      return obj;
    }

    public void remove() {
      it.remove();
    }

  }

}
TOP

Related Classes of siena.sdb.SdbSienaIterable

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.