/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.query.algebra;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* An extension operator that can be used to add bindings to solutions whose
* values are defined by {@link ValueExpr value expressions}.
*/
public class Extension extends UnaryTupleOperator {
/*-----------*
* Variables *
*-----------*/
private List<ExtensionElem> elements = new ArrayList<ExtensionElem>();
/*--------------*
* Constructors *
*--------------*/
public Extension() {
}
public Extension(TupleExpr arg) {
super(arg);
}
public Extension(TupleExpr arg, ExtensionElem... elements) {
this(arg);
addElements(elements);
}
public Extension(TupleExpr arg, Iterable<ExtensionElem> elements) {
this(arg);
addElements(elements);
}
/*---------*
* Methods *
*---------*/
public List<ExtensionElem> getElements() {
return elements;
}
public void setElements(Iterable<ExtensionElem> elements) {
this.elements.clear();
addElements(elements);
}
public void addElements(ExtensionElem... elements) {
for (ExtensionElem pe : elements) {
addElement(pe);
}
}
public void addElements(Iterable<ExtensionElem> elements) {
for (ExtensionElem pe : elements) {
addElement(pe);
}
}
public void addElement(ExtensionElem pe) {
elements.add(pe);
pe.setParentNode(this);
}
@Override
public Set<String> getBindingNames()
{
Set<String> bindingNames = new LinkedHashSet<String>(arg.getBindingNames());
for (ExtensionElem pe : elements) {
bindingNames.add(pe.getName());
}
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 (ExtensionElem elem : elements) {
elem.visit(visitor);
}
super.visitChildren(visitor);
}
@Override
public void replaceChildNode(QueryModelNode current, QueryModelNode replacement)
{
int index = elements.indexOf(current);
if (index >= 0) {
elements.set(index, (ExtensionElem)replacement);
replacement.setParentNode(this);
}
else {
super.replaceChildNode(current, replacement);
}
}
@Override
public Extension clone() {
Extension clone = (Extension)super.clone();
List<ExtensionElem> elementsClone = new ArrayList<ExtensionElem>(getElements().size());
for (ExtensionElem elem : getElements()) {
elementsClone.add(elem.clone());
}
clone.setElements(elementsClone);
return clone;
}
}