package com.bagri.xqj; import static com.bagri.xqj.BagriXQErrors.ex_sequence_closed; import java.util.List; import javax.xml.xquery.XQException; import javax.xml.xquery.XQItem; import javax.xml.xquery.XQSequence; import com.bagri.core.xquery.api.XQProcessor; import com.bagri.support.util.XQUtils; public class ScrollableXQSequence extends BagriXQSequence implements XQSequence { private List<?> sequence; private int position; ScrollableXQSequence(BagriXQDataFactory xqFactory, XQProcessor xqProcessor, List<?> sequence) { super(xqFactory, xqProcessor); this.sequence = sequence; position = 0; } private void setCurrent() throws XQException { // TODO: construct XQItemType properly..? if (position > 0 && position <= sequence.size()) { Object current = sequence.get(position - 1); if (current instanceof XQItem) { XQItem item = (XQItem) current; setCurrent(item.getItemType(), item.getObject()); } else { setCurrent(XQUtils.getTypeForObject(xqFactory, current), current); } } else { setCurrent(null, null); } } @Override public boolean absolute(int itempos) throws XQException { checkState(ex_sequence_closed); if (sequence.size() > 0) { if (itempos >= 0) { position = itempos; } else { position = sequence.size() + itempos + 1; } if (position < 0) { position = 0; } else if (position > sequence.size() + 1) { position = sequence.size() + 1; } setCurrent(); return position > 0 && position <= sequence.size(); } return false; } @Override public void afterLast() throws XQException { checkState(ex_sequence_closed); position = sequence.size() + 1; setCurrent(); } @Override public void beforeFirst() throws XQException { checkState(ex_sequence_closed); position = 0; setCurrent(); } @Override public void close() throws XQException { super.close(); // can be already cleared via cursor! if (sequence != null) { sequence.clear(); } sequence = null; } @Override public int count() throws XQException { checkState(ex_sequence_closed); return sequence.size(); } @Override public int getPosition() throws XQException { checkState(ex_sequence_closed); return position; } @Override public boolean isOnItem() throws XQException { checkState(ex_sequence_closed); return position > 0 && position <= sequence.size(); } @Override public boolean isScrollable() throws XQException { checkState(ex_sequence_closed); return true; } @Override public boolean first() throws XQException { checkState(ex_sequence_closed); if (sequence.size() > 0) { position = 1; setCurrent(); return true; } return false; } @Override public boolean isAfterLast() throws XQException { checkState(ex_sequence_closed); return position > sequence.size(); } @Override public boolean isBeforeFirst() throws XQException { checkState(ex_sequence_closed); return position == 0 && sequence.size() > 0; } @Override public boolean isFirst() throws XQException { checkState(ex_sequence_closed); return position == 1; } @Override public boolean isLast() throws XQException { checkState(ex_sequence_closed); return position == sequence.size(); } @Override public boolean last() throws XQException { checkState(ex_sequence_closed); if (sequence.size() > 0) { position = sequence.size(); setCurrent(); return true; } return false; } @Override public boolean next() throws XQException { checkState(ex_sequence_closed); position++; if (position <= sequence.size() && sequence.size() > 0) { setCurrent(); return true; } return false; } @Override public boolean previous() throws XQException { checkState(ex_sequence_closed); position--; if (position > 0 && sequence.size() > 0) { setCurrent(); return true; } return false; } @Override public boolean relative(int itempos) throws XQException { checkState(ex_sequence_closed); if (sequence.size() > 0) { position += itempos; if (position < 0) { position = 0; } else if (position > sequence.size() + 1) { position = sequence.size() + 1; } setCurrent(); return position > 0 && position <= sequence.size(); } return false; } }