001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.query.algebra;
007:
008: import java.util.ArrayList;
009: import java.util.Collections;
010: import java.util.HashSet;
011: import java.util.List;
012: import java.util.Set;
013:
014: /**
015: * A "multi-projection" that can produce multiple solutions from a single set of
016: * bindings.
017: */
018: public class MultiProjection extends UnaryTupleOperator {
019:
020: /*-----------*
021: * Variables *
022: *-----------*/
023:
024: /**
025: * The lists of projections.
026: */
027: private List<ProjectionElemList> projections = new ArrayList<ProjectionElemList>();
028:
029: /*--------------*
030: * Constructors *
031: *--------------*/
032:
033: public MultiProjection() {
034: }
035:
036: public MultiProjection(TupleExpr arg) {
037: super (arg);
038: }
039:
040: public MultiProjection(TupleExpr arg,
041: Iterable<ProjectionElemList> projections) {
042: this (arg);
043: addProjections(projections);
044: }
045:
046: /*---------*
047: * Methods *
048: *---------*/
049:
050: public List<ProjectionElemList> getProjections() {
051: return Collections.unmodifiableList(projections);
052: }
053:
054: public void setProjections(Iterable<ProjectionElemList> projections) {
055: this .projections.clear();
056: addProjections(projections);
057: }
058:
059: public void addProjections(Iterable<ProjectionElemList> projections) {
060: for (ProjectionElemList projection : projections) {
061: addProjection(projection);
062: }
063: }
064:
065: public void addProjection(ProjectionElemList projection) {
066: assert projection != null : "projection must not be null";
067: projections.add(projection);
068: projection.setParentNode(this );
069: }
070:
071: @Override
072: public Set<String> getBindingNames() {
073: Set<String> bindingNames = new HashSet<String>();
074:
075: for (ProjectionElemList projElemList : projections) {
076: bindingNames.addAll(projElemList.getTargetNames());
077: }
078:
079: return bindingNames;
080: }
081:
082: public <X extends Exception> void visit(QueryModelVisitor<X> visitor)
083: throws X {
084: visitor.meet(this );
085: }
086:
087: @Override
088: public <X extends Exception> void visitChildren(
089: QueryModelVisitor<X> visitor) throws X {
090: for (ProjectionElemList projElemList : projections) {
091: projElemList.visit(visitor);
092: }
093:
094: super .visitChildren(visitor);
095: }
096:
097: @Override
098: public void replaceChildNode(QueryModelNode current,
099: QueryModelNode replacement) {
100: int index = projections.indexOf(current);
101: if (index >= 0) {
102: projections.set(index, (ProjectionElemList) replacement);
103: replacement.setParentNode(this );
104: } else {
105: super .replaceChildNode(current, replacement);
106: }
107: }
108:
109: @Override
110: public MultiProjection clone() {
111: MultiProjection clone = (MultiProjection) super .clone();
112:
113: List<ProjectionElemList> projectionsClone = new ArrayList<ProjectionElemList>(
114: getProjections().size());
115: for (ProjectionElemList ge : getProjections()) {
116: projectionsClone.add(ge.clone());
117: }
118:
119: clone.setProjections(projectionsClone);
120:
121: return clone;
122: }
123: }
|