CVS: TapestryBook/doc Chapter-01-Introduction.doc,NONE,1.1 Tapestry-Outline.doc,1.4,1.5

Howard Lewis Ship <[email protected]>
Newsgroups gmane.comp.java.tapestry.cvs
Message-ID <[email protected]>
Update of /cvsroot/tapestry/TapestryBook/doc
In directory sc8-pr-cvs1:/tmp/cvs-serv2170/doc

Modified Files:
	Tapestry-Outline.doc 
Added Files:
	Chapter-01-Introduction.doc 
Log Message:
Check in chapter 01 - Introduction.

--- NEW FILE: Chapter-01-Introduction.doc ---
ÐÏࡱá


í†À@

lar; display the user's name as part of an HTML page.  In this case, a Tapestry Insert component is used.  Tapestry uses a pull model in which components read (and in some cases, update) the JavaBeans properties of objects as needed (Swing uses a push model, where the developer writes code that sets the JLabel's text property from the user's name).  So, when the page is rendering, the Insert component will read the name property of the user object and write it into the correct portion of the HTML response.
Just as complex Swing components can be assembled from many simpler Swing components, Tapestry allows complex components to be built from other existing components, with no limitations on how deeply nested components may become.  Like a Swing component, the implementation of a Tapestry component is a black box; the component describes itself in terms of its parameters (akin to Swing component properties) and whether it is implemented as pure Java code, as a collection of other components, or a mix of the two is privileged, private information.
Likewise, just as there are no arbitrary limitations on where a Swing component can be used in a Swing GUI, there are no limitations on where a Tapestry component can be used within a Tapestry page or application.  Tapestry components can adapt themselves to, or be configured for, pages ranging from very simple to very complex.
This pattern of choosing a component and configuring it, is where most of the behavior of a Tapestry application is defined.  It's still programming, it's just declarative programming:  Simple XML specifications instead of Java code.  Tapestry follows the theory that writing less code results in coding fewer bugs, and so, Tapestry provides many ways to define the application without requiring Java code.
Tapestry uses the component metaphor wherever possible.  Some templating systems have special directives for conditionals and loops; Tapestry uses components.  JSPs allow developers to put Java code directly into the page, but Tapestry has no facility for this, or any particular need for it.  Tapestry starts with completely static HTML template and anything dynamic is provided by a component.
Finally, Tapestry frees developers from concerns about the underlying Servlet API when coding applications.  Swing developers can use Swing components without concern for the underlying stack of frameworks, services and protocols (such as event loops, mouse events, window refreshing and pixel-oriented screen updates).  Swing developers simply expect event notifications to active their tiny bits of application specific code.
Likewise, Tapestry developers can create components, pages and applications without any awareness of the Java Servlet API.  Like the Swing developer, they know objects such as HttpSession, HttpServletRequest and HttpServlet are present, there just isn't any pressing need to access those objects.   Tapestry performs all the necessary dispatching of incoming requests and uses a simplified event notification system to get application specific code executed.
Simply put, the various link components invoke developer-provided methods when the user clicks the link in their web browser.  The fact that Tapestry has built a URL in one request cycle (to identify exactly what link within the application was clicked), and interpreted that URL in a later request cycle is immaterial.  Likewise, HTML form related components read and update JavaBeans properties; the names of query parameters involved in accomplishing this is equally irrelevant to the developer … their code simply sees properties of their application objects updated when the form submits.
Objects, Methods and Properties
Tapestry makes heavy use of the JavaBeans framework.  This framework allows virtually any object to be treated as if it was a bundle of named properties, almost as if all objects were simply Maps.  Properties provide a kind of least-common-denominator view of the entire graph of objects in a running application, and makes it possible for code written by different developers at different times to plug together seamlessly.
For example, a TextField component (which creates a text field within an HTML form) may be used to edit a user's name.   The component doesn't have to know anything about users or the rest of the application; it just needs to be pointed at the name property of the user object.  It can read the name property as a default value when a page renders, and update the name property of the user when the containing form is submitted.
Developers using other frameworks may get bogged down in the gory details, such as providing nam for form elements and query parameters.  Tapestry developers deal with just objects and properties; the framework is responsible for providing names.  The framework, specifically the individual components, can read properties when rendering a page, and update properties when a form within the page is submitted; developers never have to bother describing the names of input fields, never have to write code to translate between strings and other types, never needs to be concerned with how to handle multiple forms within a single page, or how to handle loops within a form.  The developer simply has to specify which properties to bind to which components and the framework does all the moving, validating and transforming of data.
Likewise, when a link is clicked, or a form is submitted, Tapestry does the lion's share of the dispatching.  Ultimately, the developer supplies a method to invoke when a link is clicked, or a form submitted (this is called a "listener method").  Tapestry handles all of the work between the incoming request, routed through a Servlet, right up to the point the listener method is invoked.   The developer simply supplies the method; Tapestry does all the work of building URLs and specifying names and values for query parameters.
Simplicity
As the previous few examples have shown, Tapestry applications will be simpler, and have significantly less code, than equivalent applications using other technologies.  Tapestry simplifies web application development by offloading all the complexity into the framework.
As the examples in the following chapters will show, a Tapestry developer is responsible for succinctly telling the framework what to do.  The framework is responsible for figuring out how to do it.
Reuse
Tapestry supports a level of reuse unparalleled in other web application environments.  Tapestry components are fully encapsulated; they are true "black boxes" that provide carefully defined functionality.  Tapestry components declare their API in terms of a list of named parameters (each of which may be optional or required). 
By describing components in terms of parameters only, it is easy to create components that can be adapted to any page within a particular application or even create components useful in a wide range of applications.
The Tapestry framework provides support and services to components, allowing individual components to work together to form complete pages.  Tapestry supports component libraries, distributed as Jar files, even when the components use images (also distributed inside the Jar) or complex client-side JavaScript.
Reuse is not an add-on in Tapestry, or a mere theoretical possibility; Component reuse was designed into Tapestry from day one.
Reduced Coding
In a typical Java web application, the majority of coding falls into the category of "plumbing".  This is code that does mundane things like reading query parameters and converting the values for assignment to application object properties, constructing URLs with query parameters, storing and retrieving server-side state into the HttpSession object and the like.
In fact, percentage wise, the amount of application-specific code in a Java web application, even in the presentation layer, is very, very small.  The vast majority of code is performing these simple "plumbing" operations.  These bits of plumbing show up as a few lines here, a few lines there, distributed across all the classes of the application, but they build up.  Worse, it is very hard to unit test Servlets
 effectively, which means it is relatively easy for incompletely tested code to make it into a production system.
