Tuesday, December 30, 2014

Consider a Few Issues with the Prototype

Team. There are a few issues in the servlet source which we should address.

Firstly, the directory.xml map of view model objects should only be created once and placed in the session object. So, the expensive method calls for building the document object model will only occur once. Also, the DOM eventually will be garbage collected since the references to it will stop existing after the directory.xml reading method.

Secondly, the exception message should be removed from the session object after it has been read in the exception handler method. There also might be some more issues. Any comments would be greatly appreciated.

Thirdly, the Hibernate transaction which we use is extremely simple. We should also create more complex examples that represent inner and outer joins with complex criterions plus Hibernate Query Language (HQL) functions such as count, sum, or avergage. This will likely occur after completing the prototype during the first iteration of development.

Fourthly, we should create other sample extensions for connecting with RESTful webservices and using SOAP messaging with the prototype.

Fifthly, we should also create some samples which do not use object-relational mapping for database transactions and rely soley on JDBC and ANSI SQL. These examples and with the Hibernate examples should use each of the Create, Read, Update, and Delete (CRUD) operations common in database application programming.

Sixthly, we also should consider using the redirect and forward features of the response object with JSP pages. Most likely, we will simply allow the rendering method writer the option of calling these methods from the response object. This only should discard any content which the servlet was building without causing a significant disruption in the application.

Seventhly and finally, we will review the source for an outstanding issues not mentioned above.

Plan. Plan. Plan. We had a tentative project plan for the prototype which we should follow. Let us review that over the next couple of days and see how we can incorporate some of these goals in the final few weeks of the plan.

The prototype must be complete in a few weeks and the source available on http://java.net/projects/caboose. A tentative presentation on CABOOSE is scheduled for a JAVA User's Group (JUG) in January or February. It should be fun and a source of valuable feedback.

This project, thus far, has been enjoyable. If not widely adopted, the author will at least have a base of reusable software for future development as a professional engineer. Servlet creation with CABOOSE might also benefit from the automatic code generation found in popular integrated development environments such as NetBeans. Given the directory.xml file, one has all the information needed for producing stencil handling classes with rendering method stubs.

These stubs all have the same signature:

String methodName( HttpServletRequestWrapper,HttpServletResponseWrapper ) throws Exception.
This would greatly speed up development and reduce the introduction of errors. However, this is a long term goal.

Also, recreating the Struts or Spring MVC is not our design goal. We seek a greater simplicity and further reading on each of these should be done. Feedback from anyone with extensive knowledge of both of these MVC would be appreciated. Also, we hopefully are not simply complicating a set of features already found in JAVA Server Pages and Faces. From my experience teaching servlet and JSP technology, CABOOSE will simplify and speed development. 

Certainly, you are still sorting through the source code posted from 12.29.2014. You will not be overburdened with a long message today. Happy Coding. La-La.

Monday, December 29, 2014

New Prototype Source as a Servlet with Hibernate Transaction in NetBeans

Team. This will be a longer note. There have been a number of changes in the source since it was last posted. If you plan on rebuilding these files, getting the NetBeans Integrated Development Environment (IDE) would be wise. It can be found at www.netbeans.org and is "free-of-charge". The steps for building the CABOOSE project in its current state is as follows:

A. Creating Derby Database

0. All identifiers in quotes are case-sensitive.
1. Create a JDBC Derby database called "caboose" under the Services Navigator tab of NetBeans. This will serve asasourceof information which we can extract with Hibernate Object-Relational Mapping (ORM) modules.
2. The username and password for your database should be "root" and "root", respectively.
3. Create a table in your database called "CABOOSE".
4. Within this table create the fields "ID" of type Integer and "MESSAGE" of type VARCHAR with a maximum length of 256.
5. Run the an SQL Script which creates a record with an ID of 100 and the MESSAGE that "Hibernate is a friend of CABOOSE".

B. Creating the CABOOSE Web Application

0. Use the Netbeans IDE helper application to create a new web application called "CABOOSE"
1. Place directory.xml in the WEB-INF directory
2. Create a folder called "model" for holding the stencil models of each view.
3. Place exception.xhtml and xstencil.xhtml in the "model" directory of the "WEB-INF" folder
4. Replace the content of the "index.html" file generated by the inline source for index.html.
5. Create a servlet called "CAB.java" in the net.java.CABOOSE package. It URL pattern should be "/CAB"

C. Creating JAVA packages

0. Create the folowing packages
    0.1 [DEFAULT] Given
    0.2 net.java.CABOOSE
    0.3 net.java.CABOOSE.Hibernate
    0.4 org.sharpe.sample
1. Populate the packages with the appropriate source based upon the package statement at the beginning of each module.
2. Place hibernate.cfg.xml in the default package
3. Place hibernate.reveng.xml in the net.java.CABOOSE.Hibernate package
4. Place Caboose.hbm.xml in the net.java.CABOOSE.Hibernate package

Note: Much of the code for Hibernate processing was automatically generated by the Netbeans IDE. If you like you can repeat these steps. There are tutorials at Netbeans and other web sources on creating Hibernate transactions, plus it is almost self-explanatory.

This should be all of the instructions needed for recreating the project in NetBeans. The source is below. Once we complete the prototype with all of its sample extensions for common technologies, we will place it in the repository. La-La.

//BEGINNING OF SOURCE FILES
//exception.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>CABOOSE Exception</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body>
        <div>CABOOSE Exception</div>
        <!--
        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>#EXCEPTION_MESSAGE#</p>
    </body>
</html>
//xstencil.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>CABOOSE Standard Stencil</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </head>
    <body>
        <div>CABOOSE Standard Stencil</div>
        <!--
        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>
        <p>#HIBERNATE_MESSAGE#</p>
    </body>
</html>
//index.html
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
    <head>
        <title>CABOOSE|Controller Application Bundles for Object-Oriented Software Engineering</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>CABOOSE Splash Page</div>
        <form action="/CABOOSE/CAB" method="POST">
            <input type="hidden" name="create_date" value="10.30.2014"/>
            <input type="hidden" name="module" value="StencilHandler"/>
            <input type="hidden" name="project" value="Caboose"/>
            <input type="submit" value="Run CABOOSE"/>
        </form>
    </body>
