| By Alexey Yakubovich, Alex Maclinovsky | Article Rating: |
|
| March 9, 2005 12:00 AM EST | Reads: |
30,190 |
HTML renders use content renders to arrange content into a required HTML structure. Vitrage contains a broad selection of HTML renders including CellRender, RowRender, TableRender and SpanRender. FlatRender plays a special role; it's used to insert a static HTML fragment, usually obtained from the resource bundle, into the generated HTML structure. For instance, when an HTML table is generated, the FlatRender can provide a spacer between rows.
Composite renders like Serial-Render and ConditionalRender logically combine other renders.
The SerialRender serves as an ordered container of other renders that invokes them sequentially. The ConditionalRender contains a collection of pairs of objects. Each pair consists of a render object and a condition object that implements the interface ICondition. The ConditionalRender in the build() method iterates over each pair, checking if the condition is true, and for the first of such pairs, invokes a build() method on a corresponding render. Only one render is invoked. If no condition satisfied, the ConditionalRender returns an empty string.
The following code fragment demonstrates assembling standard Vitrage renders into a custom render for the JSP-block that implements the P&C compartment described above.
1 public ARender prepareRender(
2 IBlockData data)
3 {
4 CntRefRender crr =
5 new CntRefRender(BASE_ALIGN);
6 crr.setImageCntrParam(true,
7 true, true);
8 crr.rightHanderBlock();
9 crr.setLayout(new ConRefLayout(
10 cssClass, 0, 0, 0));
11 CellRender cr =
12 new CellRender(crr, BASE_ALIGN);
13 RowRender rr = new RowRender(cr,
14 BASE_ALIGN);
15 ConditionalRender spr =
16 new ConditionalRender();
17 spr.addRender(new FlatRender(rs),
18 new NotRslv(new FirstElemRslv()));
19 SerialRender mr =
20 new SerialRender();
21 mr.addRender(spr);
22 mr.addRender(rr);
23 return mr;
24}
At the top of the hierarchy is the main render object mr of class SerianRender. That render contains two renders: rr, which renders the actual rows, and spr. The second one is responsible for spacing between rows of the result table. It is a conditional render that will include a spacer HTML fragment defined in rs for all rows except the first one. The value is read from a resource bundle at startup. The first row in the result table doesn't require a spacer. The object of class FirstElemRslv recognizes the first row in a table and the result is negated by object NotRsvl.
The second part of the main render is the chain of RowRender, CellRender and CntRefRender renders. These renders draw row tag, cell tag and the content reference object representation correspondingly. The following diagram illustrates how a block render is assembled from standard renders.
Let's consider how a render processes each contentlet.
When method build() is invoked on a render, it normally creates a StringBuffer and generates some HTML code into that buffer. For instance, if the main render is a RowRender, it adds an opening tag <TR> to the buffer with attributes specified in its layout object. Then the render invokes build() method on all contained renders in turn, passing along the contentlet. It adds the results from the containing renders to the buffer; then performs necessary post-processing (i.e., adds a closing </TR> tag and returns the content of the buffer). The outer render can always intercept and modify results of its inner renders.
JSP-blocks
The top level of code generation is provided by JSP-blocks. All blocks implement the IBlock interface with the method:
String build(HttpServletRequest r);
That method is invoked at the time of rendering from the JSP.
The Vitrage Framework implements three types of blocks: Controls, Regular blocks, and Composites.
Controls are the simplest kind of blocks to extend class ABlock directly and have to provide their own implementation of method build(). Typically they don't render contentlets but are used to create smart titles, pagination controls and A-to-Z indices, for example.
Regular blocks are responsible for rendering collections of contentlets in compartments. They encompass probably more than 90% of all blocks in a typical application. Regular blocks extend abstract class SimpleBlock. They should implement only two methods:
IBlockData getData(HttpServletRequest r, String gn);
ARender prepareRender(IBlockData d);
Method getData() is responsible for obtaining data, normally from the request object. Typically, IBlockData would contain a collection of contentlets and other supplementary data, such as the title of the compartment. Method prepareRender() assembles a block-specific render from standard renders.
Class SimpleBlock implements method build(). This implementation generates the block's header, then iterates over contentlets passed in the IBlockData object and generates the footer. While iterating over contentlets, it passes each one to the block's render, accumulating the result and recovering from any exceptions. If one contentlet was rendered successfully, build() returns the entire HTML; otherwise, it flushes the buffer and returns an empty string.
Such architecture allows implementing presentation logic on multiple levels: for each contentlet inside the block's render and for the entire block in build() method. Composite blocks implement such logic on an inter-block level.
This design facilitates a high degree of code reuse among blocks. Figure 7 contains a complete implementation for a class that renders the P&C compartment with all the business requirements listed above:
1 public class PAProgramsCompaigns
2 extends RegularRightBlock
3 {
4 public PAProgramsCompaigns(
5 String title, String blockID)
6 {
7 super(title, blockID);
8 setEndFrag(
9 getResource(blockId, END_FRAG));
10 setCssClass(
11 getResource(blockId, CSS_CLASS));
12 rowSpacer = getResource(blockId,
13 ROW_SPACER);
14 }
15}
Class PAProgramsCompaigns inherits from RightHandBlock, as shown in Error! Reference source not found. Error! Reference source not found.contains com-pletes the RightHandBlock class implementation.
1 abstract public class RightHandBlock
2 extends CTSearchEntryBlock
3 {
4 String rowSpacer;
5 public RightHandBlock(String title,
6 String id)
7 { super(title, blockID); }
8
9 protected String getStartFrag()
10 {return getResource(id, FSTART);}
11
12 public ARender prepareRender(
13 IBlockData data)
14 { // see Figure 5 }
15}
Published March 9, 2005 Reads 30,190
Copyright © 2005 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Alexey Yakubovich
Alexey Yakubovich works as a framework architect at Roundarch, Inc. He received his PhD in mathematics in Moscow State University for research in mathematical logic, and has published more than two dozen articles in mathematical magazines. Alexey has spent 20 years in software development.
More Stories By Alex Maclinovsky
Alex works at Sun Microsystems as the Engineering Manager for Sun SOA Governance Solution. For nearly two decades he architected and built distributed systems on enterprise, national and global scale. Alex specializes in SOA Infrastructure, Security and Composite Applications. He blogs at http://blogs.sun.com/RealSOA/ and can be contacted at maclinovsky@yahoo.com
![]() |
Alex Maclinovsky 04/07/05 01:15:09 PM EDT | |||
I understand how immodest it is to leave feedback to my own article, however: |
||||
![]() |
Jack C. Holt 03/30/05 11:49:23 AM EST | |||
I just tried to send email to the email addresses for the authors and my email server is telling me that those email addresses don't exist. How can I reach the authors? |
||||
![]() |
Jack C. Holt 03/30/05 11:34:31 AM EST | |||
Unfortunately, I noticed some typos in this article. For instance the white paper for Vitrage is actually at http://www.roundarch.com/features/vitrage.html. I would have appreciated a link to where I can download the code Vitrage code. |
||||
![]() |
Marina Prikaschikova 03/22/05 09:54:46 AM EST | |||
>The reason custom tags lead to such complexity is that |
||||
- Kindle 2 vs Nook
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- Confessions of a Ulitzer Addict
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- It's the Java vs. C++ Shootout Revisited!
- Cloud Computing Can Revitalize Your Career as Software Developer
- IBM Could "Reinvent" Java: Mills
- Oracle & Cloud Computing: Exclusive Q&A with SVP Richard Sarwal
- A Brief History of Cloud Computing
- Kindle 2 vs Nook
- Cloud CEOs, CTOs & SVPs to Speak at 4th International Cloud Computing Expo
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- What's New in Eclipse?
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- i-Technology Predictions for 2007: Where's It All Headed?









































