Friday, November 28, 2014

The Commented Source

Team. commenting the source took me exactly one-hour. Remember. I use the bird foraging approach when working on a computer. Hunt-Peck-Think. It works fairly well although I found a few typos in the meager source comments which I had already provided.

I hope you enjoyed your Thanksgiving. If you get a chance consider doing some community service over the holidays. It can be very rewarding. We should be more than one dimensional as software engineers and have a social conscience. Remember, "there but for the Grace of God go I", the next time you see someone pushing all of their possessions in a shopping cart. This world is not always fair and just.

The source is below. So Have a Great Weekend. It is great working with you. La-La.

//BEGIN JAVA SOURCE
//CONTROLLER APPLICATION BUNDLE (CAB)
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cab;
/**
 * The CAB eventually will be the kernel of the CABOOSE general purpose servlet.
 * Implicit Contract Requirements and Guidelines:
 * The CAB contracts with support classes that have rendering methods which
 * return String content. These methods also must have the signature
 *  public String methodName( java.util.HashMap<String,String> aMapParameter )
 * by implicit contract. If they do not, the reflection activities which
 * automatically invoke them will fail since they cannot find the requested
 * method. Class, method, tile replacement, and stencil filename identifiers are
 * all stored in a file called directory.xml which contain a mapping between
 * each item.
 *
 * @author Jody Sharpe
 */
public class CAB {
    //Simulated URL String. We will eventually get all of our input from the
    //the servlet's Request object.
    String request = "?project=caboose&module=skeleton&create_date=10.30.2014";
    //A data structure for holding a description of the page, stencil, and tile
    //directory. It is keyed by the page name. Each value in the structure is a
    //ViewModel. See the description of this inner class for information on its
    //content and structure.
    java.util.HashMap<String,ViewModel> aDirectoryMap = null;
   
    //private inner class representing a model of a single view which the
    //controller can return.
    private class ViewModel {
        //The stencil filename.
        private String theStencilName = null;
        //A data structure which holds the tile identifier as a key and the name
        //of the class and method for rendering the the tile as a
        //comma seperated value
        private java.util.HashMap<String,String> theTileRendererMappings = null;
       
        //This method assigns the stencil filename
        void settingTheStencilName( String aStencilName ){
            theStencilName = aStencilName;           
        }
       
        //This method assigns the tile renderer mappings
        void settingTheTileRendererMappings( java.util.HashMap<String,String> aSetOfTileRendererMappings ){
            theTileRendererMappings = aSetOfTileRendererMappings;           
        }
       
        //This method returns the stencil file name
        String gettingTheStencilName(){
            return( theStencilName );           
        }
       
        //This method retruns the tile renderer mappings data structure
        java.util.HashMap<String,String> gettingTheTileRendererMappings(){
            return( theTileRendererMappings );           
        }
    }
   
