Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 62 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
62
Dung lượng
1,17 MB
Nội dung
280 CHAPTER 9 Velocity template = getTemplate("ScheduleEntryView.vm"); } else { scheduleDb.addRecord(newItem); RequestDispatcher dispatcher = request. getRequestDispatcher( "/viewschedule"); dispatcher.forward(request, response); } } catch (ScheduleAddException sax) { log("Add error", sax); } catch (ParseErrorException pex) { log("SaveEntry: ", pex); } catch (ResourceNotFoundException rnfx) { log("SaveEntry: ", rnfx); } catch (Exception x) { log("SaveEntry: ", x); } return template; } private void populateContext(Context context, ScheduleItem newItem, ScheduleDb scheduleDb, List validationErrors) { context.put("scheduleItem", newItem); context.put("errors", validationErrors); context.put("eventTypes", scheduleDb.getEventTypes()); } private ScheduleItem populateItemFromRequest(HttpServletRequest request) { ScheduleItem newItem = new ScheduleItem(); String duration = request.getParameter("duration"); try { if (duration != null) newItem.setDuration(Integer.parseInt(duration)); } catch (NumberFormatException nfx) { log("Conversion error:duration", nfx); } String typeKey = request.getParameter("eventTypeKey"); try { if (typeKey != null) newItem.setEventTypeKey(Integer.parseInt(typeKey)); } catch (NumberFormatException nfx) { log("Conversion error:eventTypeKey", nfx); } String start = request.getParameter("start"); if (start != null) newItem.setStart(start); String text = request.getParameter("text"); if (text != null) Populates the ScheduleItem from request parameters C Evaluating Velocity 281 newItem.setText(text); return newItem; } } This servlet extends ScheduleSaveBase to provide access to the boundary class. The primary method in this class is handleRequest() . It populates the new item from request parameters via the populateItemFromRequest() method and vali- dates the new item, using the validation code in the entity class. If the validation fails, it populates the context with the invalid schedule item entity, the error list, and the list of event types (to populate the select field). It then re-merges with the user interface template. If the record validates successfully, the servlet redirects to the main view page. Notice that, in the successful case, the Velocity servlet returns null. The framework handles this, not by merging with a template, but by respect- ing any redirects or forwards. This method matches request parameters to the fields of the scheduleItem entity object, populating it with the values entered by the user. 9.5 Evaluating Velocity If Velocity is considered a framework, it is a very small one. However, it is a cohe- sive way to handle user interface generation. As with any framework, the quality of the documentation and samples dictates how easy it is to learn. Each framework must also justify its existence either by making a hard job easier or by creating something you couldn’t create without it. Velocity takes the former approach. 9.5.1 Documentation and samples The documentation for Velocity sets the gold standard for any product, commer- cial or open source. It consists of a few “getting started” guides and similar docu- ments. However, the meat of the documentation is the developer’s and the user’s guides. The developer’s guide walks through setup, architecture, and issues like “To Singleton or Not to Singleton.” It is well written and easy to follow. The heart of the documentation for the Velocity Template Language is in the user’s guide. It is a narrative-style reference that explains the capabilities and char- acteristics of the language. It is easy to follow and written at a level that makes it easy for web-savvy nonprogrammers (for example, web designers) to learn every- thing they need to know about Velocity. B C 282 CHAPTER 9 Velocity The samples are also excellent. The user’s guide has numerous embedded sam- ples, and the framework itself includes samples for more esoteric uses of Velocity (such as generating XML using Velocity or using Velocity outside web applications). 9.5.2 Using Velocity Velocity successfully straddles the line between power and ease of use. It is easy to use yet yields more benefits than JSTL or “vanilla” JSP. It doesn’t try to encapsulate HTML controls into custom tags like most of the frameworks do, so it does require extra coding for complex elements like tables and selects. Unfortunately, no good debugging support is available for Velocity except the log files maintained by Velocity itself. However, that is sufficient. Velocity never attempts to do anything complex enough for serious debugging. Velocity can replace virtually any of the user interface elements present in the other frameworks we’ve covered (except perhaps Tapestry). If you use Velocity in Struts, the actions create the template engine and perform the merge instead of forwarding to a JSP. WebWork has a property setting for using Velocity as the user interface layer. This highlights one of the best things about Velocity: it is highly cohesive and doesn’t have a big impact on the other parts of the architecture of the application. The primary difference (besides the use of VTL on the page) is the presence of the Context object. However, you must pass information from the controller to the user interface somehow, and the Context is as good as any other mechanism. 9.6 Summary This chapter discussed Velocity, the Java-based template language for generating user interface elements. Velocity defines a simple but powerful scripting language that is executed on the server during page render, generating HTML or other markup, such as XML. The schedule application we built in this chapter used Velocity as the user interface layer. We demonstrated several techniques, including building an HTML <select> control using the Velocity Template Language and iterating over collections. Velocity is a highly cohesive tool for assisting in the user interface portion of Model 2 applications. It doesn’t impose itself on the application to the exclusion of other technologies. It is a popular framework for exactly those reasons. In the next chapter, we look at Cocoon, a publishing framework and a web application framework. 283 Cocoon This chapter covers ■ The Cocoon publishing framework ■ Cocoon design and architecture ■ Building Model 2 applications with Cocoon ■ Evaluating Cocoon 284 CHAPTER 10 Cocoon Cocoon is more than one type of framework. It provides some of the same facili- ties as the other web frameworks we’ve discussed, but Cocoon contains an entire additional personality: that of a publishing framework. Cocoon automatically trans- forms documents based on the request context. It presents a new kind of applica- tion service, leveraging XML technologies to create web sites with unprecedented flexibility. It also embodies another dimension of Model-View-Controller, in which the framework handles all the view generation automatically. Cocoon is also a complicated framework. It relies on XML technologies, such as Extensible Stylesheet Transformation Language ( XSLT). Because it does so much, there are myriad configuration and development issues. As such, this chap- ter serves only as an introduction to Cocoon in both its guises as a publishing framework and as a web application framework. A working knowledge of XML technologies will help but shouldn’t be neces- sary. Because of the complexity of the framework, we’re going to build only a part of the schedule application with this framework. 10.1 Overview Stefano Mazzocchi founded the Cocoon project in 1999 as an open-source Apache project. It started as a simple servlet for on-the-fly transformations of XML documents using Extensible Stylesheet Language (XSL) stylesheets. It was based on the memory-intensive Document Object Model ( DOM) API, which loaded the entire document in memory to process it. This quickly became a limiting factor. To drive the transformations, the XSL stylesheet was either referenced or embed- ded inside the XML document. While convenient, it caused maintenance prob- lems for dynamic web sites. To solve these problems, Cocoon 2 included a complete rewrite of the frame- work, incorporating the lessons learned from Cocoon version 1. Cocoon 2 changed from DOM to the much more memory- and processing-thrifty Simple API for XML Processing (SAX) technique of parsing the XML documents. It also created the concept of a pipeline to determine the processing stages that a docu- ment must traverse, and included numerous performance and caching improve- ments. Legend has it that the time elapsed between the two releases was partially due to the principal developer deciding to go back to college to complete his degree. Only in the open-source world can this happen to a state-of-the-art piece of software! The architecture 285 For this chapter, we’re using Cocoon version 2.0.4. You can download Cocoon at http://xml.apache.org/cocoon/. This site allows you to download either Cocoon 1 or 2, although Cocoon 1 is provided only for backward compatibility. 10.2 The architecture Cocoon’s two parts, the publishing and web application frameworks, are related at the core level but may not seem so from the surface. It turns out that the web framework is another aspect of the publishing framework. For the purposes of architecture, we’ll show them as distinct elements. First, we’ll discuss the architec- ture of the publishing framework, then of the web framework. 10.2.1 The publishing framework A publishing framework is a tool that automates part of the generation of client- specific documents from a common base. Figure 10.1 shows this architecture. In the diagram in figure 10.1, two separate client devices are making a request of the publishing framework, which is running as part of a web application. The browser requests the document. The publishing framework notifes the user agent of the request (which is part of the HTTP header information) and the requested resource. Once it starts to return the resource, it applies an XSLT transformation to it and generates an HTML document suitable for the browser. A wireless device (like a cell phone) makes a request for the same resource from the same publish- ing framework. However, because the user agent is different, a different stylesheet Publishing Framework Browser Transformation XML Data (static or dynamic) XML HTML Content Producer HTTP XML HTTP WML Figure 10.1 A publishing framework performs automatic transformations depending on the device making the request. 286 CHAPTER 10 Cocoon transformation is applied and the cell phone receives a Wireless Markup Lan- guage ( WML) document. The benefits of a publishing framework are twofold. First, for the developers of the content, they no longer have to worry about creating different types of con- tent for different devices. The developers produce XML documents. Stylesheet designers create XSLT stylesheets for the various types of devices the application must support. This step is completely separate from the content-generation step. The second benefit is the flexibility of the application. When a new device appears, the content designers don’t have to change anything about the applica- tion. A new stylesheet is all that is required to support the new device. The problems with this approach are also twofold. First, the transformation process is very resource intensive on the servlet engine. Parsing text and applying transformations in XML takes a great deal of processor resources. Memory man- agement has gotten better with Cocoon moving to SAX instead of DOM, but it is still an issue. The other problem lies with the complexity of the XSLT stylesheets. It is an entirely new language for developers to learn, and it is not very readable or friendly. Currently, few tools do anything to ease the process of creating the stylesheets. For the time being, developers must create the stylesheets by hand. Because good stylesheet developers are hard to find, the practicability of wide use of publishing frameworks is limited. However, tool support will eventually come and the process will become much easier. Pipelines Cocoon 2 introduced the idea of a pipeline to handle a request. A pipeline is a series of steps for processing a particular kind of content. Usually, a pipeline consists of several steps that specify the generation, transformation, and serial- ization of the SAX events that make up the generated content. This is shown in figure 10.2. request File Generator XSLT Transformer HTML Serializer response SAX SAX Figure 10.2 A pipeline is a series of steps that contribute to the transformation of one type of content to another. The architecture 287 As the request is processed, it moves from stage to stage in the pipeline. Each stage is responsible for a part of the generation or transformation of the content. Cocoon allows you to customize the steps a particular type of content incurs. Between each stage of the pipeline, SAX events are fired so that you can further customize the processing of the content. In figure 10.2, a file is generated, passed to an XSLT transformation, and then passed to an HTML serializer to produce the output file. The result is the automated transformation of an XML document into an HTML document. A pipeline may consist of four types of steps (generator, transformer, aggrega- tor, and serializer), which always occur in the same order. You can, however, apply multiple processing steps of the same type at each stage. This is shown in figure 10.3. The types of processing to which content is subjected is defined in a sitemap. It is the major configuration document for the publishing framework. The format of this document is covered in section 10.3.2. Generator source document stylesheet Transformer Aggregator Serializer stylesheetstylesheet request output document Figure 10.3 A document goes through up to four steps (with as many iterations as possible through each step) during the transformation. 288 CHAPTER 10 Cocoon 10.2.2 The web framework As a web framework, Cocoon is also a publishing framework. You could configure Cocoon on a case-by-case basis to apply custom stylesheets to your content to pro- duce HTML documents. If this were the extent of the web framework, you would spend most of your time getting the plumbing correct. In addition, you would have to write all the stylesheets yourself. Wouldn’t it be better to create a set of stylesheets that always apply to web-development content? That is what the design- ers of Cocoon have done. You can create Model 2 web applications using built-in classes and stylesheets, relying on the existing transformers for most work, and then customize them for special circumstances. The web framework aspect of Cocoon is shown in figure 10.4. For a Cocoon web application, the user makes a request to the Cocoon servlet. The servlet determines that it is a request for web-application content via the sitemap and instantiates a matching action. In this case, the sitemap serves the same purpose as the Struts configuration document. The action references model beans, both boundary and entity, and performs work. The resulting information is packaged into a standard web collection (request, session, or application) and Browser <<controller>> Cocoon Servlet sitemap <<view>> XSP Action Data Model Beans 1) invoke 3) invoke 6) return 4) create 5) invoke 2) read 7) transform 8) result XSLT 7) transform Figure 10.4 The Cocoon servlet already knows how to handle common Model 2 web-application content. Key concepts 289 passed back to the Cocoon servlet. It then selects the appropriate user interface file and transformation from the sitemap and forwards the request to it. The transformation is applied, and the response is sent back to the user. Cocoon has created the concept of Extensible Server Pages ( XSP). These pages are similar to JSPs but use a stricter XML syntax and some different con- structs on the page themselves. The differences are covered in section 10.3.3. 10.3 Key concepts To understand the web framework aspect of Cocoon, you must understand some of the publishing framework as well. In this section, we discuss some key concepts of the publishing framework, move to configuration and the sitemap, and then examine web actions and XSP. 10.3.1 The publishing framework XML is a data-centric document format, whereas HTML is view-centric. The prob- lem with the data in HTML documents is that it has no intrinsic meaning beyond the presentation tags. For example, if you search the World Wide Web for infor- mation on “cardinals,” you will find documents on birds, baseball, and churches. The search engines cannot determine what kind of “cardinal” you are searching for because the documents returned contain only presentation markup. XML solves this problem by creating tags that have inherent meaning. Eventually, XML needs to be displayed or transformed into another document format, which is the purpose of XSL and XSLT. XSL defines a syntax for transform- ing XML documents into other formats, such as other XML or HTML documents. This transformation is the core of how a publishing framework functions. Transformations To understand the publishing framework aspect of Cocoon, you must understand how XSLT transformations work. XSL is an open standard for applying transforma- tions to XML documents to change them into another document type. It is used for XML to XML, XML to HTML, XML to WML, and XML to binary format (like PDF) transformations. XSL can take any XML document and transform it into another document with the same information (or a subset of it). Consider the XML document in listing 10.1. It contains a short list of planetary information. (I’ll bet you didn’t already know that most of the moons of Uranus were named after Shakespearean characters!) [...]... number of comments, but there is still more content than comments Even a simple sitemap can easily stretch to hundreds of lines Fortunately, Cocoon documents the contents of the sitemap well You’ll learn about the pertinent parts of the sitemap for the schedule application in section 10.4.1 The sitemap consists of two parts—components and pipelines—and pipelines are made up of components The first part of. .. second part of the sitemap consists of the pipeline definitions Pipelines specify how the processing of content is done In most cases, pipelines consist of a generator, zero or more transformers, and a serializer The invocation of a pipeline depends on a URI mapping either of a single document or by extension or wildcard, if you want a particular pipeline to apply to a variety of content Examples of several... application, then that would affect Part A, Part D, Part E, and Part W And, of course, it’s a dependency tree, so Part A’s dependencies must be managed, and Part D’s, and so on For many organizations, if a bus hits The Guy, they need to rewrite the application from the ground up This is the dark side of RAD development However, that isn’t to say it is always a bad thing If you have a web application that I Is... some of which have survived several iterations of the framework If that covers a complex part of the framework, you are on your own The quality of the documentation is more important than the quantity Some frameworks have both (like Velocity), but that is rare Well-written documentation is as hard (or harder) to come by as well-written code One of the shortcomings of Cocoon is the confusing format of. .. the documentation Another documentation pitfall is out -of- date material Sometimes the documentation doesn’t stay current with the code base The reverse is true in Cocoon In several sections on web development, the documentation is ahead of the release of the framework To take advantage of some of the documented features in the significantly updated web framework, you must download and build the latest... Model 2 apply here (and that encompasses most of the frameworks in this book) 11.1.2 Documentation We covered this topic individually for each of the frameworks in previous chapters Particularly for open-source projects, the quality of the documentation is critical because producing it is not the most enjoyable part of building the framework As the complexity of the framework increases, the documentation... application, this example should give you a feel for what web development looks like in Cocoon Once you understand how to set up pipelines and the interaction of the publishing framework with the web framework, the web coding is straightforward 10.5 Evaluating Cocoon Cocoon is the most complex framework in this book Of course, it is more than just a web- application framework, which is almost an afterthought... the prime execution context in Cocoon They are used in webapplication development, much like the actions in Struts Defining a pipeline with embedded actions provides most of the programmability for the way the pipeline execution proceeds A couple of example action declarations are shown in listing 10 .6 Listing 10 .6 Actions are the execution context of a Cocoon pipeline . perti- nent parts of the sitemap for the schedule application in section 10.4.1. The sitemap consists of two parts—components and pipelines—and pipelines are made up of components. The first part of the. responsible for a part of the generation or transformation of the content. Cocoon allows you to customize the steps a particular type of content incurs. Between each stage of the pipeline, SAX. framework, which is running as part of a web application. The browser requests the document. The publishing framework notifes the user agent of the request (which is part of the HTTP header information)