| Author | Dave Jarvis <email> |
|---|---|
| Date | 2015-03-21 19:08:50 GMT-0700 |
| Commit | 8eab33addac33a15be027128f92b467521999909 |
| Parent | e3391bd |
| ************************************************************************/ | ||
| -query: start statement+ where? EOF ; | ||
| +query: start statements where? EOF ; | ||
| /* Define the root, line map, and JOIN clauses. */ | ||
| start : (root | module) T_COMMA ; | ||
| root : T_ROOT T_GT element ; | ||
| module: T_MODULE T_ID ; | ||
| -statement: (pop | glob | map | include) T_COMMA ; | ||
| -pop : T_POP ; | ||
| -glob : T_GLOB ; | ||
| +statements: statement+ ; | ||
| +statement : (pop | glob | map | include) T_COMMA ; | ||
| +pop : T_POP ; | ||
| +glob : T_GLOB ; | ||
| /* Map lines affect the tree depth differently. */ | ||
| -map : tableMap | columnMap | attributeMap | innerMap | outerMap ; | ||
| +map : tableMap | columnMap | attributeMap | joinMap ; | ||
| tableMap : table T_GT path ; | ||
| columnMap : column T_GT path ; | ||
| attributeMap: column T_GT attribute ; | ||
| -innerMap : tableColumn T_INNER tableColumn ; | ||
| -outerMap : tableColumn T_OUTER tableColumn ; | ||
| +joinMap : tableColumn (T_INNER | T_OUTER) tableColumn ; | ||
| include : T_IMPORT T_ID ; |
| +package com.whitemagicsoftware.rxm; | ||
| + | ||
| +import java.util.ArrayList; | ||
| +import java.util.Iterator; | ||
| +import java.util.List; | ||
| + | ||
| +import org.antlr.v4.runtime.ParserRuleContext; | ||
| + | ||
| +import org.antlr.v4.runtime.tree.ParseTree; | ||
| +import org.antlr.v4.runtime.tree.ParseTreeListener; | ||
| +import org.antlr.v4.runtime.tree.ErrorNode; | ||
| +import org.antlr.v4.runtime.tree.TerminalNode; | ||
| + | ||
| +/** | ||
| + * Instances of this class allows multiple listeners to receive events | ||
| + * while walking the parse tree. For example: | ||
| + * | ||
| + * <pre> | ||
| + * ProxyParseTreeListener proxy = new ProxyParseTreeListener(); | ||
| + * ParseTreeListener listener1 = ... ; | ||
| + * ParseTreeListener listener2 = ... ; | ||
| + * proxy.add( listener1 ); | ||
| + * proxy.add( listener2 ); | ||
| + * ParseTreeWalker.DEFAULT.walk( proxy, ctx ); | ||
| + * </pre> | ||
| + */ | ||
| +public class ProxyParseTreeListener implements ParseTreeListener { | ||
| + private List<ParseTreeListener> listeners; | ||
| + | ||
| + /** | ||
| + * Creates a new proxy without an empty list of listeners. Add | ||
| + * listeners before walking the tree. | ||
| + */ | ||
| + public ProxyParseTreeListener() { | ||
| + // Setting the listener to null automatically instantiates a new list. | ||
| + this( null ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Creates a new proxy with the given list of listeners. | ||
| + * | ||
| + * @param listeners A list of listerners to receive events. | ||
| + */ | ||
| + public ProxyParseTreeListener( List<ParseTreeListener> listeners ) { | ||
| + setListeners( listeners ); | ||
| + } | ||
| + | ||
| + @Override | ||
| + public void enterEveryRule( ParserRuleContext ctx ) { | ||
| + Iterator<ParseTreeListener> i = iterator(); | ||
| + | ||
| + while( i.hasNext() ) { | ||
| + ParseTreeListener listener = i.next(); | ||
| + listener.enterEveryRule( ctx ); | ||
| + ctx.enterRule( listener ); | ||
| + } | ||
| + } | ||
| + | ||
| + @Override | ||
| + public void exitEveryRule( ParserRuleContext ctx ) { | ||
| + Iterator<ParseTreeListener> i = iterator(); | ||
| + | ||
| + while( i.hasNext() ) { | ||
| + ParseTreeListener listener = i.next(); | ||
| + ctx.exitRule( listener ); | ||
| + listener.exitEveryRule( ctx ); | ||
| + } | ||
| + } | ||
| + | ||
| + @Override | ||
| + public void visitErrorNode( ErrorNode node ) { | ||
| + Iterator<ParseTreeListener> i = iterator(); | ||
| + | ||
| + while( i.hasNext() ) { | ||
| + ParseTreeListener listener = i.next(); | ||
| + listener.visitErrorNode( node ); | ||
| + } | ||
| + } | ||
| + | ||
| + @Override | ||
| + public void visitTerminal( TerminalNode node ) { | ||
| + Iterator<ParseTreeListener> i = iterator(); | ||
| + | ||
| + while( i.hasNext() ) { | ||
| + ParseTreeListener listener = i.next(); | ||
| + listener.visitTerminal( node ); | ||
| + } | ||
| + } | ||
| + | ||
| + /** | ||
| + * Adds the given listener to the list of event notification recipients. | ||
| + * | ||
| + * @param listener A listener to begin receiving events. | ||
| + */ | ||
| + public void add( ParseTreeListener listener ) { | ||
| + getListeners().add( listener ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Removes the given listener to the list of event notification recipients. | ||
| + * | ||
| + * @param listener A listener to stop receiving events. | ||
| + * @return false The listener was not registered to receive events. | ||
| + */ | ||
| + public boolean remove( ParseTreeListener listener ) { | ||
| + return getListeners().remove( listener ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns an iterator of a copy of the current list. This protects | ||
| + * against concurrent modifications to the list. | ||
| + * | ||
| + * @return A non-null, possibly empty, list of ParseTreeListeners that | ||
| + * will receive events. | ||
| + */ | ||
| + private Iterator<ParseTreeListener> iterator() { | ||
| + List<ParseTreeListener> list = createParseTreeListenerList(); | ||
| + list.addAll( getListeners() ); | ||
| + return list.iterator(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the list of listeners. | ||
| + * | ||
| + * @return The list of listeners to receive tree walking events. | ||
| + */ | ||
| + private List<ParseTreeListener> getListeners() { | ||
| + return this.listeners; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Changes the list of listeners to receive events. If the given list of | ||
| + * listeners is null, an empty list will be created. | ||
| + * | ||
| + * @param listeners A list of listeners to receive tree walking | ||
| + * events. | ||
| + */ | ||
| + public void setListeners( List<ParseTreeListener> listeners ) { | ||
| + if( listeners == null ) { | ||
| + listeners = createParseTreeListenerList(); | ||
| + } | ||
| + | ||
| + this.listeners = listeners; | ||
| + } | ||
| + | ||
| + protected List<ParseTreeListener> createParseTreeListenerList() { | ||
| + return new ArrayList<ParseTreeListener>(); | ||
| + } | ||
| +} | ||
| + | ||
| import com.whitemagicsoftware.rxm.tree.Tree; | ||
| import com.whitemagicsoftware.rxm.tree.xml.SelectClauseTree; | ||
| -import com.whitemagicsoftware.rxm.tree.xml.JoinClauseList; | ||
| +import com.whitemagicsoftware.rxm.tree.xml.JoinClause; | ||
| import com.whitemagicsoftware.rxm.tree.xml.WhereClause; | ||
| import org.antlr.v4.runtime.ANTLRInputStream; | ||
| import org.antlr.v4.runtime.CommonTokenStream; | ||
| import org.antlr.v4.runtime.ParserRuleContext; | ||
| +import org.antlr.v4.runtime.tree.ParseTreeListener; | ||
| import org.antlr.v4.runtime.tree.ParseTreeWalker; | ||
| /** Current context. */ | ||
| private Tree<Payload> selectClauseTree; | ||
| - | ||
| - /** List of inner and outer joins (tree used as flat hierarchy). */ | ||
| - private Tree<Payload> joinClauseList; | ||
| + | ||
| + private JoinClause joinClause = new JoinClause(); | ||
| private WhereClause whereClause = new WhereClause(); | ||
| + | ||
| + private ProxyParseTreeListener proxy = new ProxyParseTreeListener(); | ||
| /** | ||
| QueryLexer lexer = new QueryLexer( new ANTLRInputStream( rxm ) ); | ||
| CommonTokenStream tokens = new CommonTokenStream( lexer ); | ||
| + QueryParser.QueryContext ctx = (new QueryParser( tokens )).query(); | ||
| - QueryParser parser = new QueryParser( tokens ); | ||
| - QueryParser.QueryContext ctx = parser.query(); | ||
| + receiveEvents( this ); | ||
| + receiveEvents( getJoinClause() ); | ||
| + notifyEvents( ctx ); | ||
| + } | ||
| - ParseTreeWalker walker = new ParseTreeWalker(); | ||
| - walker.walk( this, ctx ); | ||
| + private void notifyEvents( QueryParser.QueryContext ctx ) { | ||
| + ParseTreeWalker.DEFAULT.walk( getProxyParseTreeListener(), ctx ); | ||
| + } | ||
| + | ||
| + private void receiveEvents( ParseTreeListener listener ) { | ||
| + getProxyParseTreeListener().add( listener ); | ||
| + } | ||
| + | ||
| + private void rescindEvents( ParseTreeListener listener ) { | ||
| + getProxyParseTreeListener().remove( listener ); | ||
| } | ||
| } | ||
| - @Override | ||
| - public synchronized void enterInnerMap( QueryParser.InnerMapContext ctx ) { | ||
| - addJoinClause( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public synchronized void enterOuterMap( QueryParser.OuterMapContext ctx ) { | ||
| - addJoinClause( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public synchronized void enterWhere( QueryParser.WhereContext ctx ) { | ||
| - getWhereClause().enterWhere( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public void exitExprOr( QueryParser.ExprOrContext ctx ) { | ||
| - getWhereClause().exitExprOr( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public void exitExprAnd( QueryParser.ExprAndContext ctx ) { | ||
| - getWhereClause().exitExprAnd( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public synchronized void enterExprParen( QueryParser.ExprParenContext ctx ) { | ||
| - getWhereClause().enterExprParen( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public synchronized void exitExprParen( QueryParser.ExprParenContext ctx ) { | ||
| - getWhereClause().exitExprParen( ctx ); | ||
| - } | ||
| - | ||
| - @Override | ||
| - public synchronized void enterExprCompRel( | ||
| - QueryParser.ExprCompRelContext ctx ) { | ||
| - getWhereClause().enterExprCompRel( ctx ); | ||
| - } | ||
| - | ||
| + /** | ||
| + * The where clause begins after all the statements. The where clause | ||
| + * is added to the listeners at this point to receive the enterWhere | ||
| + * and subsequent events. Listening at enterWhere would be too late. | ||
| + */ | ||
| @Override | ||
| - public synchronized void enterExprCompEqual( | ||
| - QueryParser.ExprCompEqualContext ctx ) { | ||
| - getWhereClause().enterExprCompEqual( ctx ); | ||
| + public void exitStatements( | ||
| + QueryParser.StatementsContext ctx ) { | ||
| + receiveEvents( getWhereClause() ); | ||
| + rescindEvents( getJoinClause() ); | ||
| } | ||
| /** | ||
| * Invoked when there are no more <b>rxm</b> tokens to parse. | ||
| * | ||
| * @param ctx Indicates that the query has been parsed. | ||
| */ | ||
| @Override | ||
| - public synchronized void exitQuery( QueryParser.QueryContext ctx ) { | ||
| + public void exitQuery( QueryParser.QueryContext ctx ) { | ||
| String select = getSelectClause(); | ||
| String from = getFromClause(); | ||
| - String join = getJoinClause(); | ||
| + String join = getJoinClause().toString(); | ||
| String where = getWhereClause().toString(); | ||
| * | ||
| * @return The FROM portion of a SQL statement. | ||
| - */ | ||
| - private String getJoinClause() { | ||
| - return getJoinClauseList().toString(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Adds a new leaf, representing a JOIN clause, to the from clause list. | ||
| - * | ||
| - * @param ctx The INNER/OUTER JOIN expression to add to the list. | ||
| */ | ||
| - private void addJoinClause( ParserRuleContext ctx ) { | ||
| - getJoinClauseList().addLeaf( createJoinClauseList( ctx ) ); | ||
| + private JoinClause getJoinClause() { | ||
| + return this.joinClause; | ||
| } | ||
| return sct; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Changes where the next mapped items will be attached. | ||
| - */ | ||
| - private void setJoinClauseList( Tree<Payload> joinClauseList ) { | ||
| - this.joinClauseList = joinClauseList; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Lazily-initializes the from clause list. | ||
| - * | ||
| - * @return The list that will contain the query's FROM clause. | ||
| - */ | ||
| - private Tree<Payload> getJoinClauseList() { | ||
| - Tree<Payload> list = this.joinClauseList; | ||
| - | ||
| - if( list == null ) { | ||
| - setJoinClauseList( list = createJoinClauseList( null ) ); | ||
| - } | ||
| - | ||
| - return list; | ||
| } | ||
| - /** | ||
| - * Creates a new JoinClauseList instance containing the given parser | ||
| - * rule context. The resulting tree should only have leaves added | ||
| - * to the root, never branching beyond a flat hierarchy (one-level deep). | ||
| - * | ||
| - * @return A new JoinClauseList instance, never null, containing a payload | ||
| - * with the parser rule context. | ||
| - */ | ||
| - private Tree<Payload> createJoinClauseList( ParserRuleContext ctx ) { | ||
| - return new JoinClauseList<Payload>( new Payload( ctx ) ); | ||
| + private ProxyParseTreeListener getProxyParseTreeListener() { | ||
| + return this.proxy; | ||
| } | ||
| } | ||
| +package com.whitemagicsoftware.rxm.tree.xml; | ||
| + | ||
| +import java.nio.CharBuffer; | ||
| + | ||
| +import com.whitemagicsoftware.rxm.grammar.QueryBaseListener; | ||
| +import com.whitemagicsoftware.rxm.grammar.QueryParser; | ||
| + | ||
| +import org.antlr.v4.runtime.tree.TerminalNode; | ||
| + | ||
| +/** | ||
| + * Common behaviour for various clauses. | ||
| + */ | ||
| +public class Clause extends QueryBaseListener { | ||
| + private static int INDENT = 2; | ||
| + | ||
| + private StringBuilder buffer = new StringBuilder( 2048 ); | ||
| + | ||
| + /** | ||
| + */ | ||
| + public Clause() { | ||
| + } | ||
| + | ||
| + /** | ||
| + * Appends a given string to the buffer. | ||
| + * | ||
| + * @param s The string to append. | ||
| + * @return this to chain the append calls. | ||
| + */ | ||
| + protected Clause append( String s ) { | ||
| + getBuffer().append( s ); | ||
| + return this; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the buffer converted to a string. This is the result of | ||
| + * the transformed output and should only be called when the parsing | ||
| + * of the <b>rxm</b> source is complete. | ||
| + * | ||
| + * @return A non-null string, possibly empty. | ||
| + */ | ||
| + public String toString() { | ||
| + return getBuffer().toString(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the buffer used for building the transformed output. | ||
| + * | ||
| + * @return A non-null string builder, possibly empty. | ||
| + */ | ||
| + private StringBuilder getBuffer() { | ||
| + return this.buffer; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Answers whether the transformed query should be indented with newlines. | ||
| + * | ||
| + * @return true Format the output (by default). | ||
| + */ | ||
| + protected boolean beautify() { | ||
| + // Returns the System property value. | ||
| + return Boolean.getBoolean( "beautify" ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * When beautify is enabled, this returns a newline followed by | ||
| + * the default amount ofindentation; when disabled, this returns a single | ||
| + * space. | ||
| + * | ||
| + * @return A newline followed by spaces or a single space. | ||
| + */ | ||
| + protected String getNewlineIndent() { | ||
| + return getNewline() + (beautify() ? getDefaultIndent() : " "); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Creates a string of spaces that is spaces spaces long. | ||
| + * | ||
| + * @param spaces The number of spaces to add to the string. | ||
| + * @return A string with 'spaces' number of " " padding. | ||
| + */ | ||
| + protected String getIndent( int spaces ) { | ||
| + return CharBuffer.allocate( spaces ).toString().replace( '\0', ' ' ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the default amount of spaces. | ||
| + * | ||
| + * @return " " (by default) | ||
| + */ | ||
| + protected String getDefaultIndent() { | ||
| + return getIndent( getIndentBy() ); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the system newline separator character sequence. | ||
| + * | ||
| + * @return CR/LF on Windows, LF on Unix, CR on MacOS, or " " if beautify | ||
| + * is set true. | ||
| + */ | ||
| + protected String getNewline() { | ||
| + return beautify() ? System.lineSeparator() : " "; | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the number of spaces to indent by. | ||
| + * | ||
| + * @return 2 (by default) | ||
| + */ | ||
| + protected int getIndentBy() { | ||
| + return INDENT; | ||
| + } | ||
| +} | ||
| + | ||
| -package com.whitemagicsoftware.rxm.tree.xml; | ||
| - | ||
| -import com.whitemagicsoftware.rxm.grammar.QueryParser; | ||
| -import com.whitemagicsoftware.rxm.tree.Payload; | ||
| -import com.whitemagicsoftware.rxm.tree.Token; | ||
| -import com.whitemagicsoftware.rxm.tree.Tree; | ||
| - | ||
| -import org.antlr.v4.runtime.ParserRuleContext; | ||
| - | ||
| -/** | ||
| - * Transforms <b><code>table.column +> table.column</code></b> into a SQL | ||
| - * <code>INNER JOIN</code> expression. | ||
| - */ | ||
| -public class InnerMapContext extends JoinMapContext { | ||
| - /** | ||
| - * Default constructor (calls super). | ||
| - * | ||
| - * @param ctx The payload that associates the parser rule context with | ||
| - * the abstract syntax tree. | ||
| - */ | ||
| - public InnerMapContext( Payload ctx ) { | ||
| - super( ctx ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the JOIN qualifier keyword. | ||
| - * | ||
| - * @return "INNER"; | ||
| - */ | ||
| - @Override | ||
| - public String getJoinType() { | ||
| - return "INNER"; | ||
| - } | ||
| - | ||
| - @Override | ||
| - protected QueryParser.TableColumnContext tableColumn( int i ) { | ||
| - return ((QueryParser.InnerMapContext)getParserRuleContext()).tableColumn(i); | ||
| - } | ||
| -} | ||
| - | ||
| +package com.whitemagicsoftware.rxm.tree.xml; | ||
| + | ||
| +import com.whitemagicsoftware.rxm.tree.Payload; | ||
| +import com.whitemagicsoftware.rxm.tree.Tree; | ||
| + | ||
| +import com.whitemagicsoftware.rxm.grammar.QueryBaseListener; | ||
| +import com.whitemagicsoftware.rxm.grammar.QueryParser; | ||
| + | ||
| +import org.antlr.v4.runtime.ParserRuleContext; | ||
| +import org.antlr.v4.runtime.tree.TerminalNode; | ||
| + | ||
| +/** | ||
| + * Transforms <b><code>table.column +> table.column</code></b> into a SQL | ||
| + * <code>INNER JOIN</code> expression; similarly, transforms the operand | ||
| + * <code>-></code> into <code>OUTER JOIN</code>. | ||
| + */ | ||
| +public class JoinClause extends Clause { | ||
| + public JoinClause() { | ||
| + } | ||
| + | ||
| + @Override | ||
| + public void enterJoinMap( QueryParser.JoinMapContext ctx ) { | ||
| + QueryParser.TableColumnContext | ||
| + lhs = ctx.tableColumn( 0 ), | ||
| + rhs = ctx.tableColumn( 0 ); | ||
| + | ||
| + String lhsTableName = lhs.table().getText(); | ||
| + String rhsTableName = rhs.table().getText(); | ||
| + | ||
| + append( String.format( "%s JOIN %s %s ON%s%s = %s%s", | ||
| + ctx.T_OUTER() == null ? "INNER" : "OUTER", | ||
| + lhsTableName, | ||
| + lhsTableName, | ||
| + getNewlineIndent(), | ||
| + lhsTableName, | ||
| + rhsTableName, | ||
| + getNewline() ) | ||
| + ); | ||
| + } | ||
| +} | ||
| + | ||
| -package com.whitemagicsoftware.rxm.tree.xml; | ||
| - | ||
| -import com.whitemagicsoftware.rxm.grammar.QueryParser; | ||
| -import com.whitemagicsoftware.rxm.tree.Payload; | ||
| -import com.whitemagicsoftware.rxm.tree.Token; | ||
| - | ||
| -import org.antlr.v4.runtime.ParserRuleContext; | ||
| - | ||
| -/** | ||
| - * Superclass for common behaviour between INNER and OUTER JOIN clauses. | ||
| - */ | ||
| -public abstract class JoinMapContext extends PayloadParserRuleContext { | ||
| - /** | ||
| - * Default constructor (calls super). | ||
| - * | ||
| - * @param initPayload The payload that associates the parser rule context | ||
| - * with the abstract syntax tree. | ||
| - */ | ||
| - public JoinMapContext( Payload initPayload ) { | ||
| - super( initPayload ); | ||
| - } | ||
| - | ||
| - public abstract String getJoinType(); | ||
| - | ||
| - /** | ||
| - * Returns the starting text for an OUTER JOIN clause. | ||
| - */ | ||
| - @Override | ||
| - public Token getStart() { | ||
| - return new Token( String.format( "%s JOIN %s %s ON", | ||
| - getJoinType(), | ||
| - getTableName(), | ||
| - getTableName() ) | ||
| - ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the ending text for an OUTER JOIN clause. | ||
| - */ | ||
| - @Override | ||
| - public Token getStop() { | ||
| - return new Token( | ||
| - String.format( "%s = %s", | ||
| - tableColumn( 0 ).getText(), | ||
| - tableColumn( 1 ).getText() | ||
| - ) | ||
| - ); | ||
| - } | ||
| - | ||
| - private String getTableName() { | ||
| - return table().getText(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the left-hand-side (LHS) table, used for <code>JOIN * ON</code>. | ||
| - * | ||
| - * @return The <code>*</code> value in the aforementioned JOIN. | ||
| - */ | ||
| - protected QueryParser.TableContext table() { | ||
| - return tableColumn( 0 ).table(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the left-hand-side (LHS) or right-hand-side (RHS) table column | ||
| - * context. | ||
| - * | ||
| - * @param i Pass 0 for the LHS, pass 1 for the RHS. | ||
| - * @return The TableColumnContext for the given index. | ||
| - */ | ||
| - protected abstract QueryParser.TableColumnContext tableColumn( int i ); | ||
| -} | ||
| - | ||
| -package com.whitemagicsoftware.rxm.tree.xml; | ||
| - | ||
| -import com.whitemagicsoftware.rxm.grammar.QueryParser; | ||
| -import com.whitemagicsoftware.rxm.tree.Payload; | ||
| -import com.whitemagicsoftware.rxm.tree.Token; | ||
| -import com.whitemagicsoftware.rxm.tree.Tree; | ||
| - | ||
| -import org.antlr.v4.runtime.ParserRuleContext; | ||
| - | ||
| -/** | ||
| - * Transforms <b><code>table.column -> table.column</code></b> into a SQL | ||
| - * <code>OUTER JOIN</code> expression. | ||
| - */ | ||
| -public class OuterMapContext extends JoinMapContext { | ||
| - /** | ||
| - * Default constructor (calls super). | ||
| - * | ||
| - * @param ctx The payload that associates the parser rule context with | ||
| - * the abstract syntax tree. | ||
| - */ | ||
| - public OuterMapContext( Payload ctx ) { | ||
| - super( ctx ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the JOIN qualifier keyword. | ||
| - * | ||
| - * @return "OUTER"; | ||
| - */ | ||
| - @Override | ||
| - public String getJoinType() { | ||
| - return "OUTER"; | ||
| - } | ||
| - | ||
| - @Override | ||
| - protected QueryParser.TableColumnContext tableColumn( int i ) { | ||
| - return ((QueryParser.OuterMapContext)getParserRuleContext()).tableColumn(i); | ||
| - } | ||
| -} | ||
| - | ||
| * Formats the start of the XMLELEMENT call. | ||
| * | ||
| - * @param name The name assigned to the element. | ||
| + * @param ctx The name assigned to the element. | ||
| * | ||
| * @return The text used for SQL/XML XMLELEMENT calls. |
| /** | ||
| */ | ||
| -public class WhereClause { | ||
| - private StringBuilder buffer = new StringBuilder( 2048 ); | ||
| - | ||
| - /** | ||
| - */ | ||
| +public class WhereClause extends Clause { | ||
| public WhereClause() { | ||
| } | ||
| /** | ||
| * Appends "<code>WHERE </code>" to the output. | ||
| * | ||
| * @param ctx The WHERE expression context (unused). | ||
| */ | ||
| public void enterWhere( QueryParser.WhereContext ctx ) { | ||
| - append( "WHERE " ); | ||
| + append( "WHERE" ).append( getNewlineIndent() ); | ||
| } | ||
| /** | ||
| * Appends "<code> AND </code>" to the output. | ||
| * | ||
| * @param ctx The AND expression context (unused). | ||
| */ | ||
| public void exitExprAnd( QueryParser.ExprAndContext ctx ) { | ||
| - append( " AND " ); | ||
| + append( getNewlineIndent() ).append( "AND " ); | ||
| } | ||
| /** | ||
| * Appends "<code> OR </code>" to the output. | ||
| * | ||
| * @param ctx The OR expression context (unused). | ||
| */ | ||
| public void exitExprOr( QueryParser.ExprOrContext ctx ) { | ||
| - append( " OR " ); | ||
| + append( getNewlineIndent() ).append( "OR " ); | ||
| } | ||
| public void enterExprCompRel( QueryParser.ExprCompRelContext ctx ) { | ||
| append( ctx.getText() ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Appends a given string to the buffer. | ||
| - * | ||
| - * @param s The string to append. | ||
| - */ | ||
| - private void append( String s ) { | ||
| - getBuffer().append( s ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the buffer used for building the transformed output. | ||
| - * | ||
| - * @return A non-null string builder, possibly empty. | ||
| - */ | ||
| - private StringBuilder getBuffer() { | ||
| - return this.buffer; | ||
| - } | ||
| - | ||
| - /** | ||
| - * Returns the buffer converted to a string. This is the result of | ||
| - * the transformed output and should only be called when the parsing | ||
| - * of the <b>rxm</b> source is complete. | ||
| - * | ||
| - * @return A non-null string, possibly empty. | ||
| - */ | ||
| - public String toString() { | ||
| - return getBuffer().toString(); | ||
| } | ||
| } | ||
| Delta | 352 lines added, 294 lines removed, 58-line increase |
|---|