package siena.gae; import java.util.ArrayList; import java.util.Collections; import java.util.List; import siena.core.options.QueryOption; import siena.embed.EmbeddedMap; import com.google.appengine.api.datastore.PreparedQuery; @EmbeddedMap public class QueryOptionGaeContext extends QueryOption{ public static final int ID = 0x2001; public List<String> cursors = new ArrayList<String>(); // -1 means empty public int cursorIdx = -1; public boolean useCursor = true; // this is the current offset synchronized with the cursor by the PM // a flag that can be used when there is no more data to fetch (when previous page is the first one for ex) public boolean noMoreDataBefore = false; public boolean noMoreDataAfter = false; public int realOffset = 0; public int realPageSize = 0; //public PreparedQuery query; public QueryOptionGaeContext() { super(ID); } public QueryOptionGaeContext(PreparedQuery query) { super(ID); //this.query = query; } public QueryOptionGaeContext(QueryOptionGaeContext option) { super(option); Collections.copy(this.cursors, option.cursors); this.cursorIdx = option.cursorIdx; this.useCursor = option.useCursor; this.noMoreDataBefore = option.noMoreDataBefore; this.noMoreDataAfter = option.noMoreDataAfter; this.realOffset = option.realOffset; this.realPageSize = option.realPageSize; //this.query = option.query; } public void addCursor(String cursor){ // if cursor in the middle of the list, replace next one if(cursorIdx < cursors.size()-1 && cursorIdx>=0){ cursors.set(cursorIdx+1, cursor); } // if first or last cursor in the list, adds a new cursor else{ cursors.add(cursorIdx+1, cursor); } } public void addAndMoveCursor(String cursor){ // if cursor in the middle of the list, replace next one if(cursorIdx < cursors.size()-1 && cursorIdx>=0){ cursors.set(++cursorIdx, cursor); } // if first or last cursor in the list, adds a new cursor else{ cursors.add(++cursorIdx, cursor); } } public void setCurrentCursor(String cursor){ // replaces the cursor at current index (useful for iterators) if(cursorIdx!=-1) cursors.set(cursorIdx, cursor); else { addAndMoveCursor(cursor); } } public String currentCursor() { if(cursorIdx!=-1){ return cursors.get(cursorIdx); }else { return null; } } public String nextCursor(){ int sz = cursors.size(); if(sz==0){ return null; }else { if(cursorIdx<sz-1){ return cursors.get(++cursorIdx); } else { return cursors.get(cursorIdx); } } } public boolean hasNextCursor(){ int sz = cursors.size(); if(sz==0){ return false; }else { return true; } } public String previousCursor(){ int sz = cursors.size(); if(sz==0){ return null; }else { if(cursorIdx>0){ return cursors.get(--cursorIdx); } else if(cursorIdx==0){ cursorIdx=-1; return null; } else { return null; } } } @Override public QueryOption clone() { return new QueryOptionGaeContext(this); } public String toString() { return "type:GAE_CONTEXT - state:"+this.state + " - realOffset:"+realOffset + " - realPageSize:"+realPageSize + " - useCursor:"+useCursor + " - cursorIdx:"+cursorIdx+ " - cursors:"+cursors; } }