</html>
//directory.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, 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="/WEB-INF/model/xstencil.xhtml">
            <tile id="#PROJECT#" class="org.sharpe.sample.StencilHandler" method="projectRenderer"/>
            <tile id="#MODULE#" class="org.sharpe.sample.StencilHandler" method="moduleRenderer"/>
            <tile id="#CREATE_DATE#" class="org.sharpe.sample.StencilHandler" method="createDateRenderer"/>  
            <tile id="#HIBERNATE_MESSAGE#" class="org.sharpe.sample.StencilHandler" method="hibernateMessageRenderer"/>
        </view>
        <view id="exception" stencil="/WEB-INF/model/exception.xhtml">
            <tile id="#EXCEPTION_MESSAGE#" class="org.sharpe.sample.StencilHandler" method="exceptionRenderer"/>
 </view>
</model>
//hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
    <property name="hibernate.connection.url">jdbc:derby://localhost:1527/caboose</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <mapping class="" file="" jar="" package="" resource="net/java/CABOOSE/Hibernate/Caboose.hbm.xml"/>
  </session-factory>
</hibernate-configuration>
//Caboose.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Dec 28, 2014 1:19:10 AM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
    <class name="net.java.CABOOSE.Hibernate.Caboose" table="CABOOSE" schema="ROOT" optimistic-lock="version">
        <id name="id" type="int">
            <column name="ID"/>
            <generator class="assigned" />
        </id>
        <property name="message" type="string">
            <column name="MESSAGE" length="256"/>
        </property>
    </class>
</hibernate-mapping>
//hibernate.reveng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
  <schema-selection match-schema="ROOT"/>
  <table-filter match-name="CABOOSE"/>
</hibernate-reverse-engineering>
//CAB.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.java.CABOOSE;
/**
 *
 * @author Jody
 */
@javax.servlet.annotation.WebServlet(name = "CAB", urlPatterns = {"/CAB"})
public class CAB extends javax.servlet.http.HttpServlet implements SystemExceptions {
    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
            throws javax.servlet.ServletException, java.io.IOException {
        response.setContentType("text/html;charset=UTF-8");
        java.io.PrintWriter out = response.getWriter();
        javax.servlet.ServletContext theServletContext = this.getServletContext();
        Kernel aCAB = new Kernel();       
        javax.servlet.http.HttpServletRequestWrapper aRequestWrapper = new javax.servlet.http.HttpServletRequestWrapper( request );
        javax.servlet.http.HttpServletResponseWrapper aResponseWrapper = new javax.servlet.http.HttpServletResponseWrapper( response );
        try {          
            aCAB.populatingTheDirectoryMap(theServletContext);
            //throw new Exception("Testing CABOOSE Exceptions");
            out.println(aCAB.preparingTheSuccessfulResponse("test_page",theServletContext, aRequestWrapper, aResponseWrapper));
        } catch (Exception e) {
           
            ((javax.servlet.http.HttpSession) aRequestWrapper.getSession()).setAttribute(EXCEPTION_KEY,e.getMessage());
            out.println(aCAB.preparingTheExceptionResponse(theServletContext, aRequestWrapper, aResponseWrapper));
            e.printStackTrace(out);
        }       
    }
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
            throws javax.servlet.ServletException, java.io.IOException {
        processRequest(request, response);
    }
    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
            throws javax.servlet.ServletException, java.io.IOException {
        processRequest(request, response);
    }
    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "CABOOSE General-Purpose Servlet";
    }// </editor-fold>
}
//Kernel.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.java.CABOOSE;
/**
 * The CAB is 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 contains a mapping between each item.
 * @author Jody
 */
public class Kernel implements SystemExceptions, SystemStandards {
   
