/* * This file is part of the HyperGraphDB source distribution. This is copyrighted * software. For permitted uses, licensing options and redistribution, please see * the LicensingInformation file at the root level of the distribution. * * Copyright (c) 2005-2010 Kobrix Software, Inc. All rights reserved. */ package org.hypergraphdb.query.impl; import java.util.NoSuchElementException; import org.hypergraphdb.HGHandle; import org.hypergraphdb.HGSearchResult; import org.hypergraphdb.HyperGraph; import org.hypergraphdb.type.HGTypedValue; import org.hypergraphdb.type.TypeUtils; public class ProjectionAtomResultSet implements HGSearchResult { private HyperGraph graph; private HGSearchResult searchResult; private HGHandle baseType = null; private String [] dimensionPath; private Object current = null; // // The number of elements preceeding the current in the underlying // searchResult that satisfy the predicate. // private int prevCount = 0; // // The diff in the underlying result b/w the location of our 'current' member // variable and its own "current" element. // private int lookahead = 0; private Object examine(HGHandle h) { HGHandle ot = baseType == null ? graph.getTypeSystem().getTypeHandle(h) : baseType; HGTypedValue tv = TypeUtils.project(graph, ot, graph.get(h), dimensionPath, false); return tv != null ? graph.getHandle(tv.getValue()) : null; } /** * <p> * The constructor assumes the underlying set is already positioned to the * first matching entity. * </p> * * @param graph The * @param searchResult * @param predicate */ public ProjectionAtomResultSet(HyperGraph graph, HGSearchResult searchResult, String [] dimensionPath, HGHandle baseType) { this.graph = graph; this.searchResult = searchResult; this.dimensionPath = dimensionPath; this.baseType = baseType; } public void close() { searchResult.close(); } public Object current() { return current; } public boolean hasPrev() { return prevCount > 0; } public Object prev() { if (prevCount == 0) throw new NoSuchElementException(); while (lookahead > 0) { lookahead--; searchResult.prev(); } prevCount--; while (searchResult.hasPrev() && examine((HGHandle)searchResult.prev()) == null); return current = examine((HGHandle)searchResult.current()); } public boolean hasNext() { if (lookahead > 0) return examine((HGHandle)searchResult.current()) != null; while (true) { if (!searchResult.hasNext()) return false; lookahead++; if (examine((HGHandle)searchResult.next()) == null) continue; else return true; } } public Object next() { if (!hasNext()) throw new NoSuchElementException(); else { prevCount++; lookahead = 0; return current = examine((HGHandle)searchResult.current()); } } public void remove() { throw new UnsupportedOperationException(); } public boolean isOrdered() { return searchResult.isOrdered(); } }