| */ | ||
| protected String toString( Tree<T> tree, int depth ) { | ||
| - StringBuilder sb = new StringBuilder( indent( depth ) ); | ||
| + StringBuilder sb = new StringBuilder( 2048 ); | ||
| + String indent = "", newline = ""; | ||
| - sb.append( start( tree ) ); | ||
| + if( beautify() ) { | ||
| + indent = indent( depth ); | ||
| + newline = System.lineSeparator(); | ||
| + } | ||
| - for( Tree<T> branch : tree.getBranches() ) { | ||
| - sb.append( System.lineSeparator() ); | ||
| + sb.append( indent ).append( start( tree ) ); | ||
| + for( Tree<T> branch : tree.getBranches() ) { | ||
| // Recurse for all the branches at this level of the tree. | ||
| - sb.append( toString( branch, depth + getIndent() ) ); | ||
| + sb.append( newline ).append( toString( branch, depth + getIndent() ) ); | ||
| } | ||
| - sb.append( System.lineSeparator() ).append( indent( depth ) ); | ||
| + sb.append( newline ).append( indent ); | ||
| return sb.append( stop( tree ) ).toString(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Answers whether the transformed query should be | ||
| + * indented with newlines. | ||
| + */ | ||
| + protected boolean beautify() { | ||
| + return true; | ||
| } | ||
| return new Token( | ||
| String.format( ",%s", hasPrecedingPayload() ? | ||
| - nextAttribute( getTableName(), getColumnName(), getAttributeName() ) : | ||
| - firstAttribute( getTableName(), getColumnName(), getAttributeName() ) | ||
| + nextAttribute( getParentTableText(), getColumnText(), getAttributeText() ) : | ||
| + firstAttribute( getParentTableText(), getColumnText(), getAttributeText() ) | ||
| ) | ||
| ); | ||
| } | ||
| - private String getAttributeName() { | ||
| + private String getAttributeText() { | ||
| return attribute().getChild(1).getText(); | ||
| } | ||
| */ | ||
| private String firstAttribute( String table, String column, String node ) { | ||
| - return "XMLATTRIBUTES( " + nextAttribute( table, column, node ); | ||
| + return "XMLATTRIBUTES(" + nextAttribute( table, column, node ); | ||
| } | ||
| */ | ||
| public class ColumnMapContext extends PayloadParserRuleContext { | ||
| + /** | ||
| + * Default constructor (calls super). | ||
| + * | ||
| + * @param ctx The payload that associates the parser rule context with | ||
| + * the abstract syntax tree. | ||
| + */ | ||
| public ColumnMapContext( Payload ctx ) { | ||
| super( ctx ); | ||
| @Override | ||
| public Token getStart() { | ||
| - QueryParser.PathContext path = getPathContext(); | ||
| - String e = path.getText(); | ||
| - | ||
| - String s = String.format( ",%s, %s", startElement( e ), getColumnName() ); | ||
| - return new Token( s ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * This will return column name without the leading period. | ||
| - * | ||
| - * @return The column name, without a leading period. | ||
| - */ | ||
| - protected String getColumnName() { | ||
| - // The first child (index 0) is the leading period. | ||
| - // The second child (index 1) is the column name. | ||
| - return getColumnContext().getChild(1).getText(); | ||
| + return new Token( | ||
| + String.format( ",%s,%s.%s", | ||
| + startElement( getPathText() ), | ||
| + getParentTableText(), | ||
| + getColumnText() | ||
| + ) | ||
| + ); | ||
| } | ||
| /** | ||
| - * Casts the payload into the proper context, then extracts the path. | ||
| + * Returns the path from the column map context, rather than using | ||
| + * the superclass's table map context. | ||
| * | ||
| * @return The path associated with the column map parser rule. | ||
| - */ | ||
| - protected QueryParser.PathContext getPathContext() { | ||
| - return ((QueryParser.ColumnMapContext)getParserRuleContext()).path(); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Casts the payload into the proper context, then extracts the column. | ||
| - * | ||
| - * @return The column associated with the column map parser rule. | ||
| */ | ||
| - protected QueryParser.ColumnContext getColumnContext() { | ||
| - return ((QueryParser.ColumnMapContext)getParserRuleContext()).column(); | ||
| + protected QueryParser.PathContext path() { | ||
| + return getColumnMapContext().path(); | ||
| } | ||
| } | ||
| - | ||
| /** | ||
| + * Formats the start of the XMLELEMENT call. | ||
| + * | ||
| + * @param name The name assigned to the element. | ||
| + * | ||
| + * @return The text used for SQL/XML XMLELEMENT calls. | ||
| + */ | ||
| + protected String startElement( String name ) { | ||
| + return String.format( "XMLELEMENT(NAME \"%s\"", name ); | ||
| + } | ||
| + | ||
| + /** | ||
| * Answers whether the current payload has an antecedent sibling. | ||
| * | ||
| /** | ||
| - * Returns column name without the preceding period. | ||
| - * | ||
| - * @return The column name. | ||
| + * This will return column name without the preceding period. | ||
| + * | ||
| + * @return The column name, without a leading period. | ||
| */ | ||
| - protected String getColumnName() { | ||
| + protected String getColumnText() { | ||
| + // The first child (index 0) is the leading period. | ||
| + // The second child (index 1) is the column name. | ||
| return column().getChild(1).getText(); | ||
| } | ||
| /** | ||
| - * Returns nearest, contextual table name. | ||
| + * Returns the path text, which includes any slashes that separate | ||
| + * the XPath-like path elements. | ||
| * | ||
| - * @return The table name that precedes the column name. | ||
| + * @return A non-null string. | ||
| */ | ||
| - protected String getTableName() { | ||
| - return table().getText(); | ||
| + protected String getPathText() { | ||
| + return path().getText(); | ||
| } | ||
| /** | ||
| - * Returns the table instance for the table map context. | ||
| + * Returns nearest, contextual table name. | ||
| + * | ||
| + * @return The table name that precedes the column name. | ||
| */ | ||
| - protected QueryParser.TableContext table() { | ||
| - return getTableMapContext().table(); | ||
| + protected String getParentTableText() { | ||
| + return parentTable().getText(); | ||
| } | ||
| /** | ||
| - * Implemented by subclasses to return the column context. | ||
| - * An alternative is to revise the grammar to have a common | ||
| - * BNF definition that defines both a table map and a column | ||
| - * map. | ||
| + * Returns the column name, if any. This should not be called | ||
| + * if the parser rule context doesn't know about columns. | ||
| * | ||
| - * @return null by default. | ||
| + * @return A column instance, but could throw a class cast exception. | ||
| */ | ||
| protected QueryParser.ColumnContext column() { | ||
| - return null; | ||
| + return getColumnMapContext().column(); | ||
| } | ||
| /** | ||
| - * Formats the start of the XMLELEMENT call. | ||
| - * | ||
| - * @param name The name assigned to the element. | ||
| + * Casts the payload into the proper context, then extracts the path. | ||
| * | ||
| - * @return The text used for SQL/XML XMLELEMENT calls. | ||
| + * @return The path associated with the table map parser rule. | ||
| */ | ||
| - protected String startElement( String name ) { | ||
| - return String.format( "XMLELEMENT( NAME \"%s\"", name ); | ||
| + protected QueryParser.PathContext path() { | ||
| + return getTableMapContext().path(); | ||
| } | ||
| /** | ||
| - * Returns the current payload. | ||
| + * Returns the table instance for the table map context. | ||
| + */ | ||
| + protected QueryParser.TableContext parentTable() { | ||
| + return getParentTableMapContext().table(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Casts the payload into the proper context, then extracts the column. | ||
| * | ||
| - * @return The payload containing tokens parsed from the input <b>rxm</b> | ||
| - * document. | ||
| + * @return The column associated with the column map parser rule. | ||
| */ | ||
| - protected ParserRuleContext getParserRuleContext() { | ||
| - return getInitPayload().getParserRuleContext(); | ||
| + protected QueryParser.ColumnMapContext getColumnMapContext() { | ||
| + return (QueryParser.ColumnMapContext)getParserRuleContext(); | ||
| } | ||
| /** | ||
| * Returns the nearest table context to this parser rule context. | ||
| */ | ||
| - protected QueryParser.TableMapContext getTableMapContext() { | ||
| + protected QueryParser.TableMapContext getParentTableMapContext() { | ||
| return (QueryParser.TableMapContext)getTreePayload().getParserRuleContext(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the nearest table context to this parser rule context. | ||
| + */ | ||
| + protected QueryParser.TableMapContext getTableMapContext() { | ||
| + return (QueryParser.TableMapContext)getParserRuleContext(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the current payload. | ||
| + * | ||
| + * @return The payload containing tokens parsed from the input <b>rxm</b> | ||
| + * document. | ||
| + */ | ||
| + protected ParserRuleContext getParserRuleContext() { | ||
| + return getInitPayload().getParserRuleContext(); | ||
| } | ||
| } | ||
| - |
| @Override | ||
| public Token getStart() { | ||
| - QueryParser.PathContext path = getPathContext(); | ||
| - String e = path.getText(); | ||
| - | ||
| - String s = String.format( ",%s", startElement( e ) ); | ||
| - return new Token( s ); | ||
| - } | ||
| - | ||
| - /** | ||
| - * Casts the payload into the proper context, then extracts the path. | ||
| - * | ||
| - * @return The path associated with the table map parser rule. | ||
| - */ | ||
| - protected QueryParser.PathContext getPathContext() { | ||
| - return ((QueryParser.TableMapContext)getParserRuleContext()).path(); | ||
| + return new Token( String.format( ",%s", startElement( getPathText() ) ) ); | ||
| } | ||
| } | ||
| - | ||
| Author | Dave Jarvis <email> |
|---|---|
| Date | 2015-03-13 12:00:57 GMT-0700 |
| Commit | a7910c48f9100e1ab27b9e3e8cb33f9a713e376a |
| Parent | cc3c770 |
| Delta | 104 lines added, 84 lines removed, 20-line increase |