    //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 theStencilFileName = 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 settingTheStencilFileName(String aStencilFileName) throws Exception {
            //Opening Contract
            //The stencil name is not a null or empty string.           
            if (aStencilFileName == null || aStencilFileName.length() == 0) {
                throw new Exception(STENCIL_FILE_NAME_ERROR);
            }
            theStencilFileName = aStencilFileName;
            //Closing Contract (Implicit)
            //The stencil name is a non-empty string.
        }
        //This method assigns the tile renderer mappings
        void settingTheTileRendererMappings(java.util.HashMap<String, String> aSetOfTileRendererMappings) throws Exception {
            //Opening Contract
            //The set of mappings between tiles and renderer methods is not null
            //It might be of size zero if there does not exist any replacment tiles
            //within the stencil.
            if (aSetOfTileRendererMappings == null) {
                throw new Exception(TILE_RENDERER_MAPPINGS_ERROR);
            }
            theTileRendererMappings = aSetOfTileRendererMappings;
            //Closing Contract (Implicit)
            //The tile renderer mappings is not null. They might be empty.
        }
        //This method returns the stencil file name
        String gettingTheStencilFileName() throws Exception {
            //Invariant Opening Contract
            //The stencil name is not a null or empty string.           
            if (theStencilFileName == null || theStencilFileName.length() == 0) {
                throw new Exception(STENCIL_FILE_NAME_ERROR);
            }
            return (theStencilFileName);
        }
        //This method retruns the tile renderer mappings data structure
        java.util.HashMap<String, String> gettingTheTileRendererMappings() throws Exception{
            //Invariant Opening Contract
            //The tile renderer mappings are not null. They might be empty.
            if (theTileRendererMappings == null ) {
                throw new Exception(TILE_RENDERER_MAPPINGS_ERROR);
            }           
            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.
    private String gettingTheResponseStencil(javax.servlet.ServletContext theServletContext, String aStencilFileName) throws Exception {
        //Opening Contract
        //The file name of the view stencil is not a null or empty string.
        if (aStencilFileName == null || aStencilFileName.length() == 0) {
            throw new Exception(STENCIL_FILE_NAME_ERROR);
        }
        java.io.BufferedReader aStencilReader = new java.io.BufferedReader(new java.io.FileReader(theServletContext.getRealPath(aStencilFileName)));
        String theStencilContent = "", theNextLine = null;
        while ((theNextLine = aStencilReader.readLine()) != null) {
            theStencilContent += theNextLine;
        }
        //Closing Contract
        //The stencil content of the view in not its initial value of an empty string.
        if (theStencilContent.length() == 0) {
            throw new Exception(STENCIL_CONTENT_ERROR);
        }
        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) throws Exception {
        java.util.HashMap<String, String> aMap = new java.util.HashMap<String, String>();
        //Opening Contract
        //If the request query string is null or empty, return an empty aMap
        if (aRequest == null || aRequest.length() == 0) {
            return aMap;
        }
        aRequest = aRequest.replace("?", "");
        String[] theNameValuePairs = aRequest.split("&");
        for (String aNameValuePair : theNameValuePairs) {           
            String[] aTuple = aNameValuePair.split("=");
            aMap.put(aTuple[NAME_INDEX], aTuple[VALUE_INDEX]);
        }
        //Closing Contract
        //The Map cannot be empty on the input of a non-empty request query string
        if (aMap.size() == 0) {
            throw new Exception(QUERY_STRING_ERROR);
        }
        return aMap;
    }
    //When an exception has occurred, this method populates a view stencil with
    //the content generated by dynamically invoking rendering methods and
    //replacing their associated user-defined tile identifiers
    //( a.k.a stencil replacement variables ). Notice that this method does not
    //throw an exception upward.
    //See the contract guideline in the header comments of this document.
    String preparingTheExceptionResponse(javax.servlet.ServletContext theServletContext,javax.servlet.http.HttpServletRequest theHTTPServletRequest,javax.servlet.http.HttpServletResponse theHTTPServletResponse) {
        String aReplacementString = "";
        String aSupplementalExceptionMessage = "";
        String theStencilContent = VIEW_MODEL_ERROR;
        ViewModel aViewModel = null;
        String[] aTileClassAndMethod = null;
        //Opening Contract (Implicit)
        //The size of the request map is zero or larger
        aViewModel = (ViewModel) aDirectoryMap.get(EXCEPTION_VIEW);
        //Intermediate Contract
        //The view model cannot be null.
        if (aViewModel == null) {
            return (theStencilContent);
        }
        try {
            theStencilContent = gettingTheResponseStencil(theServletContext,aViewModel.gettingTheStencilFileName());
        } catch (Exception e) {
            return (theStencilContent);
        }
        //Intermediate Contract (Implicit)
        //The stencil content of the view in not an empty string.
        java.util.HashMap<String, String> someTileRenderMappings = null;
       
        try {
            someTileRenderMappings = aViewModel.gettingTheTileRendererMappings();
        }catch( Exception e ) {
            return (theStencilContent);
        }
       
        //Intermediate Contract (Implicit)
        //The tile renderer mappings are not null. They might be empty.
        for (String aTileId : someTileRenderMappings.keySet()) {
            //Intermediate Contract Within Evaluation (.get) (Implicit)
            //The tile class and method is a non-empty string which contains a single
            //comma as a CSV string.
            aTileClassAndMethod = ((String) someTileRenderMappings.get(aTileId)).split(",");                       
            //Intermediate Contract
            //The class and method names for the tile renderer cannot be null or empty.
            if (aTileClassAndMethod[CLASS_INDEX] == null || aTileClassAndMethod[METHOD_INDEX] == null || aTileClassAndMethod[CLASS_INDEX].length() == 0 || aTileClassAndMethod[METHOD_INDEX].length() == 0) {
                aSupplementalExceptionMessage += FORMATTED_CLASS_METHOD_ERROR;
            }
            try {
                //Start Reflection Activities
                Class aClass = Class.forName(aTileClassAndMethod[CLASS_INDEX]);
                Class[] theFullyQualifiedParameterTypeClasses = new Class[2];
                theFullyQualifiedParameterTypeClasses[0] = theHTTPServletRequest.getClass();
                theFullyQualifiedParameterTypeClasses[1] = theHTTPServletResponse.getClass();
                Object[] theParameterObjectList = new Object[2];
                theParameterObjectList[0] = theHTTPServletRequest;
                theParameterObjectList[1] = theHTTPServletResponse;
                aReplacementString = (String) (aClass.getMethod(aTileClassAndMethod[METHOD_INDEX], theFullyQualifiedParameterTypeClasses)).invoke((aClass.getConstructor()).newInstance(), theParameterObjectList);
                //End Reflection Activities                        
            } catch (Exception e) {
                aReplacementString = "<p>" + e.getMessage() + "</p>";
            }
            theStencilContent = theStencilContent.replace(aTileId, aReplacementString + aSupplementalExceptionMessage);
        }
        //Closing Contract (Implicit)
        //The class and method for the given name exist among the controller application bundle.     
        return (theStencilContent);
    }
    //This method 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 preparingTheSuccessfulResponse(String theViewId, javax.servlet.ServletContext theServletContext,javax.servlet.http.HttpServletRequest theHTTPServletRequest,javax.servlet.http.HttpServletResponse theHTTPServletResponse) throws Exception {
        //Opening Contract
        //The id of the view cannot be null or empty
        if (theViewId == null || theViewId.length() == 0) {
            throw new Exception(VIEW_IDENTIFIER_ERROR);
        }
        //Opening Contract (Implicit)
        //The size of the request map is zero or larger
        ViewModel aViewModel = (ViewModel) aDirectoryMap.get(theViewId);
        //Intermediate Contract
        //The view model cannot be null.
        if (aViewModel == null) {
            throw new Exception(VIEW_MODEL_MISSING_ERROR);
        }
        String[] aTileClassAndMethod = null;
        String theStencilContent = gettingTheResponseStencil(theServletContext,aViewModel.gettingTheStencilFileName());
        //Intermediate Contract (Implicit)
        //The stencil content of the view in not an empty string.
        java.util.HashMap<String, String> someTileRenderMappings = aViewModel.gettingTheTileRendererMappings();
        //Intermediate Contract (Implicit)
        //The tile renderer mappings are not null. They might be empty.
        for (String aTileId : someTileRenderMappings.keySet()) {
            //Intermediate Contract Within Evaluation (.get) (Implicit)
            //The tile class and method is a non-empty string which contains a single
            //comma as a CSV string.
            aTileClassAndMethod = ((String) someTileRenderMappings.get(aTileId)).split(",");
            //Intermediate Contract
            //The class and method names for the tile renderer cannot be null or empty.
            if (aTileClassAndMethod[CLASS_INDEX] == null || aTileClassAndMethod[METHOD_INDEX] == null || aTileClassAndMethod[CLASS_INDEX].length() == 0 || aTileClassAndMethod[METHOD_INDEX].length() == 0) {
                throw new Exception(CLASS_METHOD_ERROR);
            }
            //Start Reflection Activities
            Class aClass = Class.forName(aTileClassAndMethod[CLASS_INDEX]);
            Class[] theFullyQualifiedParameterTypeClasses = new Class[2];
                theFullyQualifiedParameterTypeClasses[0] = theHTTPServletRequest.getClass();
                theFullyQualifiedParameterTypeClasses[1] = theHTTPServletResponse.getClass();
                Object[] theParameterObjectList = new Object[2];
                theParameterObjectList[0] = theHTTPServletRequest;
                theParameterObjectList[1] = theHTTPServletResponse;
                theStencilContent = theStencilContent.replace(aTileId, (String) (aClass.getMethod(aTileClassAndMethod[METHOD_INDEX], theFullyQualifiedParameterTypeClasses)).invoke((aClass.getConstructor()).newInstance(), theParameterObjectList));
            //End Reflection Activities                        
        }
        //Closing Contract (Implicit)
        //The class and method for the given name exist among the controller application bundle.     
        return (theStencilContent);
    }
    private org.w3c.dom.Document gettingTheDirectoryXMLDocument(javax.servlet.ServletContext theServletContext) throws Exception {
       
        javax.xml.parsers.DocumentBuilderFactory theDocumentBuilderFactory =
        javax.xml.parsers.DocumentBuilderFactory.newInstance();
        javax.xml.parsers.DocumentBuilder theDocumentBuilder = theDocumentBuilderFactory.newDocumentBuilder();
        //Intermediate Contract (implicit)
        //The argument for the java.io.File constructor is the canonical name
        //for all CABOOSE bundles and is XML. (It will differ in the final version).
        java.io.File aFile = new java.io.File(theServletContext.getRealPath(STANDARD_DIRECTORY_SOURCE));
        org.w3c.dom.Document theDocument = theDocumentBuilder.parse(aFile);
        theDocument.getDocumentElement().normalize();
       
        return (theDocument);
    }
    //This module 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 doing it once during a servlet
    //session and storing the utlimate view model map in the servlet's session
    //object. Directory.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 populatingTheDirectoryMap(javax.servlet.ServletContext theServletContext) throws Exception {
        String aViewId = null;
        String aStencil = null;
        String aTileId = null;
        String aTileClass = null;
        String aTileMethod = null;
        aDirectoryMap = new java.util.HashMap<String, ViewModel>();
        org.w3c.dom.Document theDocument = gettingTheDirectoryXMLDocument(theServletContext);
       
        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.settingTheStencilFileName(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);
                    }
                }
            }
        }
        //Closing Contract
        //The directory map cannot be empty if the CAB returns a view
        if (aDirectoryMap.size() == 0) {
            throw new Exception(DIRECTORY_ERROR);
        }
    }
}
//SystemExceptions.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.java.CABOOSE;
/**
 *
 * @author Jody
 */