    //This method extracts the content of a stencil from the file system based
    //upon a file name. In the future this method will need adapting so it
    //retrieves the proper file in a web server's file system using
    //the servlet context.
    String gettingTheResponseStencil(String aViewFileName) throws Exception {
        java.io.BufferedReader aStencilReader = new java.io.BufferedReader(new java.io.FileReader(aViewFileName));
        String theStencilContent = "", theNextLine = null;
        while ((theNextLine = aStencilReader.readLine()) != null) {
            theStencilContent += theNextLine;
        }
        return (theStencilContent);
    }
    //This method extracts the name and value pairs from the input query string.
    //We assume that it is not url encoded. For the generic servlet edition of
    //the cab, this method will not be useful. But it might be of use for a
    //command-line based edition of the cab for report writing or rendering
    //windowing applications.
    java.util.HashMap<String, String> mappingTheRequestNameValuePairs(String aRequest) {
        java.util.HashMap<String, String> aMap = new java.util.HashMap<String, String>();
        aRequest = aRequest.replace("?", "");
        String[] theNameValuePairs = aRequest.split("&");
        for (String aNameValuePair : theNameValuePairs) {
            final int theName = 0, theValue = 1;
            String[] aTuple = aNameValuePair.split("=");
            aMap.put(aTuple[theName], aTuple[theValue]);
        }
        return aMap;
    }
    //This model populates a view stencil with the content generated by
    //dynamically invoking reendering methods and replacing their associated
    //user-defined tile identifiers ( a.k.a stencil replacement variables ).
    //See the contract guideline in the header comments of this document.
    String preparingTheResponse(String theViewId, java.util.HashMap<String, String> aRequestMap) throws Exception {
       
        ViewModel aViewModel = (ViewModel) aDirectoryMap.get( theViewId );
        if ( aViewModel == null ) throw new Exception("View Model Not Found");
       
        String [] aTileClassAndMethod = null;       
       
        String theStencilContent = gettingTheResponseStencil( aViewModel.gettingTheStencilName() );
        java.util.HashMap<String,String> someTileRenderMappings = aViewModel.gettingTheTileRendererMappings();
       
        for( String aTileId : someTileRenderMappings.keySet()){       
           
            aTileClassAndMethod = ((String)someTileRenderMappings.get( aTileId )).split(",");                                   
           
            //Start Reflection Activities
            Class aClass = Class.forName( aTileClassAndMethod[0] );
            Class [] theFullyQualifiedParameterTypeClasses = new Class[1];
            theFullyQualifiedParameterTypeClasses[0] = (new java.util.HashMap<String,String>()).getClass();
            Object [] theParameterObjectList= new Object [1];                                   
            theParameterObjectList[0] = aRequestMap;
            theStencilContent = theStencilContent.replace( aTileId , (String) ( aClass.getMethod(aTileClassAndMethod[1],theFullyQualifiedParameterTypeClasses) ).invoke((aClass.getConstructor()).newInstance(), theParameterObjectList)); 
            //End Reflection Activities                        
           
        }
       
        return (theStencilContent);
    }
    //This model extracts the information from the directory.xml file using an
    //XML reader that creates a DOM from which the method creates a user-defined
    //map between view names and ViewModel objects. In the future, we might
    //utilize a SAX XML reader skipping the creation of the DOM and directly
    //create the ViewModel map data structure. This should result in a slight
    //processing speed up although we will only be during it once during a servlet
    //session and storing the utlimate view model map in the servlet's session
    //object. Directoy.xml represents a model mapping for the entire application.
    //Based upon the length of this method ( 50+ lines of code ) it should
    //likely be subdivided and invoke a few private utility methods for
    //completing its work.
    void readingTheDirectoryXMLFile(String theViewId) throws Exception {
              
        String aViewId = null;
        String aStencil = null;
        String aTileId = null;
        String aTileClass = null;
        String aTileMethod = null;
       
        aDirectoryMap = new java.util.HashMap<String, ViewModel>();
       
        javax.xml.parsers.DocumentBuilderFactory theDocumentBuilderFactory =
                javax.xml.parsers.DocumentBuilderFactory.newInstance();
        javax.xml.parsers.DocumentBuilder theDocumentBuilder = theDocumentBuilderFactory.newDocumentBuilder();
        java.io.File aFile = new java.io.File("./src/cab/directory.xml");
        org.w3c.dom.Document theDocument = theDocumentBuilder.parse(aFile);
        theDocument.getDocumentElement().normalize();
        org.w3c.dom.NodeList theModelNodeList = theDocument.getElementsByTagName("model");
        for (int aModelNodeIndex = 0; aModelNodeIndex < theModelNodeList.getLength(); aModelNodeIndex++) {
            org.w3c.dom.Node aModelNode = theModelNodeList.item(aModelNodeIndex);
            if (aModelNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                org.w3c.dom.Element aModelElement = (org.w3c.dom.Element) aModelNode;
                org.w3c.dom.NodeList theViewNodeList =
                        aModelElement.getElementsByTagName("view");
                for (int aViewNodeIndex = 0; aViewNodeIndex < theViewNodeList.getLength(); aViewNodeIndex++) {
                    org.w3c.dom.Node aViewNode = (org.w3c.dom.Node) theViewNodeList.item(aViewNodeIndex);
                    if (aViewNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                        org.w3c.dom.Element aViewElement = (org.w3c.dom.Element) aViewNode;
                        ViewModel aViewModel = new ViewModel();
                       
                        aViewId = aViewElement.getAttribute("id");
                       
                        aStencil = aViewElement.getAttribute("stencil");
                       
                        aViewModel.settingTheStencilName(aStencil);
                        java.util.HashMap<String,String> someTileRendererMappings = new java.util.HashMap<String,String>();
                        org.w3c.dom.NodeList theTileNodeList = aViewElement.getElementsByTagName("tile");
                            for (int aTileNodeIndex = 0; aTileNodeIndex < theTileNodeList.getLength(); aTileNodeIndex++) {
                               
                                org.w3c.dom.Node aTileNode = (org.w3c.dom.Node) theTileNodeList.item(aTileNodeIndex);
                                if (aTileNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                                    org.w3c.dom.Element aTileElement = (org.w3c.dom.Element) aTileNode;
                                   
                                    aTileId = aTileElement.getAttribute("id");
                                    aTileClass = aTileElement.getAttribute("class");
                                    aTileMethod = aTileElement.getAttribute("method");
                                   
                                    someTileRendererMappings.put( aTileId, aTileClass + "," + aTileMethod );
                                   
                                }
                               
                            }            
                            aViewModel.settingTheTileRendererMappings(someTileRendererMappings);
                                aDirectoryMap.put(aViewId, aViewModel);
                           
                    }
                }
            }
        }  
    }
    /**
     * @param args the command line arguments
     * This is the main entry point of the application. It builds the request
     * map from the the "temporary" query string. It then build the view model
     * mappings from the directory.xml file by side-effect. Finally it prepares
     * and presents a response. All in less than 0.5 KLOC including
     * the comments. The number of lines of code are not critical in application.
     * The features it provides in the lines it has is most important.
     */
    public static void main(String[] args) {
        // TODO code application logic here
        CAB aCAB = new CAB();
        java.util.HashMap<String, String> aRequestMap = aCAB.mappingTheRequestNameValuePairs(aCAB.request);
        try {
            aCAB.readingTheDirectoryXMLFile("test_page");
            System.out.println(aCAB.preparingTheResponse("test_page", aRequestMap));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//STENCIL HANDLER
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cab;
/**
 * An example stencil handler class. For each unique instance of a CABOOSE
 * application, these will be user defined.
 * @author Jody Sharpe
 */
public class StencilHandler {
   
    //Renderer for supplying content about the create date
    public String createDateRenderer( java.util.HashMap<String,String> aRequestMap){
        return( aRequestMap.get("create_date") ); 
    }
    //Renderer for supplying content about the module
    public String moduleRenderer( java.util.HashMap<String,String> aRequestMap){
        return( aRequestMap.get("module") ); 
    }
    //Renderer for supplying content about the project
    public String projectRenderer( java.util.HashMap<String,String> aRequestMap){
        return( aRequestMap.get("project") ); 
    }
}
//END JAVA SOURCE
//BEGIN XHTML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>CABOOSE Embryo</title>
    </head>
    <body>
        <!--
        I chose that my tile replacement identifiers would
        follow the pattern #ALL_CAPS_JAVA_IDENTIFIER#. This
        is only a convention and not strictly enforced by the
        cab. Obviously, the string used should not collide with
        any other one that might be found in a markup document.
        -->
        <p>#PROJECT#</p>
        <p>#MODULE#</p>
        <p>#CREATE_DATE#</p>
    </body>
</html>
//END XHTML
//BEGIN XML
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
the model is for the entire application. one view associates
with one page of markup. As attributes this element has an id and a stencil
which is a the filename of the markup. Each view has zero or more replacement
tile child elements associated with it. The tile id attribute appears in the
markup and will be replaced by the String content rendered by the method
uniquely described by the class and method attributes of the tile element.
-->
<model>   
 <view id="test_page" stencil="./src/cab/xstencil.xhtml">
            <tile id="#PROJECT#" class="cab.StencilHandler" method="projectRenderer"/>
            <tile id="#MODULE#" class="cab.StencilHandler" method="moduleRenderer"/>
            <tile id="#CREATE_DATE#" class="cab.StencilHandler" method="createDateRenderer"/>
 </view>
</model>
//END XML

No comments:

Post a Comment