001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.sail.rdbms.algebra.base;
007:
008: import java.util.ArrayList;
009: import java.util.List;
010:
011: import org.openrdf.query.algebra.QueryModelNode;
012: import org.openrdf.query.algebra.QueryModelVisitor;
013: import org.openrdf.sail.rdbms.algebra.ColumnVar;
014:
015: /**
016: * An item in the SQL from clause.
017: *
018: * @author James Leigh
019: *
020: */
021: public abstract class FromItem extends RdbmsQueryModelNodeBase {
022: private String alias;
023: private boolean left;
024: private List<FromItem> joins = new ArrayList<FromItem>();
025: private List<SqlExpr> filters = new ArrayList<SqlExpr>();
026:
027: public FromItem(String alias) {
028: super ();
029: this .alias = alias;
030: }
031:
032: public String getAlias() {
033: return alias;
034: }
035:
036: public boolean isLeft() {
037: return left;
038: }
039:
040: public void setLeft(boolean left) {
041: this .left = left;
042: }
043:
044: public List<SqlExpr> getFilters() {
045: return filters;
046: }
047:
048: public void addFilter(SqlExpr filter) {
049: this .filters.add(filter);
050: filter.setParentNode(this );
051: }
052:
053: public List<FromItem> getJoins() {
054: return joins;
055: }
056:
057: public ColumnVar getVarForChildren(String name) {
058: for (FromItem join : joins) {
059: ColumnVar var = join.getVar(name);
060: if (var != null)
061: return var;
062: }
063: return null;
064: }
065:
066: public ColumnVar getVar(String name) {
067: return getVarForChildren(name);
068: }
069:
070: public void addJoin(FromItem join) {
071: joins.add(join);
072: joinAdded(join);
073: }
074:
075: public void addJoinBefore(FromItem valueJoin, FromItem join) {
076: for (int i = 0, n = joins.size(); i < n; i++) {
077: if (joins.get(i) == join) {
078: joins.add(i, valueJoin);
079: joinAdded(valueJoin);
080: return;
081: }
082: }
083: addJoin(valueJoin);
084: }
085:
086: protected void joinAdded(FromItem valueJoin) {
087: valueJoin.setParentNode(this );
088: }
089:
090: public FromItem getFromItem(String alias) {
091: if (this .alias.equals(alias))
092: return this ;
093: for (FromItem join : joins) {
094: FromItem result = join.getFromItem(alias);
095: if (result != null)
096: return result;
097: }
098: return null;
099: }
100:
101: public void removeFilter(SqlExpr sqlExpr) {
102: for (int i = filters.size() - 1; i >= 0; i--) {
103: if (filters.get(i) == sqlExpr) {
104: filters.remove(i);
105: break;
106: }
107: }
108: }
109:
110: public List<ColumnVar> appendVars(List<ColumnVar> vars) {
111: for (FromItem join : joins) {
112: join.appendVars(vars);
113: }
114: return vars;
115: }
116:
117: @Override
118: public String getSignature() {
119: StringBuilder sb = new StringBuilder();
120: if (left) {
121: sb.append("LEFT ");
122: }
123: sb.append(super .getSignature());
124: sb.append(" ").append(alias);
125: return sb.toString();
126: }
127:
128: @Override
129: public FromItem clone() {
130: FromItem clone = (FromItem) super .clone();
131: clone.joins = new ArrayList<FromItem>();
132: for (FromItem join : joins) {
133: clone.addJoin(join.clone());
134: }
135: clone.filters = new ArrayList<SqlExpr>();
136: for (SqlExpr expr : filters) {
137: clone.addFilter(expr.clone());
138: }
139: return clone;
140: }
141:
142: @Override
143: public <X extends Exception> void visitChildren(
144: QueryModelVisitor<X> visitor) throws X {
145: super .visitChildren(visitor);
146: for (FromItem join : new ArrayList<FromItem>(joins)) {
147: join.visit(visitor);
148: }
149: for (SqlExpr expr : new ArrayList<SqlExpr>(filters)) {
150: expr.visit(visitor);
151: }
152: }
153:
154: @Override
155: public void replaceChildNode(QueryModelNode current,
156: QueryModelNode replacement) {
157: for (int i = 0, n = joins.size(); i < n; i++) {
158: if (current == joins.get(i)) {
159: joins.set(i, (FromItem) replacement);
160: joinAdded((FromItem) replacement);
161: return;
162: }
163: }
164: for (int i = 0, n = filters.size(); i < n; i++) {
165: if (current == filters.get(i)) {
166: filters.set(i, (SqlExpr) replacement);
167: replacement.setParentNode(this);
168: return;
169: }
170: }
171: super.replaceChildNode(current, replacement);
172: }
173:
174: }
|