public interface SystemExceptions {
     //Exception Handling Constants
    final String VIEW_MODEL_ERROR = "<html><head><title>CABOOSE ERROR</title><head><body>The exception view model, content, or tile mappings were not found.</body></html>";
    final String STENCIL_FILE_NAME_ERROR = "Stencil name is null or empty.";
    final String TILE_RENDERER_MAPPINGS_ERROR = "The mapping between tiles and render methods is null.";
    final String STENCIL_CONTENT_ERROR = "The stencil content of the view stencil is empty.";
    final String QUERY_STRING_ERROR = "The input key-value map is empty. Could not interpret the query string.";
    final String VIEW_IDENTIFIER_ERROR = "The view identifier is null or empty.";
    final String VIEW_MODEL_MISSING_ERROR = "The view model was not found.";
    final String CLASS_METHOD_ERROR = "The class or method name for the tile renderer was null or empty.";
    final String FORMATTED_CLASS_METHOD_ERROR = "<p>" + CLASS_METHOD_ERROR + "</p>"; ;   
    final String DIRECTORY_ERROR = "The application view directory map is empty.";
    final String EXCEPTION_VIEW = "exception";
    final String EXCEPTION_KEY = "exception_message";
}
//SystemStandards.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.java.CABOOSE;
/**
 *
 * @author Jody
 */
public interface SystemStandards {
     //Standard Constants
    final int CLASS_INDEX = 0;
    final int METHOD_INDEX = 1;
    final int NAME_INDEX = 0;
    final int VALUE_INDEX = 1;
    final String STANDARD_DIRECTORY_SOURCE = "/WEB-INF/directory.xml";
   
}
//Caboose.java - Hibernate Auto-generated Class Through Reverse Engineering
package net.java.CABOOSE.Hibernate;
// Generated Dec 28, 2014 1:19:07 AM by Hibernate Tools 4.3.1

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
 * Caboose generated by hbm2java
 */
@Entity
@Table(name="CABOOSE"
    ,schema="ROOT"
)
public class Caboose  implements java.io.Serializable {

     private int id;
     private String message;
    public Caboose() {
    }

    public Caboose(int id) {
        this.id = id;
    }
    public Caboose(int id, String message) {
       this.id = id;
       this.message = message;
    }
  
     @Id
   
    @Column(name="ID", unique=true, nullable=false)
    public int getId() {
        return this.id;
    }
   
    public void setId(int id) {
        this.id = id;
    }
   
    @Column(name="MESSAGE", length=256)
    public String getMessage() {
        return this.message;
    }
   
    public void setMessage(String message) {
        this.message = message;
    }
}
//HibernatePort.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.sharpe.sample;
/**
 *
 * @author Jody
 */
class HibernatePort {
   
   
    private org.hibernate.SessionFactory aHibernateSessionFactory = new org.hibernate.cfg.Configuration().configure().buildSessionFactory();
   
    String listCABOOSEMessages () throws Exception{
        String theMessages = "";
        String anExceptionMessage = null;
        boolean anExceptionOccurred = false;
        org.hibernate.Session anHibernateSession = null;
        org.hibernate.Transaction anHibernateTransaction = null;
        try {
        anHibernateSession = aHibernateSessionFactory.openSession();
        anHibernateTransaction = anHibernateSession.beginTransaction();
        java.util.List<net.java.CABOOSE.Hibernate.Caboose> theCabooseMessages = anHibernateSession.createQuery("FROM Caboose").list();
        for ( net.java.CABOOSE.Hibernate.Caboose theMessage: theCabooseMessages ){
            theMessages += "MSG[" + theMessage.getId()+ "]: " + theMessage.getMessage() + "</br>";           
        }
        anHibernateTransaction.commit();
        }catch(org.hibernate.HibernateException anHibernateException){
            if( anHibernateTransaction != null ){
                anHibernateTransaction.rollback();
                anExceptionOccurred = true;
                anExceptionMessage = anHibernateException.getMessage();               
            }
        }finally{
            anHibernateSession.close();
        }
       
        if(anExceptionOccurred){
            throw new Exception(anExceptionMessage);
        }
        return theMessages;
    }
   
}
//StencilHandler.java
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.sharpe.sample;
/**
 * An example stencil handler class. For each unique instance of a CABOOSE
 * application, these will be user defined.
 * @author Jody
 */
