Package org.openrdf.result.impl

Source Code of org.openrdf.result.impl.MutableTupleResult

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2007.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.result.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

import org.openrdf.query.BindingSet;
import org.openrdf.result.MultipleResultException;
import org.openrdf.result.NoResultException;
import org.openrdf.result.Result;
import org.openrdf.result.TupleResult;
import org.openrdf.store.StoreException;

/**
* An implementation of the {@link TupleResult} interface that stores the
* complete query result in memory. The query results in a
* MutableTupleQueryResult can be iterated over multiple times and can also be
* iterated over in reverse order.
*
* @author Arjohn Kampman
*/
public class MutableTupleResult implements TupleResult, Cloneable {

  /*-----------*
   * Variables *
   *-----------*/

  private Set<String> bindingNames = new LinkedHashSet<String>();

  private List<BindingSet> bindingSets = new LinkedList<BindingSet>();

  /**
   * The index of the next element that will be returned by a call to
   * {@link #next()}.
   */
  private int currentIndex = 0;

  /**
   * The index of the last element that was returned by a call to
   * {@link #next()} or {@link #previous()}. Equal to -1 if there is no such
   * element.
   */
  private int lastReturned = -1;

  /*--------------*
   * Constructors *
   *--------------*/

  public <E extends Exception> MutableTupleResult(Collection<String> bindingNames, BindingSet... bindingSets)
  {
    this(bindingNames, Arrays.asList(bindingSets));
  }

  /**
   * Creates a query result table with the supplied binding names.
   * <em>The supplied list of binding names is assumed to be constant</em>;
   * care should be taken that the contents of this list doesn't change after
   * supplying it to this solution.
   *
   * @param bindingNames
   *        The binding names, in order of projection.
   */
  public MutableTupleResult(Collection<String> bindingNames, Collection<? extends BindingSet> bindingSets) {
    this.bindingNames.addAll(bindingNames);
    this.bindingSets.addAll(bindingSets);
  }

  public MutableTupleResult(Collection<String> bindingNames, Result<? extends BindingSet> bindingSetIter)
    throws StoreException
  {
    this.bindingNames.addAll(bindingNames);
    bindingSetIter.addTo(this.bindingSets);
  }

  public MutableTupleResult(TupleResult tqr)
    throws StoreException
  {
    this(tqr.getBindingNames(), tqr);
  }

  /*---------*
   * Methods *
   *---------*/

  public List<String> getBindingNames() {
    return new ArrayList<String>(bindingNames);
  }

  public int size() {
    return bindingSets.size();
  }

  public BindingSet get(int index) {
    return bindingSets.get(index);
  }

  public int getIndex() {
    return currentIndex;
  }

  public void setIndex(int index) {
    if (index < 0 || index > bindingSets.size() + 1) {
      throw new IllegalArgumentException("Index out of range: " + index);
    }

    this.currentIndex = index;
  }

  public boolean hasNext() {
    return currentIndex < bindingSets.size();
  }

  public BindingSet next() {
    if (hasNext()) {
      BindingSet result = get(currentIndex);
      lastReturned = currentIndex;
      currentIndex++;
      return result;
    }

    throw new NoSuchElementException();
  }

  public boolean hasPrevious() {
    return currentIndex > 0;
  }

  public BindingSet previous() {
    if (hasPrevious()) {
      BindingSet result = bindingSets.get(currentIndex - 1);
      currentIndex--;
      lastReturned = currentIndex;
      return result;
    }

    throw new NoSuchElementException();
  }

  /**
   * Moves the cursor to the start of the query result, just before the first
   * binding set. After calling this method, the result can be iterated over
   * from scratch.
   */
  public void beforeFirst() {
    currentIndex = 0;
  }

  /**
   * Moves the cursor to the end of the query result, just after the last
   * binding set.
   */
  public void afterLast() {
    currentIndex = bindingSets.size() + 1;
  }

  /**
   * Inserts the specified binding set into the list. The binding set is
   * inserted immediately before the next element that would be returned by
   * {@link #next()}, if any, and after the next element that would be returned
   * by {@link #previous}, if any. (If the table contains no binding sets, the
   * new element becomes the sole element on the table.) The new element is
   * inserted before the implicit cursor: a subsequent call to <tt>next()</tt>
   * would be unaffected, and a subsequent call to <tt>previous()</tt> would
   * return the new binding set.
   *
   * @param bindingSet
   *        The binding set to insert.
   */
  public void insert(BindingSet bindingSet) {
    insert(currentIndex, bindingSet);
  }

  public void insert(int index, BindingSet bindingSet) {
    bindingSets.add(index, bindingSet);

    if (currentIndex > index) {
      currentIndex++;
    }

    lastReturned = -1;
  }

  public void append(BindingSet bindingSet) {
    bindingSets.add(bindingSet);
    lastReturned = -1;
  }

  public void set(BindingSet bindingSet) {
    if (lastReturned == -1) {
      throw new IllegalStateException();
    }

    set(lastReturned, bindingSet);
  }

  public BindingSet set(int index, BindingSet bindingSet) {
    return bindingSets.set(index, bindingSet);
  }

  public void remove() {
    if (lastReturned == -1) {
      throw new IllegalStateException();
    }

    remove(lastReturned);

    if (currentIndex > lastReturned) {
      currentIndex--;
    }

    lastReturned = -1;
  }

  public BindingSet remove(int index) {
    BindingSet result = bindingSets.remove(index);

    if (currentIndex > index) {
      currentIndex--;
    }

    lastReturned = -1;

    return result;
  }

  public BindingSet singleResult()
    throws StoreException
  {
    if (bindingSets.isEmpty()) {
      throw new NoResultException("expected zero, but was:" + bindingSets.size());
    }
    if (bindingSets.size() > 1) {
      throw new MultipleResultException("expected zero, but was:" + bindingSets.size());
    }
    return this.bindingSets.get(0);
  }

  public <C extends Collection<? super BindingSet>> C addTo(C bindingSets)
    throws StoreException
  {
    bindingSets.addAll(this.bindingSets);
    return bindingSets;
  }

  public List<BindingSet> asList()
    throws StoreException
  {
    return this.bindingSets;
  }

  public Set<BindingSet> asSet()
    throws StoreException
  {
    return new LinkedHashSet<BindingSet>(this.bindingSets);
  }

  public void clear() {
    bindingNames.clear();
    bindingSets.clear();
    currentIndex = 0;
    lastReturned = -1;
  }

  public void close() {
    // no-opp
  }

  @Override
  public MutableTupleResult clone()
    throws CloneNotSupportedException
  {
    MutableTupleResult clone = (MutableTupleResult)super.clone();
    clone.bindingNames = new LinkedHashSet<String>(bindingNames);
    clone.bindingSets = new LinkedList<BindingSet>(bindingSets);
    return clone;
  }
}
TOP

Related Classes of org.openrdf.result.impl.MutableTupleResult

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.