/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.query.algebra;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A "multi-projection" that can produce multiple solutions from a single set of
* bindings.
*/
public class MultiProjection extends UnaryTupleOperator {
/*-----------*
* Variables *
*-----------*/
/**
* The lists of projections.
*/
private List<ProjectionElemList> projections = new ArrayList<ProjectionElemList>();
/*--------------*
* Constructors *
*--------------*/
public MultiProjection() {
}
public MultiProjection(TupleExpr arg) {
super(arg);
}
public MultiProjection(TupleExpr arg, Iterable<ProjectionElemList> projections) {
this(arg);
addProjections(projections);
}
/*---------*
* Methods *
*---------*/
public List<ProjectionElemList> getProjections() {
return Collections.unmodifiableList(projections);
}
public void setProjections(Iterable<ProjectionElemList> projections) {
this.projections.clear();
addProjections(projections);
}
public void addProjections(Iterable<ProjectionElemList> projections) {
for (ProjectionElemList projection : projections) {
addProjection(projection);
}
}
public void addProjection(ProjectionElemList projection) {
assert projection != null : "projection must not be null";
projections.add(projection);
projection.setParentNode(this);
}
@Override
public Set<String> getBindingNames() {
Set<String> bindingNames = new HashSet<String>();
for (ProjectionElemList projElemList : projections) {
bindingNames.addAll(projElemList.getTargetNames());
}
return bindingNames;
}
public <X extends Exception> void visit(QueryModelVisitor<X> visitor)
throws X
{
visitor.meet(this);
}
@Override
public <X extends Exception> void visitChildren(QueryModelVisitor<X> visitor)
throws X
{
for (ProjectionElemList projElemList : projections) {
projElemList.visit(visitor);
}
super.visitChildren(visitor);
}
@Override
public void replaceChildNode(QueryModelNode current, QueryModelNode replacement)
{
int index = projections.indexOf(current);
if (index >= 0) {
projections.set(index, (ProjectionElemList)replacement);
replacement.setParentNode(this);
}
else {
super.replaceChildNode(current, replacement);
}
}
@Override
public MultiProjection clone() {
MultiProjection clone = (MultiProjection)super.clone();
List<ProjectionElemList> projectionsClone = new ArrayList<ProjectionElemList>(getProjections().size());
for (ProjectionElemList ge : getProjections()) {
projectionsClone.add(ge.clone());
}
clone.setProjections(projectionsClone);
return clone;
}
}