001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc.sql.exp;
012:
013: import java.util.Map;
014:
015: /**
016: * A join to a table.
017: * @see SelectExp
018: */
019: public class Join {
020:
021: /**
022: * The table being joined to.
023: */
024: public SelectExp selectExp;
025: /**
026: * The expression that joins the tables.
027: */
028: public SqlExp exp;
029: /**
030: * The next join in the list.
031: */
032: public Join next;
033: private Join mergedWith;
034:
035: public Join() {
036: }
037:
038: public Join getClone(Map cloneMap) {
039: Join clone = new Join();
040: if (selectExp != null)
041: clone.selectExp = (SelectExp) SqlExp.createClone(selectExp,
042: cloneMap);
043: if (exp != null)
044: clone.exp = SqlExp.createClone(exp, cloneMap);
045: if (next != null)
046: clone.next = next.getClone(cloneMap);
047: return clone;
048: }
049:
050: public String toString() {
051: return "Join@" + System.identityHashCode(this ) + " "
052: + selectExp;
053: }
054:
055: /**
056: * Dump debugging info to System.out.
057: */
058: public void dump(String indent) {
059: System.out.println(indent + this );
060: indent = indent + " ";
061: if (exp == null) {
062: System.out.println(indent + " exp is NULL");
063: } else {
064: exp.dump(indent);
065: }
066: selectExp.dump(indent);
067: }
068:
069: /**
070: * Dump us and our list to System.out.
071: */
072: public void dumpList(String indent) {
073: dump(indent);
074: for (Join j = next; j != null; j = j.next)
075: j.dump(indent);
076: }
077:
078: /**
079: * Create an aliases for any tables we may have.
080: */
081: public int createAlias(int index) {
082: if (mergedWith != null) {
083: index = mergedWith.createAlias(index);
084: selectExp.alias = mergedWith.selectExp.alias;
085: }
086:
087: index = selectExp.createAlias(index);
088: if (exp != null) {
089: return exp.createAlias(index);
090: } else {
091: return index;
092: }
093: }
094:
095: /**
096: * Add an extra expression to our exp. This will be joined with any
097: * existing exp using and.
098: */
099: public void appendJoinExp(SqlExp e) {
100: if (exp == null) {
101: exp = e;
102: } else if (exp instanceof AndExp) {
103: exp.append(e);
104: } else {
105: AndExp ae = new AndExp(exp);
106: exp.next = e;
107: exp = ae;
108: }
109: }
110:
111: /**
112: * Find the deepest Join from us down. This will return this if there
113: * are no joins from our selectExp.
114: */
115: public Join findDeepestJoin() {
116: if (selectExp.joinList == null)
117: return this ;
118: Join j;
119: for (j = selectExp.joinList; j.next != null; j = j.next)
120: ;
121: return j.findDeepestJoin();
122: }
123:
124: /**
125: * If the join tree's are equivalent.
126: */
127: public static boolean isEqaul(Join j1, Join j2) {
128: if (j1 == j2)
129: return true;
130: if (j1 == null)
131: return false;
132: if (j2 == null)
133: return false;
134:
135: if (j1.selectExp != null && j2.selectExp != null) {
136: if (j1.selectExp.jdbcField == j2.selectExp.jdbcField) {
137: if (j1.exp instanceof JoinExp
138: && j2.exp instanceof JoinExp) {
139: if (JoinExp.isEqual((JoinExp) j1.exp,
140: (JoinExp) j2.exp)) {
141: if (isEqaul(j1.selectExp.joinList,
142: j2.selectExp.joinList)) {
143: return Join.isEqaul(j1.next, j2.next);
144: }
145: }
146: }
147: }
148: }
149: return false;
150: }
151:
152: /**
153: * Only check if the actual two joins are equal and ignore next joins.
154: */
155: public static boolean isCurrentEqaul(Join j1, Join j2) {
156: if (j1 == j2)
157: return true;
158: if (j1 == null)
159: return false;
160: if (j2 == null)
161: return false;
162:
163: if (j1.selectExp != null && j2.selectExp != null) {
164: if (j1.selectExp.jdbcField == j2.selectExp.jdbcField) {
165: if (j1.exp instanceof JoinExp
166: && j2.exp instanceof JoinExp) {
167: return JoinExp.isEqual((JoinExp) j1.exp,
168: (JoinExp) j2.exp);
169: }
170: }
171: }
172: return false;
173: }
174:
175: /**
176: * Return true if this join is only acting as a place holder for the selectList
177: */
178: public boolean isMerged() {
179: return mergedWith != null;
180: }
181:
182: public Join getMergedWith() {
183: return mergedWith;
184: }
185:
186: public void setMergedWith(Join mergedWith) {
187: this.mergedWith = mergedWith;
188: }
189: }
|