public class StencilHandler implements net.java.CABOOSE.SystemExceptions{
     //Renderer for supplying content about the create date
    public String createDateRenderer( javax.servlet.http.HttpServletRequestWrapper theHTTPServletRequest, javax.servlet.http.HttpServletResponseWrapper theHTTPServletResponse ){
        return( theHTTPServletRequest.getParameter("create_date") ); 
    }
    //Renderer for supplying content about the module
    public String moduleRenderer(  javax.servlet.http.HttpServletRequestWrapper theHTTPServletRequest, javax.servlet.http.HttpServletResponseWrapper theHTTPServletResponse ){
        return( theHTTPServletRequest.getParameter("module") ); 
    }
    //Renderer for supplying content about the project
    public String projectRenderer(  javax.servlet.http.HttpServletRequestWrapper theHTTPServletRequest, javax.servlet.http.HttpServletResponseWrapper theHTTPServletResponse ){
        return( theHTTPServletRequest.getParameter("project") ); 
    }
    //Renderer for supplying exception content
    public String exceptionRenderer(  javax.servlet.http.HttpServletRequestWrapper theHTTPServletRequest, javax.servlet.http.HttpServletResponseWrapper theHTTPServletResponse ){
        return( (String) ((javax.servlet.http.HttpSession) theHTTPServletRequest.getSession()).getAttribute(EXCEPTION_KEY) ); 
    }
    public String hibernateMessageRenderer( javax.servlet.http.HttpServletRequestWrapper theHTTPServletRequest, javax.servlet.http.HttpServletResponseWrapper theHTTPServletResponse ) throws Exception{
        HibernatePort anHibernatePort = new HibernatePort();
        return( anHibernatePort.listCABOOSEMessages() ); 
    }
}
//END OF SOURCE FILES

Tuesday, December 23, 2014

Holiday Season

Team. Have a wonderful holiday season. Regular posting will resume on 01/05/2014.La-La.

Monday, December 22, 2014

Source Code Delivery Delay

Team.  The source once was reviewed once this past weekend. Other responsibilities took most of my time. Plan on delivery next Monday. Post will not appear on 12/24/2014 to 12/26/2014 and 12/31/2014 to 01/01/2015. Upon editing the code, it seemed best that there be an interface for holding all of the constants associated with exception handling. Also, an interface for all of the standard CABOOSE constants also might be useful. The prototype code will first be placed in-line in a post. After which, we will place it in the java.net repository. La-La.

Friday, December 19, 2014

A Hill of Beans

Team. An idea about placing a layer of beans which holds stencil replacement content on top of the beans which interface with the system entities struck yesterday. With limited experience with JAVA beans plus bean reflection, more reading must be done in the API reference before settling on this idea.

Also, there are many alternative ways to supply the stencil replacement content. Form beans generated with JSP and JSF pages also could have methods called by reflection to render content.

One our goals should be keeping any and all XML/XHTML elements out of the rendering methods source code. In other words it should not be hard-coded and compiled in the JAVA object.

Plus, we must reconsider stencil replacement tiles which supply content for an XHTML attribute or attribute lists. If we use an XML element called "tile" for these replacements, we will have malformed XML. Therefore, we could not use a DOM or SAX parser for the replacement tasks. Consider,

<td align="#ALIGNMENT#" #DYNAMIC_ATTRIBUTES#>Varied Alignment and Dynamic Attributes</td>

versus

<td align="<tile class='cab.TDHandler' method='renderAlignAttribute'/>" <tile class='cab.TDHandler' method='renderDynamicAttributes'/>>Varied Alignment and Dynamic Attributes</td>


This is malformed XHTML/XML, and a parser will not process it properly.
So, it will be likely that our directory.xml file will remain where it is. When working with JSP and JSF, we might achieve the same replacement effects with Expression Language (EL) and calling the rendering method. Consider,

<td align="#{cab.TDHandler.renderAlignAttribute()}"
 #{cab.TDHandler.renderDynamicAttributes()}>Varied Alignment and Dynamic Attributes</td>

Just a few thoughts before the weekend. The edited source code should be available on Monday. La-La.

Thursday, December 18, 2014

Short Note and Starting A Technical Writing Syle

Team. Upon tracking the page views for this weblog, it was found that some international visitors were visiting once or twice and then not returning. For fear that the style of English-writing which is being used might be somewhat confusing for those whose mother tongue is not English, we will adopt a simple style consistent with writing procedures and technical manuals. The style used so far is simply the most comfortable for the author.

The style of this paragraph was used to write a paper for COMPSAC 2005, an international software engineering conference. The paper was well-accepted. In the upcoming weeks, we will summarize the notes from previous posts with this style. The sentences will be shorter. Plus, the English will be simpler.

The delivery of the edited (redacted) source code for CABOOSE might be delayed. The source should be proof-read at least three times before delivery. Plus, the comments should be descriptive and meaningful. This will be about a sixteen hour effort. Planning allows for an hour of work each week day plus eight on the weekend. To begin evolving the prototype in the initial development cycle without reviewing the source at least three times would be unwise.

Also, we probably will add some more time on the project plan for the prototype. This is so we can create stencil handlers to use SOAP, REST, Hibernate, and etc.

We would appreciate any constructive critiques in the online forum at http://java.net/projects/caboose. La-La.

Wednesday, December 17, 2014

String Theory Addend, JAVA Similarities, the Number Theory of Computing, and Considering Directions

Team.Today will be another extended post demystifying what we are doing with CABOOSE.

STRING THEORY ADDEND

Yesterday, we considered four Axioms for the String Theory of Computing. After a little more pondering, it became apparent that a very important axiom of computing strings was completely omitted. Reviewing, the first four axioms are as follows:

Strings are everywhere in computing. This is our first axiom of string theory. The Ubiquity Axiom. For this theory, a string is like a point in geometry.

Our second axiom is that in essence, computing is the passing of strings between data sources and data targets (sinks - for those of you who think in terms of discrete graphs and abstract networks) . This is our Axiom of Transfer.

The next axiom, our Axiom of Transformation, states that, while in transfer, computational modules might mutate a string as needed.

Our fourth and last axiom holds that the final state of any computation is a transfer-able string. This is the Axiom of Invariance.


Our missing rule follows:

The fifth and likely most important is the Axiom of Universality. The symbols which compose strings are primitive, often well-known, and a commonly agreed upon medium for communication among all humans and machines.

JAVA SIMILARITIES

Interestingly enough, the original design of the language JAVA includes the complementary goals of ubiquitousness and universality. With its prevalence as a de-facto standard in computing and the differing editions for Micro, Standard, or Enterprise applications, it is rapidly reaching both goals in roughly a pair of decades. Sun Microsystems and its management should be applauded for creating JAVA. It was an incredibly bold move. Most students of computing in the early 1990s when JAVA was originally prototyped were told a single universal high-level computing language did not exist and was an impossible undertaking. This seems like a rather strong statement for such a young and immature field; however, this was taught.

