10-Jul-06 (Created: 10-Jul-06) | More in 'OSCON-2004'

Master page pattern: Code Examples

Structure of a master page


<html>
<head>

<link rel="stylesheet" type="text/css" href="../../../style/style.css">
<!--ASPIRE_MP_HEADER_BEGIN-->
<!--
****************************************************************
* Include here the following
* style
* java script etc
****************************************************************
-->
<!--ASPIRE_MP_HEADER_END-->

</head>
<body>
<!--ASPIRE_MP_BODY_BEGIN-->
<!--
****************************************************************
* This is made available as top
****************************************************************
-->
{{ASPIRE_MP_CONTENT}}
<!--
****************************************************************
* This is made available as bottom
****************************************************************
-->
<!--ASPIRE_MP_BODY_END-->
</body>
</html>

Structure of an html page


<html>
<head>
<title/>
<link/>
<script/>
{{aspire_masterpage_header}}
</head>

<body>
{{aspire_masterpage_tophalf}}
<!--
**********************************************************
* Page content goes here
**********************************************************
-->
{{aspire_masterpage_bottomhalf}}
</body></html>

Masterpage interface


public interface IMasterPage
{
   public String headerInclude() throws com.ai.servlets.AspireServletException;
   public String topHalf() throws com.ai.servlets.AspireServletException;
   public String bottomHalf() throws com.ai.servlets.AspireServletException;
}

URL definition


<url name="page1URL">
	<transformrequestName="page1TransformRequet"/>
	<datarequestName="page1DataRequest"/>
	<masterpageRequestName="GetMasterPage"/>
</url>

For this page obtain a master page by using GetMasterPage request.

GetMasterPageRequest defined

Use a reusable part that can parse a string


request.GetMasterPage.classname=com.ai.masterpage.RequestBasedMasterPagePart
request.GetMasterPage.masterPageTemplateRN=GetMasterPageTemplate
request.GetMasterPage.cacheKey=/{ownerUserId}/masterpage

Get the string from a database. Expect "ownerUserId" as an input parameter


request.GetMasterPageTemplate.classname=com.ai.db.DBRequestExecutor2
request.GetMasterPageTemplate.db=reportsDB
request.GetMasterPageTemplate.stmt=\
\
select st.statement as masterPageTemplate \
from reports r, sql_statements st \
where 1=1 \
and r.report_content_id = st.statement_id \
and r.report_id = (select master_page_template_item_id from users where user_id = {ownerUserId.quote})

Source code for MasterPageRequest


public class RequestBasedMasterPagePart extends AMasterPageCreatorPart implements IInitializable
{

   private String mpRequestName = null;

    public void initialize(String requestName)
    {
       mpRequestName = AppObjects.getValue(requestName + ".masterPageTemplateRN",null);
    }

   protected IMasterPage create(String requestName, Map params)
          throws RequestExecutionException
   {
      //Get it from the cache
      Object obj = CacheUtils.getObjectFromCache(requestName, params);
      if (obj != null)
      {
         //Object is in the cache
         return (IMasterPage)obj;
      }

      AppObjects.log("Info:Object is not in the cachej for the masterPageTemplate");
      IDataCollection col = null;
      IMasterPage masterPage = null;
      try
      {
         col = (IDataCollection)AppObjects.getObject(mpRequestName, params);
         IIterator itr = col.getIIterator();
         if (itr.isAtTheEnd() == true)
         {
            AppObjects.log("Warn:No rows retrieved. NO master page for this user");
            masterPage = new EmptyMasterPage();
         }
         else
         {
            itr.moveToFirst();
            IDataRow dr = (IDataRow)itr.getCurrentElement();
            String masterPageTemplate = dr.getValue("masterPageTemplate");

            masterPage = this.getMasterPageFromString(masterPageTemplate);
         }

         //Place the object in cache
         CacheUtils.putObjectInCache(requestName, params,masterPage);
         return masterPage;
      }
      catch(DataException x)
      {
         throw new RequestExecutionException("Error:Could not get collection iterator",x);
      }
      catch(com.ai.data.FieldNameNotFoundException x)
      {
         throw new RequestExecutionException("Error:A field called masterPageTemplate not found in the relational data",x);
      }
      finally
      {
         if (col != null)
         {
            try {col.closeCollection();}
            catch(DataException x) { AppObjects.log("Error:Error closing collection",x);}
          }
      }//finally

   }//eof-function
   /**
    * Must return a valid page
    * null is not accepted
    */
   private IMasterPage getMasterPageFromString(String masterPageTemplate)
   {
      String headerPart = getHeaderPart(masterPageTemplate);
      String bodyPart = getBodyPart(masterPageTemplate);

      if (bodyPart == null)
      {
         //Assume the whole string is the body part
         bodyPart = masterPageTemplate;
      }
      int contentIndex = bodyPart.indexOf("{{ASPIRE_MP_CONTENT}}");
      if (contentIndex == -1)
      {
         AppObjects.log("Error: No master page found. aspire content tag is not there");
         return new EmptyMasterPage();
      }

      String topHalf = bodyPart.substring(0,contentIndex);
      String bottomHalf = bodyPart.substring(contentIndex + 21);

      AppObjects.log("Info:mp: Successfully constructing a master page");
      AppObjects.log("Info:mp:tophalf:" + topHalf);
      AppObjects.log("Info:mp:bottomhalf:" + bottomHalf);
      AppObjects.log("Info:mp:header:" + headerPart);

      IMasterPage masterPage = new DefaultMasterPage(topHalf, bottomHalf,headerPart);
      return masterPage;

   }
   private String getHeaderPart(String mpTemplate)
   {
      //Extract header first
      int headerStIndex = mpTemplate.indexOf("");
      if (headerStIndex == -1)
      {
         AppObjects.log("Info: No header detected. Assuming no header");
         return "";
      }
      int headerEndIndex = mpTemplate.indexOf("");
      if (headerEndIndex == -1)
      {
         AppObjects.log("Error:Master page header start detected but no header end");
         return "";
      }
      return mpTemplate.substring(headerStIndex + 29, headerEndIndex);

   }//eof-function

   private String getBodyPart(String mpTemplate)
   {
      //Extract header first
      int bodyStIndex = mpTemplate.indexOf("");
      if (bodyStIndex == -1)
      {
         AppObjects.log("Info: No Body part detected. Assuming the entire document as a body");
         return null;
      }
      int bodyEndIndex = mpTemplate.indexOf("");
      if (bodyEndIndex == -1)
      {
         AppObjects.log("Error:Master page header start detected but no header end");
         return null;
      }
      return mpTemplate.substring(bodyStIndex + 27, bodyEndIndex);
   }//eof-function
}//eof-class

References

1. General Introduction to other Server side Patterns in this series

2. OSCON 2004 Summary page for Server side patterns session

3. Pluggable Transformations Pattern: Code Examples.

4. Generic Transformations Pattern: Code Examples.