/******************************************************************************* * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation * ******************************************************************************/ package org.eclipse.persistence.jpa.jpql.parser; import org.eclipse.persistence.jpa.jpql.WordParser; import static org.eclipse.persistence.jpa.jpql.parser.Expression.*; /** * This {@link JoinFactory} creates a new {@link Join} when the portion of the query to parse starts * with <b>JOIN</b> or <b>FETCH JOIN</b>, respectively. * * @see Join * * @version 2.5.2 * @since 2.3 * @author Pascal Filion */ @SuppressWarnings("nls") public final class JoinFactory extends ExpressionFactory { /** * The unique identifier of this {@link JoinFactory}. */ public static final String ID = JOIN; /** * Creates a new <code>JoinFactory</code>. */ public JoinFactory() { super(ID, LEFT, INNER, JOIN, OUTER, FETCH); } /** * {@inheritDoc} */ @Override protected AbstractExpression buildExpression(AbstractExpression parent, WordParser wordParser, String word, JPQLQueryBNF queryBNF, AbstractExpression expression, boolean tolerant) { int index = wordParser.position(); // TODO: There must be a better way to parse all the JOIN identifiers with a generic // parsing behavior without parsing something like "LEFT JOIN OUTER" has a single // expression but multiple join expressions // JOIN and JOIN FETCH if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, JOIN_FETCH); } // JOIN else { expression = new Join(parent, JOIN); } } // LEFT else if (wordParser.startsWithIdentifier(LEFT)) { index += 4; index += wordParser.whitespaceCount(index); // LEFT OUTER if (wordParser.startsWithIdentifier(OUTER, index)) { index += 5; index += wordParser.whitespaceCount(index); if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // LEFT OUTER JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, LEFT_OUTER_JOIN_FETCH); } // LEFT OUTER JOIN else { expression = new Join(parent, LEFT_OUTER_JOIN); } } // LEFT OUTER INNER else if (wordParser.startsWithIdentifier(INNER, index)) { index += 5; index += wordParser.whitespaceCount(index); if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // LEFT OUTER INNER JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, "LEFT OUTER INNER JOIN FETCH"); } // LEFT OUTER INNER JOIN else { expression = new Join(parent, "LEFT OUTER INNER JOIN"); } } else { expression = new Join(parent, "LEFT OUTER INNER"); } } else { expression = new Join(parent, "LEFT OUTER"); } } // LEFT JOIN else if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // LEFT JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, LEFT_JOIN_FETCH); } // LEFT JOIN else { expression = new Join(parent, LEFT_JOIN); } } // LEFT INNER else if (wordParser.startsWithIdentifier(INNER, index)) { index += 5; index += wordParser.whitespaceCount(index); // LEFT INNER JOIN if (wordParser.startsWithIdentifier(JOIN, index)) { index += 5; index += wordParser.whitespaceCount(index); // LEFT INNER JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, "LEFT INNER JOIN FETCH"); } // LEFT INNER JOIN else { expression = new Join(parent, "LEFT INNER JOIN"); } } } // LEFT else { expression = new Join(parent, LEFT); } } // INNER JOIN and INNER JOIN FETCH else if (wordParser.startsWithIdentifier(INNER, index)) { index += 5; index += wordParser.whitespaceCount(index); if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // INNER JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, INNER_JOIN_FETCH); } // INNER JOIN else { expression = new Join(parent, INNER_JOIN); } } // INNER else { expression = new Join(parent, INNER); } } // OUTER JOIN and OUTER JOIN FETCH // OUTER INNER JOIN and OUTER INNER JOIN FETCH else if (wordParser.startsWithIdentifier(OUTER, index)) { index += 5; index += wordParser.whitespaceCount(index); // OUTER JOIN and OUTER JOIN FETCH if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // OUTER JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, "OUTER JOIN FETCH"); } // OUTER JOIN else { expression = new Join(parent, "OUTER JOIN"); } } // OUTER INNER JOIN and OUTER INNER JOIN FETCH else if (wordParser.startsWithIdentifier(INNER, index)) { index += 5; index += wordParser.whitespaceCount(index); if (wordParser.startsWithIdentifier(JOIN, index)) { index += 4; index += wordParser.whitespaceCount(index); // OUTER INNER JOIN FETCH if (wordParser.startsWithIdentifier(FETCH, index)) { expression = new Join(parent, "OUTER INNER JOIN FETCH"); } // INNER JOIN else { expression = new Join(parent, "OUTER INNER JOIN"); } } } // OUTER else { expression = new Join(parent, OUTER); } } else { return null; } expression.parse(wordParser, tolerant); return expression; } }