Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/rxm.git

Transformation classes now have the ability to review the context tree.

AuthorDave Jarvis <email>
Date2015-03-08 19:51:22 GMT-0700
Commitf90899b8928ca2c478606b3d23bf01770aedde4f
Parentacdc3b4
source/java/com/whitemagicsoftware/rxm/Parser.java
/**
- * Creates a new tree with the given payload.
+ * Creates a new tree with the given context.
*/
- private Tree<Payload> createTree( ParserRuleContext payload ) {
- return new QueryTree<Payload>( new Payload( payload ) );
+ private Tree<Payload> createTree( ParserRuleContext ctx ) {
+ return new QueryTree<Payload>( new Payload( ctx ) );
}
}
source/java/com/whitemagicsoftware/rxm/tree/Payload.java
package com.whitemagicsoftware.rxm.tree;
+import java.lang.reflect.Constructor;
+
import com.whitemagicsoftware.rxm.grammar.QueryParser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
/**
- * The wrapper class for ParserRuleContext. This class uses an implicit
- * factory technique to derive the
+ * <p>
+ * The wrapper class for ParserRuleContext. This class employs an implicit
+ * factory technique to derive the transformation class instances. The
+ * tree associated with this payload is required to determine the context
+ * for each document (output) format-specific Parser Rule.
+ * </p>
+ * <p>
+ * The implicit factory works as follows. The Payload is associated with
+ * a particular instance of Tree. The particular Tree instance is in a
+ * package. The package name includes the factory method for creating the
+ * requisite *Context parser classes. The *Context parser classes are
+ * responsible for producing the correct code (e.g., SQL) to generate the
+ * respective output document.
+ * </p>
+ * By virtue of the Tree being in the package with te *Context classes,
+ * the *Context class names themselves can be derived, and therefore
+ * instantiated. (The *Context class names directly correspond to QueryParser
+ * inner class names and are therefore coupled to the language grammar.)
+ * <p>
*/
public class Payload extends ParserRuleContext {
/** Wrapped parser rule context instance. */
private ParserRuleContext ctx;
+
+ /** Parser rule context instance for transforming the payload. */
+ private ParserRuleContext transformer;
+ /** Abstract Syntax Tree (the factory tree). */
private Tree<Payload> tree;
public Payload( ParserRuleContext ctx ) {
setParserRuleContext( ctx );
}
@Override
public Token getStart() {
- //System.out.println( getTree().getClass().getPackage().getName() );
- //System.out.println( getParserRuleContext().getClass().getSimpleName() );
- return getParserRuleContext().getStart();
+ return getTransformer().getStart();
}
@Override
public Token getStop() {
- return getParserRuleContext().getStop();
+ return getTransformer().getStop();
}
/**
* Allows subclasses to retrieve the payload.
*
* @return The original (unwrapped) payload.
*/
- protected ParserRuleContext getParserRuleContext() {
+ public ParserRuleContext getParserRuleContext() {
return this.ctx;
}
/**
- * Sets the payload.
+ * Sets the payload to the transformation class.
*
* @param ctx The original (unwrapped) payload.
*/
private void setParserRuleContext( ParserRuleContext ctx ) {
this.ctx = ctx;
+ }
+
+ /**
+ * Creates a new instance of the transformer.
+ */
+ private ParserRuleContext createTransformer() {
+ try {
+ return getTransformerConstructor().newInstance( this );
+ }
+ catch( Exception e ) {
+ return getParserRuleContext();
+ }
+ }
+
+ private Constructor<ParserRuleContext> getTransformerConstructor()
+ throws ClassNotFoundException, NoSuchMethodException {
+ return getTransformerClass().getConstructor( Payload.class );
+ }
+
+ /**
+ * Returns the class name of the transformer to instantiate.
+ *
+ * @return A non-null, fully qualified Java class name.
+ */
+ private String getTransformerName() {
+ return String.format( "%s.%s",
+ getTreePackageName(),
+ getParserRuleContextClassName() );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private Class<ParserRuleContext> getTransformerClass()
+ throws ClassNotFoundException {
+ return (Class<ParserRuleContext>)Class.forName( getTransformerName() );
+ }
+
+ /**
+ * Lazily initialize the transformer. This is required because the
+ * transformer isn't known when this payload is instantiated. Technically,
+ * the transformer could be assigned when the tree is set, but lazy
+ * initialization is cleaner. (That is, no instantiation happens until
+ * the object is needed.)
+ */
+ private ParserRuleContext getTransformer() {
+ ParserRuleContext transformer = this.transformer;
+
+ if( transformer == null ) {
+ setTransformer( transformer = createTransformer() );
+ }
+
+ return transformer;
+ }
+
+ private void setTransformer( ParserRuleContext ctx ) {
+ this.transformer = ctx;
}
public void setTree( Tree<Payload> tree ) {
this.tree = tree;
}
public Tree<Payload> getTree() {
return this.tree;
+ }
+
+ private Class getTreeClass() {
+ return getTree().getClass();
+ }
+
+ private Package getTreePackage() {
+ return getTreeClass().getPackage();
+ }
+
+ private String getTreePackageName() {
+ return getTreePackage().getName();
+ }
+
+ private Class getParserRuleContextClass() {
+ return getParserRuleContext().getClass();
+ }
+
+ private String getParserRuleContextClassName() {
+ return getParserRuleContextClass().getSimpleName();
}
}
source/java/com/whitemagicsoftware/rxm/tree/Tree.java
Tree<T> root = this;
- // Traverse until there are no more parents.
+ // Traverse until there are no more parents, which should be the root.
while( root.getParent() != null ) {
root = root.getParent();
source/java/com/whitemagicsoftware/rxm/tree/xml/ASTParserRuleContext.java
-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;
-
-/**
- * Represents a wrapper class for ParserRuleContext. This class is marked
- * as abstract because only its subclasses should be instantiated.
- */
-public abstract class ASTParserRuleContext {
- private ParserRuleContext payload;
- private Tree<Payload> tree;
-
- protected ASTParserRuleContext( Payload payload ) {
- this.payload = payload;
- this.tree = payload.getTree();
- }
-
- protected ParserRuleContext getParserRuleContext() {
- return this.payload;
- }
-
- /**
- * 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 );
- }
-
- /**
- * Formats the start of the XMLATTRIBUTES call.
- *
- * @param name The name assigned to the attribute.
- *
- * @return The text used for SQL/XML XMLATTRIBUTES calls.
- */
- protected String startAttributes( String name ) {
- return String.format( "XMLATTRIBUTES( %s AS ", name );
- }
-
- protected Tree<Payload> getTree() {
- return this.tree;
- }
-
- /**
- * Closes the current payload transformation.
- */
- public Token getStart() {
- return new Token( "(" );
- }
-
- /**
- * Closes the current payload transformation.
- */
- public Token getStop() {
- return new Token( ")" );
- }
-}
-
source/java/com/whitemagicsoftware/rxm/tree/xml/AttributeMapContext.java
* Transforms <code>table &gt; @attribute</code>.
*/
-public class AttributeMapContext extends ASTParserRuleContext {
+public class AttributeMapContext extends PayloadParserRuleContext {
public AttributeMapContext( Payload ctx ) {
super( ctx );
source/java/com/whitemagicsoftware/rxm/tree/xml/ColumnMapContext.java
* Transforms <code>column &gt; path</code>.
*/
-public class ColumnMapContext extends ASTParserRuleContext {
+public class ColumnMapContext extends PayloadParserRuleContext {
public ColumnMapContext( Payload ctx ) {
super( ctx );
source/java/com/whitemagicsoftware/rxm/tree/xml/PayloadParserRuleContext.java
+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;
+
+/**
+ * Represents a wrapper class for ParserRuleContext. This class is marked
+ * as abstract because only its subclasses should be instantiated.
+ */
+public abstract class PayloadParserRuleContext extends ParserRuleContext {
+ private ParserRuleContext payload;
+ private Tree<Payload> tree;
+
+ protected PayloadParserRuleContext( Payload payload ) {
+ this.payload = payload.getParserRuleContext();
+ this.tree = payload.getTree();
+ }
+
+ protected ParserRuleContext getParserRuleContext() {
+ return this.payload;
+ }
+
+ /**
+ * 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 );
+ }
+
+ /**
+ * Formats the start of the XMLATTRIBUTES call.
+ *
+ * @param name The name assigned to the attribute.
+ *
+ * @return The text used for SQL/XML XMLATTRIBUTES calls.
+ */
+ protected String startAttributes( String name ) {
+ return String.format( "XMLATTRIBUTES( %s AS ", name );
+ }
+
+ /**
+ * Returns the context tree that provides subclasses the ability to
+ * determine their database entity context. This allows subclasses
+ * to use the correct entity alias as defined by the <b>rxm</b>.
+ */
+ protected Tree<Payload> getTree() {
+ return this.tree;
+ }
+
+ /**
+ * Closes the current payload transformation. Subclasses must override
+ * this to provide the correct opening SQL/XML expression.
+ */
+ @Override
+ public Token getStart() {
+ return new Token( "(" );
+ }
+
+ /**
+ * Closes the current payload transformation. Subclasses may override
+ * this to provide a custom closing SQL/XML expression.
+ */
+ @Override
+ public Token getStop() {
+ return new Token( ")" );
+ }
+}
+
source/java/com/whitemagicsoftware/rxm/tree/xml/RootContext.java
* Transforms <code>root &gt; element</code>.
*/
-public class RootContext extends ASTParserRuleContext {
+public class RootContext extends PayloadParserRuleContext {
public RootContext( Payload ctx ) {
super( ctx );
source/java/com/whitemagicsoftware/rxm/tree/xml/TableMapContext.java
* Transforms <code>table &gt; path</code>.
*/
-public class TableMapContext extends ASTParserRuleContext {
+public class TableMapContext extends PayloadParserRuleContext {
public TableMapContext( Payload ctx ) {
super( ctx );
Delta188 lines added, 83 lines removed, 105-line increase