Even frameworks such as Jakarta Struts don't significantly reduce coding.  Using Struts, you'll code Actions instead of Servlets, but the methods you implement will be similar.  For form and link submissions, Struts may read query parameters and update the properties of a form object, but you, the developer, will still be responsible for reading properties from the form object and updating your application objects … and you still have to write the form object yourself.
Struts, when combined with its JSP tag libraries, implements a partial pull model, but still requires that the developer "seed" things, by storing root objects into the HttpServletRequest as attributes before forwarding to the JSP to render a response.  When multiple Actions share a single JSP, the code that performs this seeding may be duplicated.
Meanwhile, once the query parameters are converted into objects and values, and once those values have been used to update application objects, the final relevant code, the application-specific code, is probably pretty small.  It may be just a few lines of code to validate data before storing it into a database, or to fire off a message to an EJB to initiate a business process.
The core concept of Tapestry is to move all this plumbing into the framework, where it can be coded, verified and stress-tested just once.  Tapestry components build and interpret URLs.  Tapestry form components read object properties when rendering, and update object properties when the form is submitted.  Ultimately, you simply provide the listener method to invoke when a link is clicked or a form is submitted; the listener method is where you put that small slice of application-specific logic.
There's still some amount of overhead in the form of instance variables, accessor methods, and a few methods to deal with persisting server-side state, but these simply don't add up to much.
There is no magic in Tapestry; it doesn't read your mind.  You still have to inform the framework where data comes from and where it goes and even what to do with it … but this is done inside a page specification file, a succinct XML file that describes the page, its components and the configuration of the components.  It's still programming, yes, but its declarative programming, and done not in Java, but in the higher-level XML specification language.
Developer Support
Tapestry is designed from the ground up to be developer-friendly.  Tapestry includes a number of built-in tools to assist developers.  Tapestry catches unexpected exceptions with several layers of handling and reporting.  In a typical web application, when an unexpected exception is thrown while processing a request, the user will be presented with a page showing the name of the exception and a stack trace.
Tapestry does significantly more; it shows the name of the exception, the message associated with it, any JavaBean properties of the exception, and then does the same for any nested exception, as deep as possible, showing a stack trace only at the deepest level.  When the problem is, for example, invalid syntax in a specification file, these exception properties will identify the specific file and line that is in error.
It also displays all the information it can about the request, the application, the Servlet API objects … even all the JVM system properties.  The goal is to provide the developer with the tools needed to quickly diagnose and repair the problem without needing to re-run the application using a debugger.
Tapestry also includes a special component, the Inspector, which is kind of a mini-application for inspecting the structure of a running Tapestry application.  It provides access to the pages, components, parameters and other details of the application.  Again, this provides streamlined access to the kind of data that is usually collected using a debugger, and presents the information in a very accessible format.
Team Development
Tapestry's model of the application, as a cluster of individual pages, meshes well with how medium- to large-scale web applications are developed.  Tapestry allows multiple developers to work in parallel with few hot spots, points of contention, to cause conflicts.  Pages may share some set of components for common elements (page navigation and the like), but unless and until the API for those components change, it will not affect other developers (even when the implementation of the shared component changes significantly).
On the first Tapestry-driven project at Primix (my employer back when the Tapestry project first started), I received and integrated the finished HTML for the Border component, a component which provided the basic look and feel of the application.  The other developers, unaware, synched up their workspaces to the common source code repository and suddenly and unexpectedly, found their pages had the finished look and feel, complete with images, stylesheets and JavaScript popup menus. The point is that making these significant style and functionality changes were contained within a single shared component.  Changing that component internally meant that the changes were shared with all other team members, without affecting any of the pages they were responsible for.
Tapestry also supports a proper division of labor between the "creative" team, responsible for HTML and graphics, and the "technical" team, responsible creating a functional application.  These two teams may not be physically located near each other … they may not even work for the same company.  Streamlining the interaction between these two teams is critical for large-scale applications that may have hundreds of individual pages.
Converting HTML for use in a web application is typically a destructive, one-way process.  HTML mockups provided by the creative team and converted into JSPs by slicing and dicing the mockup, adding lots of JSP specific tags (or even Java scripting) and replacing some of the HTML tags with JSP tags.  Common portions of the JSP may even be moved into JSP include files.
Once instrumented in this way, the JSP will no longer preview properly in a WYSIWYG editor such as HomeSite (though some HTML editors and IDEs have recently provided better JSP-aware preview capability).  This makes later changes to the look and feel of the application, even things as simple as changing a font or the width of a column, a tedious process.  Often, the application must be run so that the creative team member can see if a desired change worked.
Tapestry HTML templates, unlike JSPs, are still completely valid HTML documents, and still preview correctly in WYSIWYG editors.  Within some simple guidelines, discussed in detail in chapter XXX, it is reasonable to have creative and technical developers work on the same HTML templates without breaking each other's work.
What's Wrong with Servlets and JSPs?
Tapestry was created, not to right the wrongs of the Servlet API, but simply to build a different model of web application development on top of it.  There's nothing wrong with what the Servlet API provides in terms of facilities, but it is only a starting point for a framework such as Tapestry.
Many organizations code Java web applications using just the Servlet API.  A properly structured web application consists of a number of servlets that handle incoming requests, and a number of JSPs that render responses.  Servlets are responsible for extracting values from query parameters, managing any server-side state, performing application-specific operations, and finally, selecting and forwarding to a JSP to render the response.
The Jakarta Struts framework also builds on the Servlet API, in a much less ambitious way than Tapestry does.  Struts "rounds out" the rough edges of the Servlet API, adding a few select features, supported by a JSP tag library.
Like Tapestry, Struts filters all application requests through a single servlet.  The servlet dispatches to a specific Action, a class provided by the developer.  Actions, however, are all but indistinguishable from servlets in st
yle and implementation.  Like servlets, they must be stateless, containing no data specific to any individual user of the overall application.
Struts provides assistance when decoding query parameters, using form beans.  Query parameters contain values either encoded into a URL, or passed up from an HTML form.  The Struts configuration file for the application will link Actions to form beans.  When a request for the Action is processed, Struts will extract query parameters from the request and assign them to properties of the form bean, doing necessary conversions as needed.  This can replace a good amount of code related extracting query parameters from the request, and performing conversions on them.
Struts provides an abstraction that separates an Action from the JSP that renders a response.  An Action must return a forward, an object that will next process the request.  Typically, the forward maps to a JSP, which will render the HTML response returned to the client.  A forward can also be another Struts Action. Struts can use other technologies to render responses, such as the Velocity template engine.
It is quite possible to create applications using just the Servlet API, or by using Struts.   For small, simple applications, this is quite reasonable.  Likewise, using JSPs can also be effective, at least initially.
By simple, I mean applications that do not have a lot of duplicated functionality between pages.  As long as the application falls into the category of "form on page A submits into result on page B" the interactions between the servlets (or Actions) and the JSPs are manageable.  This is the domain of demos and tutorials, but is rarely the domain of real applications.
Real applications have "fixtures", common features that appear on many pages.  Real web applications have consistent navigation bars, search forms, login links … even banner ads.  In the world of JSP, some of these fixtures can be implemented using JSP includes, or as custom JSP tags.
For output-only fixtures, these solutions do work.  For example, a common fixture may display an error message in a special font, perhaps with a graphical warning symbol.  This might be used when validating an input form, to indicate missing values or input errors.  Such as fixture could easily be implemented using a custom JSP tag.
The more interesting, and problematic, fixtures are interactive.  A common example is a "paging component" used on many application pages, to allow the user to page through long lists of results one page at a time.  Such as control may have links to jump forwards and backwards through the list of pages and may include a form or other control for controlling how many items are displayed on each page.
Building such a component in a flexible way can be a challenge.  A paging component will have some internal state:  how many items per page?  What page in the sequence is being displayed?  It must be parameterized so that different sets of data can be displayed using it.  To be truly useful, such a component must be reusable throughout the application.
Having a component with interactivity is a challenge.  Quite often, the component will be used on a page that requires setup before the JSP can render a response.  This setup is storing objects as request attributes, so that the JSP can access them … perhaps the list of results to be displayed by the paging component is one of these attributes.
Making this paging component work requires either that the component has special knowledge of the page that contains it, or that the page has special knowledge of the needs of the component.  If the component has its own servlet to handle interactions (such as clicking the "next page" link), then the component needs to be connected, somehow, to the page that contains it, so that it can invoke setup code needed by the page's JSP.  This could be another servlet that the paging component must forward to.  This second servlet performs setup and, finally, forwards to the JSP to render the response.
Alternately, the page may have to provide the component with a servlet to invoke when component interactions occur.  This page-provided servlet has to invoke code, provided by the component, to allow the component to update its internal state, and then perform setup and forward to a JSP to render the response.
What's going on here is that there is an only tenuous connection between the simple notion of a "page" and the servlets and JSPs that make up the page.  If several servlets can each render the same JSP, which of them is the page?  Can a JSP that requires setup by a servlet be a page?  There needs to be a more formal concept of a page, of a component within a page, and of the setup and render process for the page.  These concepts exist formally in Tapestry, but do not exist in the Servlet API, or within Struts.
The dispatch model used by the servlets and Struts Actions is purely at the level of identifying an operation.  What object, or objects to operate on is left open; it is the developer’s responsibility to define query parameters when constructing URLs, and to interpret those query parameters within the servlet (or Action).  By contrast, Tapestry's dispatch model is component-oriented; it identifies pages or components within pages, to trigger behavior in.
Linking all these pages and fixtures together purely as URLs and query parameters has its share of pitfalls as well.  When coding a traditional, non-servlet, application, the Java compiler can identify mismatches, such as a change in the name of a method.  This means that errors are caught at compile time.  Modern sophisticated IDEs don't even wait that long, they identify errors as soon as the incorrect method name is typed.
Likewise, if one developer on a team changes the name or signature of a method, a recompile of the application will generate errors that guide the developer to existing code that must be updated to account for the change to the method.  There is a strong, explicit dependency that can be checked at compile time, during development.
When the interface between developers is expressed in terms of a URL and query parameters, no such safeguards exist.  For example, an application may include search forms on many pages that all submit to a single servlet to perform the search and display the results.
If the developer of the search form servlet changes the name of the servlet, or changes the name of any of the query parameters expected by the servlet, this will invisibly break all the uses of the search form on all the pages in the application.  This will require searching for affected JSPs and manually fixing them, with no compile-time support that every occurrence was found and fixed.  Errors may only be discovered during system testing … or worse, in production.
Tapestry ensures that these kind of page-to-page interactions occur in Java code.  A listener method for each individual search form would invoke methods on the search page to initiate the search and render the response.  A change to the method's name or signature would be caught at compile time, just like any traditional Java application.
Summary
Tapestry is a uniquely powerful way to create web applications in Java; freeing developers to work in traditional object-oriented fashion when developing applications for the very non-traditional web environment.  In the following chapters, we’ll visit all these features of Tapestry and show how Tapestry expands developer productivity, allowing developers to focus on the details of the application, and not on the trivia of web applications and the Servlet API.	

PAGE  2


PAGE  9



Author’s Template 	Manning Publications Co.		 PAGE 2

	
Author’s Template 	Manning Publications Co.	 PAGE 9








&F
&F
&F
&F
&F
&F
&F
&


&F
&


&F

&

&

ð
ð
Þaæ¦(





&F
&F
&F
&F
&F
&F
&F
&


&F
&


&F

&

&

ð
ð
Þaæ¦(





od

&F
&F
&F
&F
&F
&F
&F
&


&F
&


&F

&

&

ð
ð
Þaæ¦(





od
od

od
od
od






í†À@





í†À@

Index: Tapestry-Outline.doc
===================================================================
RCS file: /cvsroot/tapestry/TapestryBook/doc/Tapestry-Outline.doc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
Binary files /tmp/cvsfxqRCe and /tmp/cvsA6Kbrk differ



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.