From the point of computing theory, universal languages which could represent any computable program existed, but they were so incredibly simple that whey would not be practical for professional use. One of these is S. Pronounced "script ess" and represented with a cursive capital S, it only has three instructions. These are increment by one, decrement by one, and branch on zero. Obviously, any hardware system which supported these would require large, unwieldy programs for performing the most simple of common business-oriented computing tasks.

For the young aspiring entrepreneur, learn a lesson from Sun. If you can produce a product that the majority of individuals in your profession says would be useful but is an impossiblity, success will follow. JAVA is not perfect, but it is an excellent attempt at the impossible. Kudos Sun and Oracle. Thank you for making this available. Another lesson one can learn is that "free,quality" products can gain market share rapidly. You can always charge a nominal fee in the future. Shareware often cost between five and ten dollars and does not come with any support. If Oracle offered initial installs of JAVA major releases for ten dollars with free automatic updates, they would have some wonderful quarterly reports considering that JAVA has over three billion active installs.

THE NUMBER THEORY OF COMPUTING

Number Theory for the modern mathematician is a study of the fundamental properties of numbers such as primality, divisibilty, congruence, and more. Historically, the Theory of Numbers was called Arithmetic. Although it uses the four fundamental operations of addition, subtraction, multiplication, and division, its extends far beyond these. In centuries past, what we now know as the arithmetic learned in elementary school was called Coss. For those who like math as a recreation, Oystein Ore wrote a wonderful book on the History of Number Theory. It reads somewhat like a novel with a number of historical antecdotes.

The Number Theory of Mathematics can trace its history as far back as the early Egyptian and Chinese civilizations and likely pre-dates them. Yet, the the Number Theory of Computing is much different and derives much of its inspiration from the early work on computing theory in the early twentieth century. During those years, many professional mathematicians earned a living as a human computer. They would tabulate list of logarithms, trigonometric functions, and such. Someone wondered whether it would be possible if one could create a function that computed another function given its function definition and its input. This was the early mathematical work that produced modern computers, because eventually someone inspired by Charles Babbage's work created a machine as a hard-wired function that could compute any other function described with a language that it understood. What is fundamental in this early work is that all functions could be represented by a single unique number. In essence, a computer programs is a functions which is the composition of smaller functions. So, a computer program can be represented by a single unique number.

Hence, our first rule in the Number Theory of Computing, The Axiom of Identity. There is a single number which uniquely describes a computer program.

Our second rule is the Axiom of Proximity. Numbers describing computer programs which are near each other represent programs with similar behavior.

Finally, the third and last rules states that writing correct programs is the process of choosing a starting number and making gradual progress through code revision until one reaches its target. Hence, program development is iterative and optimizing. This is the Axiom of Hill-Climbing.

Summarizing the Number Theory of Computing, a program is naught more than a number.

CONSIDERING DIRECTIONS

It also crossed my mind that within a JSP, a scriptlet could easily call a rendering method; however, scriptlets are somewhat frowned upon. So we will probably continue along the path of creating a custom tag for JSP and JSF which generates content given a class and method. We will also continue using a tile as a placeholder in our stencils. This tile might be XML or a user-defined string.

Also, JSF is not a strong point of this developer. Skimming the JEE 7 Tutorial Reference did not produce an in-depth knowledge of JSF. The rendering methods used by CABOOSE might be found in this approach in a simpler form. More review and research must be done. If this effort is reproducing prior work, it will simply be a fun exercise. La-La.

Tuesday, December 16, 2014

String Theory of Computing

Team. Many modern-day physicist believe that a multidimensional unit of existence that they call a "string" is the fundamental building block of the universe. Before, one becomes an accomplished physicist one must master "strings". There is a parallel in computing, software engineering, and traditional data processing. Thankfully, this parallel is not nearly as complex. Remember, we believe in keeping things simple; physicist lost that philosophy in their profession with the advent of  the numerous counter-intuitive theories which arose after Einstein turned Newton's classical physics of the macroscopic, sub-lightspeed world on its ear.

In the world of computing, a string is simple a sequence of letters, numbers, or other symbols. These weblog posts are simply an extended string. Strings have the property that each sub-portion of a string is also a string that we call a sub-string. For instance, the word "Team" which starts this post is a sub-string at the head of the string which represents the first paragraph. A sub-string is simple a small contiguous portion of a larger string which is a string itself.

More abstractly, the primary and secondary storage devices on any electronic computing device hold a string of zeroes and ones represented by electromagnetic signals of varying intensity. Depending on the collating sequence, collections of these electronic states grouped by eight, sixteen, thirty-two, or sixty-four represent the various symbols which a computer can manipulate. A collating sequence is simply a mapping between a sequence of zeroes and ones of a "given, fixed" sized and symbols.

One of the earliest, common, and standard sequences used was EBCDIC which stands for Extended Binary Coded Decimal Interchange Code. It is still in common use by many mainframe computers.

Another popular and common sequence is ASCII, the American Standard Code for Information Interchange. It is a standard that has been used with mini- and micro-computers since the early sixties. ASCII supports representing one hundred and twenty-eight symbols including the English alphabet, 'a' - 'z' and 'A' - 'Z', plus the digits, '0' -'9'.

As computers expanded in their capabilities and had needs for expressing more complex and diverse strings, the American National Standards Institute (ANSI) developed Extended-ASCII. This list supported two-hundred and fifty-six symbols.

It is important that it be emphasized that the word "sequence" has been used in more that one way: firstly, describing strings, and, secondly, describing the list or tables which hold mappings between a sequence zeroes and ones, called a binary number, and a symbol. It should also be added that the binary numbers in these tables often appear in related forms such as an octal or hexadecimal number which are more readable and compact. One can easily convert between binary and octal or hexadecimal by simple grouping zero and one symbols in sets of three or four digits and converting between bases.

Finally, in the most recent years of computing, researchers at Xerox PARC in Northern California sought the production of a universal collating sequence which could represent any symbol in any language, whether current or historical, plus provide room for expansion in the future. This collating sequence is known as Unicode and supports over one hundred thousand symbols currently. As with general purposefulness, universality is a common goal found in computing.

Strings are everywhere in computing. This is our first axiom of string theory. The Ubiquity Axiom. For this theory, a string is like a point in geometry.

