/*
* Copyright 2008 Fedora Commons, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mulgara.resolver.prefix;
// Java 2 standard packages
import java.util.*;
// Third party packages
import org.apache.log4j.Logger; // Apache Log4J
// Locally written packages
import org.mulgara.query.*;
import org.mulgara.resolver.spi.*;
import org.mulgara.store.tuples.Annotation;
import org.mulgara.store.tuples.RowComparator;
import org.mulgara.store.tuples.Tuples;
/**
* A {@link Resolution} which wraps a Tuples object.
*
* @created 2004-10-28
* @author <a href="mailto:pgearon@users.sourceforge.net">Paula Gearon</a>
* @copyright © 2005 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
*/
class TuplesWrapperResolution implements Resolution {
/** Logger. */
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(TuplesWrapperResolution.class.getName());
/** The constraint. */
private final Constraint constraint;
/** The wrapped tuples. */
private Tuples tuples;
//
// Constructor
//
/**
* Construct a {@link TuplesWrapperResolution}.
*
* @param tuples the tuples to wrap
* @param constraint the constraint, never <code>null</code>
* @throws IllegalArgumentException if <var>constraint<var> is
* <code>null</code>
*/
TuplesWrapperResolution(Tuples tuples, Constraint constraint)
{
// Validate "constraint" parameter
if (constraint == null) {
throw new IllegalArgumentException("Null \"constraint\" parameter");
}
// Initialize fields
this.constraint = constraint;
this.tuples = tuples;
}
//
// Methods implementing Resolution
//
public Constraint getConstraint()
{
return constraint;
}
/**
* @return This is always <code>true</code>.
*/
public boolean isComplete()
{
return true;
}
/**
* Converts this class into a formatted string
*
* @return A string representation of the tuples that this wraps
*/
public String toString() {
return tuples.toString();
}
/**
* Tests for equality.
*
* @param o Object to test against.
* @return <code>true</code> if this obj is equal to this object.
*/
public boolean equals(Object o) {
if (!(o instanceof TuplesWrapperResolution)) return false;
TuplesWrapperResolution t = (TuplesWrapperResolution)o;
return constraint.equals(t.constraint) && tuples.equals(t.tuples);
}
/**
* Added to match {@link #equals(Object)}.
*/
public int hashCode() {
return constraint.hashCode() ^ tuples.hashCode();
}
/**
* Clone the tuples and constraint, and re-wrap them in a new object.
*/
public Object clone() {
try {
TuplesWrapperResolution copy = (TuplesWrapperResolution)super.clone();
copy.tuples = (Tuples)tuples.clone();
return copy;
} catch (CloneNotSupportedException ec) {
throw new IncompatibleClassChangeError("CloneNotSupportedException thrown on Resolution");
}
}
/**
* The variables bound and their default collation order. The array returned
* by this method should be treated as if its contents were immutable, even
* though Java won't enforce this. If the elements of the array are modified,
* there may be side effects on the past and future clones of the tuples it
* was obtained from.
*
* @return The Variables value
*/
public Variable[] getVariables() {
return tuples.getVariables();
}
/**
* This method returns an upper bound on the number of rows which this
* instance contains, or an exact value if the instance
* {@link #isMaterialized}.
*
* @return The RowCount value
* @throws TuplesException EXCEPTION TO DO
*/
public long getRowCount() throws TuplesException {
return tuples.getRowCount();
}
/**
* This method returns cardinality of the number of rows which this instance contains.
*
* @return The cardinality of this tuples. {0,1,N} rows.
* @throws TuplesException EXCEPTION TO DO
*/
public int getRowCardinality() throws TuplesException {
return tuples.getRowCardinality();
}
/* (non-Javadoc)
* @see org.mulgara.query.Cursor#isEmpty()
*/
public boolean isEmpty() throws TuplesException {
return tuples.isEmpty();
}
/**
* Accessor for the binding of a given variable within the current product
* term (row).
*
* @param variable the variable binding to query
* @return the bound value, or {@link Tuples#UNBOUND} if there is no binding
* within the current product term (row)
* @throws TuplesException if there is no current row (before first or after
* last) or if <var>variable</var> isn't an element of {@link
* #getVariables}
*/
public int getColumnIndex(Variable variable) throws TuplesException {
return tuples.getColumnIndex(variable);
}
/**
* Whether a variable (column) is {@link Tuples#UNBOUND unbound} in any
* minterm (row) of this instance.
*
* @param column the variable to check
* @return whether the <var>column</var> is {@link Tuples#UNBOUND unbound} in
* any minterm (row) of this instance
* @throws TuplesException if <var>column</var> does not exist in this
* instance
*/
public boolean isColumnEverUnbound(int column) throws TuplesException {
return tuples.isColumnEverUnbound(column);
}
/**
* If a tuples is materialized, then:
* <ul>
* <li>the {@link #getRowCount} method returns an exact value rather than
* an upper bound</li>
* <li>element access is cached, rather than requiring recalculation</li>
* </ul>
*
* @return whether this instance actually exists in physical storage, rather
* than being calculated on demand
*/
public boolean isMaterialized() {
return tuples.isMaterialized();
}
/**
* An unconstrained tuples is a proposition which is always true.
*
* It is independent of variable bindings.
*
* @return whether this instance is equal to the unconstrained tuples
* @throws TuplesException if unconstrainedness couldn't be tested
*/
public boolean isUnconstrained() throws TuplesException {
return tuples.isUnconstrained();
}
/**
* Test for the absence of duplicate product terms (rows).
*
* If this is <var>false</var>, it is not guaranteed that the tuples has
* duplicate terms.
*
* @return <code>true</code> only if this instance has no duplicate terms
* @throws TuplesException if the presence of duplicate terms can't be tested
*/
public boolean hasNoDuplicates() throws TuplesException {
return tuples.hasNoDuplicates();
}
/**
* Obtain the sort ordering of this instance.
*
* @return a comparator specifying the collation order of this instance, or
* <code>null</code> if this tuples is unsorted
*/
public RowComparator getComparator() {
return tuples.getComparator();
}
/**
* Return the list of operands to this tuples.
*
* This is intended to allow debugging traversal of an unevaluated tuples hierachy.
* Be aware that the tuples returned from this method are not cloned, and should
* be considered immutable.
*/
public List<Tuples> getOperands() {
return tuples.getOperands();
}
/**
* Move the cursor to before the first row, optionally with a specifies list
* of leading column values.
*
* @param prefix only iterate through product terms with the specified leading
* column values ({@link #NO_PREFIX} should be passed if all prefix
* values are desired
* @param suffixTruncation the number of trailing rows to ignore when
* determining whether a row is distinct
* @throws IllegalArgumentException if <var>prefix</var> is <code>null</code>
* @throws TuplesException EXCEPTION TO DO
*/
public void beforeFirst(long[] prefix, int suffixTruncation) throws TuplesException {
tuples.beforeFirst(prefix, suffixTruncation);
}
/**
* Get the binding of a variable (column) in the currect product term (row)
*
* @param column the column number; columns are numbered starting from 0
* @return the value of the column, or {@link #UNBOUND}
* @throws TuplesException EXCEPTION TO DO
*/
public long getColumnValue(int column) throws TuplesException {
return tuples.getColumnValue(column);
}
/** {@inheritDoc} */
public long getRawColumnValue(int column) throws TuplesException {
return tuples.getColumnValue(column);
}
/**
* Renames the variables which label the tuples if they have the "magic" names
* such as "Subject", "Predicate", "Object" and "Meta".
*
* @param constraint PARAMETER TO DO
*/
public void renameVariables(Constraint constraint) {
tuples.renameVariables(constraint);
}
/**
* Move to the next row satisfying the current prefix and suffix truncation.
*
* If no such row exists, return <code>false<code> and the current row
* becomes unspecified. The current row is unspecified when a tuples instance
* is created. To specify the current row, the {@link #beforeFirst()} or
* {@link #beforeFirst(long[], int)} methods must be invoked
*
* @return whether a subsequent row with the specified prefix exists
* @throws IllegalStateException if the current row is unspecified.
* @throws TuplesException {@inheritDoc}
*/
public boolean next() throws TuplesException {
return tuples.next();
}
/**
* This method returns an upper bound on the number of rows which this instance contains.
*
* @return The upper bound of the number of rows that this instance contains.
* @throws TuplesException Error accessing the underlying data.
*/
public long getRowUpperBound() throws TuplesException {
return tuples.getRowUpperBound();
}
/**
* This method returns the expected count on the number of rows which this instance contains.
*
* @return The expected value of the number of rows that this instance contains.
* @throws TuplesException Error accessing the underlying data.
*/
public long getRowExpectedCount() throws TuplesException {
return tuples.getRowExpectedCount();
}
/**
* Returns the number of variables (columns).
*
* @return the number of variables (columns)
*/
public int getNumberOfVariables() {
return tuples.getNumberOfVariables();
}
/**
* Free resources associated with this instance.
*
* @throws TuplesException EXCEPTION TO DO
*/
public void close() throws TuplesException {
tuples.close();
}
/**
* Reset to iterate through every single element.
*
* @throws TuplesException EXCEPTION TO DO
*/
public void beforeFirst() throws TuplesException {
tuples.beforeFirst();
}
/**
* Copied from AbstractTuples
*/
public Annotation getAnnotation(Class<? extends Annotation> annotationClass) throws TuplesException {
return null;
}
}