protected boolean usesSelector(Join join, SelectorName selector) { Source left = join.getLeft(); if (left instanceof Selector && selector.equals(((Selector) left).aliasOrName())) return true; if (left instanceof Join && usesSelector((Join) left, selector)) return true; Source right = join.getRight(); if (right instanceof Selector && selector.equals(((Selector) right).aliasOrName())) return true; if (right instanceof Join && usesSelector((Join) right, selector)) return true; return false; }
protected Source rewrite(JoinableSources joinableSources) { // Find the order of the joins ... List<Join> joins = new LinkedList<Join>(); for (SameNodeJoinCondition joinCondition : joinableSources.getJoinConditions()) { SelectorName selector1 = joinCondition.selector1Name(); SelectorName selector2 = joinCondition.selector2Name(); boolean found = false; ListIterator<Join> iter = joins.listIterator(); while (iter.hasNext()) { Join next = iter.next(); Join replacement = null; if (usesSelector(next, selector1)) { Source right = joinableSources.getSelectors().get(selector2.name()); replacement = new Join(next, JoinType.INNER, right, joinCondition); } else if (usesSelector(next, selector2)) { Source left = joinableSources.getSelectors().get(selector1.name()); replacement = new Join(left, JoinType.INNER, next, joinCondition); } if (replacement != null) { iter.previous(); iter.remove(); joins.add(replacement); found = true; break; } } if (!found) { // Nothing matched, so add a new join ... Source left = joinableSources.getSelectors().get(selector1.name()); Source right = joinableSources.getSelectors().get(selector2.name()); if (left == null) { Position pos = joinableSources.getJoinCriteriaPosition(); String msg = JcrI18n.selectorUsedInEquiJoinCriteriaDoesNotExistInQuery.text( selector1.name(), pos.getLine(), pos.getColumn()); throw new ParsingException(pos, msg); } if (right == null) { Position pos = joinableSources.getJoinCriteriaPosition(); String msg = JcrI18n.selectorUsedInEquiJoinCriteriaDoesNotExistInQuery.text( selector2.name(), pos.getLine(), pos.getColumn()); throw new ParsingException(pos, msg); } joins.add(new Join(left, JoinType.INNER, right, joinCondition)); } } if (joins.size() == 1) { return joins.get(0); } // Otherwise the join conditions were not sufficient return null; }