Our second axiom is that in essence, computing is the passing of strings between data sources and data targets (sinks - for those of you who think in terms of discrete graphs and abstract networks) . This is our Axiom of Transfer.

The next axiom, our Axiom of Transformation, states that while in transfer computational modules might mutate a string as needed.

Our fourth and last axiom holds that the final state of any computation is a transfer-able string. This is the Axiom of Invariance.

Clarifying CABOOSE, its primary goal is simplifying the string processing and passing which occurs in layered type-II model-view-controller web applications. As a software engineer, whenever you become overwhelmed by the technical nature of the computing task which you are performing remember that ultimately you are only moving a string between point A and point B. Software development frequently can be muddled by unfamiliar technical terms, domain knowledge, and a learning curve. When puzzled by a new technological paradigm, language, or method of concerns partitioning, simply stop, identify the strings in the system, their sources, and targets, and research the ways in which one moves a string between each source and target in a programmer's guide, language reference, or tutorial at a quality developer's internet site. There are many developer resources on the web such as the Oracle Technology Network (OTN), the Microsoft Developer's Network (MSDN), perl.org, php.net, pyhton.org, plus many more. It is best if you seek development advice from the originators of the technology which you might be using.

Experience in scientific and business computing has taught much. From scripting in Magical on a Varian 500 Mhz Nuclear Magnetic Resonance Spectrascope, report writing on retired Wang mini-computers using the Professional Application Creation Environment (PACE) and its fourth generation language, building a computer telephony integration device using C, UNIX and a Dialogic API, providing decision support services with COBOL in OS/360 and OS/390 environments, scripting common gateway interface processes during the early days of the web using HTML, JavaScript, C, UNIX, and embedded SQL, creating business support applications in VB6 and VB.NET, increasing the sales of small businesses using JAVA, creating web applications in PERL, PHP, and Python, plus teaching all of these skills and more, I am convinced that at the end of the day the summation of all of the efforts of the modern computing professional simply is the passing of strings between source and sink.

Please pardon the longer post. Occasionally, making a concept "plain" requires an extended explanation. Hopefully, this post has helped you decipher what we are doing with CABOOSE.

Concepts are rarely ever over-simplified. We will also examine some of the other mysteries in modern computing with this Wednesday post, The "Number Theory of Computing".

The redacted source code for the progress on the protoype which we have made will be posted this Friday. La-La.



Monday, December 15, 2014

Taking Stocking. Friends of CABOOSE.

Team. Let us take a good look at the project and decide how we can produce the best prototype with the resources and time that we have left. We have already mentioned adding a custom tag for JSP or JSF which we would use for placing view-model content in the webpage. We also considered how one might use a bean for placing a property's value on a page. What if we make this value structured web content and access it with the "jsp:usebean" and "jsp:getproperty" tags while using the "jsp:setproperty" method for accessing form data. We also have considered creating a custom CABOOSE tile element for returning content when using the general-purpose servlet. And, it was promised that the prototype would not be gold-plated and the "feature creep" would not be allowed in our informal joint application design (JAD) session. Yet, extending the prototype with a few stencil handlers which use popular technologies like SOAP, REST, Hibernate and etc. might be worth while. This would provide users of the servlet or custom tags with a template for development which they could utilize. Our primary focus over the coming weeks will be the servlet. Any custom tags will follow.

Based upon the "simple development plan" given in November, this week we should be adding the contracts which we have already completed. We did delay the use of a SAX reader, and we likely will continue delaying it since we decided that it would involve the using the custom CABOOSE "tile" element. A excellent use of our efforts this week would be insuring that the code has quality comments and content, is algorithmically efficient, and is highly readable. We should also spend some time investigating the use of other "friendly" technologies. This would also be a reasonable time for creating some test-cases since we are still working on requirements elicitation.

Enjoy the best week possible. La-La.


Friday, December 12, 2014

Prototype Exception Handling

Team. This is the JAVA source with exception handling and the rest of the prototype code. We can test how well our modifications work by throwing an exception in the main method at the end of the try-catch block. I completed both of the steps which I mentioned earlier this week when creating this solution and did not post any intermediate work. I would appreciate any feedback which you might have. Have a great weekend. La-La.

//BEGIN JAVA CAB SOURCE
/*
 * 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 {

    //Exception Handling constants
    final String CABOOSE_EXCEPTION_VIEW_MODEL_ERROR = "<html><head><title>CABOOSE ERROR</title><head><body>The exception view model or content was not found.</body></html>";
    final String EXCEPTION_VIEW = "exception";
    //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) throws Exception {
            //Opening Contract
            //The stencil name is not a null or empty string.
            if (aStencilName == null || aStencilName.length() == 0) {
                throw new Exception("Stencil name is null or empty");
            }
            theStencilName = aStencilName;
            //Closing Contract (Implicit)
            //The stencil name is a non-empty string.
        }

        //This method assigns the tile renderer mappings
        void settingTheTileRendererMappings(java.util.HashMap<String, String> aSetOfTileRendererMappings) throws Exception {
            //Opening Contract
            //The set of mappings between tiles and renderer methods is not null
            //It might be of size zero if there soes not exist any replacment tiles
            //within the stencil.
            if (aSetOfTileRendererMappings == null) {
                throw new Exception("The mapping between tiles and render methods is null");
            }
            theTileRendererMappings = aSetOfTileRendererMappings;
            //Closing Contract (Implicit)
            //The tile renderer mappings is not null. They might be empty.
        }

        //This method returns the stencil file name
        String gettingTheStencilName() {
            //Invariant Contract (Implicit)
            //The stencil name is a non-empty string.
            return (theStencilName);
        }

        //This method retruns the tile renderer mappings data structure
        java.util.HashMap<String, String> gettingTheTileRendererMappings() {
            //Invariant Contract (Implicit)
            //The tile renderer mappings are not null. They might be empty.
            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 {
        //Opening Contract
        //The file name of the view stencil is not a null or empty string.
        if (aViewFileName == null || aViewFileName.length() == 0) {
            throw new Exception("The filename of the view stencil is null or empty");
        }
        java.io.BufferedReader aStencilReader = new java.io.BufferedReader(new java.io.FileReader(aViewFileName));
        String theStencilContent = "", theNextLine = null;
        while ((theNextLine = aStencilReader.readLine()) != null) {
            theStencilContent += theNextLine;
        }
        //Closing Contract
        //The stencil content of the view in not its initial value of an empty string.
        if (theStencilContent.length() == 0) {
            throw new Exception("The stencil content of the view stencil is empty");
        }
        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) throws Exception {
        java.util.HashMap<String, String> aMap = new java.util.HashMap<String, String>();
        //Opening Contract
        //If the request query string is null or empty, return an empty aMap
        if (aRequest == null || aRequest.length() == 0) {
            return aMap;
        }
        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]);
        }
        //Closing Contract
        //The Map cannot empty on the input of a non-empty request query string
        if (aMap.size() == 0) {
            throw new Exception("The input key-value map is empty. Could not interpret the query string.");
        }
        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 preparingTheExceptionResponse(java.util.HashMap<String, String> aRequestMap) {

        String aReplacementString = "";
        String aSupplementalExceptionMessage = "";
        String theStencilContent = CABOOSE_EXCEPTION_VIEW_MODEL_ERROR;
        ViewModel aViewModel = null;
        String[] aTileClassAndMethod = null;

        //Opening Contract (Implicit)
        //The size of the request map is zero or larger

        aViewModel = (ViewModel) aDirectoryMap.get(EXCEPTION_VIEW);

        //Intermediate Contract
        //The view model cannot be null.
        if (aViewModel == null) {
            return (theStencilContent);
        }

        try {
            theStencilContent = gettingTheResponseStencil(aViewModel.gettingTheStencilName());
        } catch (Exception e) {
            return (theStencilContent);           
        }

        //Intermediate Contract (Implicit)
        //The stencil content of the view in not an empty string.

        java.util.HashMap<String, String> someTileRenderMappings = aViewModel.gettingTheTileRendererMappings();

        //Intermediate Contract (Implicit)
        //The tile renderer mappings are not null. They might be empty.

        for (String aTileId : someTileRenderMappings.keySet()) {

            //Intermediate Contract Within Evaluation (.get) (Implicit)
            //The tile class and method is a non-empty string whcih contains a single
            //comma as a CSV string.

            aTileClassAndMethod = ((String) someTileRenderMappings.get(aTileId)).split(",");

            //Intermediate Contract
            //The class and method names for the tile renderer cannot be null or empty.
            if (aTileClassAndMethod[0] == null || aTileClassAndMethod[1] == null || aTileClassAndMethod[0].length() == 0 || aTileClassAndMethod[1].length() == 0) {
                aSupplementalExceptionMessage += "<p>" + "The class or method name for the tile renderer was null or empty."  + "</p>";
            }

            try {
                //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;
                aReplacementString = (String) (aClass.getMethod(aTileClassAndMethod[1], theFullyQualifiedParameterTypeClasses)).invoke((aClass.getConstructor()).newInstance(), theParameterObjectList);
                //End Reflection Activities                        
            } catch (Exception e) {
                aReplacementString = "<p>" + e.getMessage() + "</p>";
            }

            theStencilContent = theStencilContent.replace(aTileId, aReplacementString + aSupplementalExceptionMessage );

        }

        //Closing Contract (Implicit)
        //The class and method for the given name exist among the controller application bundle.     
        return (theStencilContent);
    }

    //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 preparingTheSuccessfulResponse(String theViewId, java.util.HashMap<String, String> aRequestMap) throws Exception {

        //Opening Contract
        //The id of the view cannot be null or empty
        if (theViewId == null || theViewId.length() == 0) {
            throw new Exception("The view identifier is null or empty.");
        }

        //Opening Contract (Implicit)
        //The size of the request map is zero or larger

        ViewModel aViewModel = (ViewModel) aDirectoryMap.get(theViewId);

        //Intermediate Contract
        //The view model cannot be null.
        if (aViewModel == null) {
            throw new Exception("The view model was not found.");
        }

        String[] aTileClassAndMethod = null;

        String theStencilContent = gettingTheResponseStencil(aViewModel.gettingTheStencilName());

        //Intermediate Contract (Implicit)
        //The stencil content of the view in not an empty string.

        java.util.HashMap<String, String> someTileRenderMappings = aViewModel.gettingTheTileRendererMappings();

        //Intermediate Contract (Implicit)
        //The tile renderer mappings are not null. They might be empty.

        for (String aTileId : someTileRenderMappings.keySet()) {

            //Intermediate Contract Within Evaluation (.get) (Implicit)
            //The tile class and method is a non-empty string whcih contains a single
            //comma as a CSV string.

            aTileClassAndMethod = ((String) someTileRenderMappings.get(aTileId)).split(",");

            //Intermediate Contract
            //The class and method names for the tile renderer cannot be null or empty.
            if (aTileClassAndMethod[0] == null || aTileClassAndMethod[1] == null || aTileClassAndMethod[0].length() == 0 || aTileClassAndMethod[1].length() == 0) {
                throw new Exception("The class or method name for the tile renderer was null or empty.");
            }

            //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                        

        }

        //Closing Contract (Implicit)
        //The class and method for the given name exist among the controller application bundle.     
        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() 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();

        //Intermediate Contract (implicit)
        //The argument for the java.io.File constructor is the canonical name
        //for all CABOOSE bundles and is XML. (It will differ in the final version).
        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);
                    }
                }
            }
        }
        //Closing Contract
        //The directory amp cannot be empty if the CAB returns a view
        if (aDirectoryMap.size() == 0) {
            throw new Exception("The application view directory map is empty.");
        }
    }

    /**
     * @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 = null;
        try {
            aRequestMap = aCAB.mappingTheRequestNameValuePairs(aCAB.request);
            aCAB.readingTheDirectoryXMLFile();           
            System.out.println(aCAB.preparingTheSuccessfulResponse("test_page", aRequestMap));
        } catch (Exception e) {
            //For servlets, we will place this method in the system object.
            aRequestMap.put("exception_message", e.getMessage());
            System.out.println(aCAB.preparingTheExceptionResponse(aRequestMap));
        }
    }
}
//END JAVA CAB SOURCE
//BEGIN DIRECTORY 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>   
        <view id="exception" stencil="./src/cab/exception.xhtml">
            <tile id="#EXCEPTION_MESSAGE#" class="cab.StencilHandler" method="exceptionRenderer"/>
    </view>
</model>

//END DIRECTORY XML
//BEGIN STENCIL HANDLER JAVA SOURCE
/*
 * 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") ); 
    }
    //Renderer for supplying exception content
    public String exceptionRenderer( java.util.HashMap<String,String> aRequestMap){
        return( aRequestMap.get("exception_message") ); 
    }
}
//END STENCIL HANDLER JAVA SOURCE
//BEGIN EXCEPTION XHTML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>CABOOSE Embryo Exception</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>#EXCEPTION_MESSAGE#</p>
    </body>
</html>
//END EXCEPTION XHTML
//BEGIN STENCIL 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 STENCIL XHTML