12.1. Server-Side Code GenerationAutoGenerated, CodeGen, Framework, Library Figure 12-1. Server-Side Code Generation12.1.1. Developer StoryDave's creating a web app with a trendy new server-side framework, ZeroWeb. The framework lets him write everything in Java as if he's writing a standalone GUI application. It's capable of using that code to generate a conventional edition of the application, An Ajax edition, a desktop edition, andfor an extra $99.95a smartphone app too. 12.1.2. ProblemHow do you avoid using HTML and JavaScript? 12.1.3. Forces
12.1.4. SolutionAutomatically generate HTML and JavaScript from server-side code. You write code in a standard server-side language like Java and it's converted to HTML and JavaScript. Depending on the framework, you might not need to code directly in HTML or JavaScript at all. Since you're unlikely to create such a framework yourself, this pattern relies on a certain category of publicly available Ajax framework (see Appendix A). In the case of all code being auto-generated, the code is something like a conventional desktop application. Widgets and event handlers are defined, and the browser generates the appropriate HTML, along with XMLHttpRequest Calls (Chapter 6) and general JavaScript handling. As well, the framework will often generate Ajax Stubs to deal with incoming calls and pass them to appropriate application code. In other frameworks, the approach is more mixed. The framework might let you create a Slider with just a single tag, for example. But in the tag, you'll specify a JavaScript function to be called whenever the slider value changes. There are several arguments for Server-Side Code Generation:
However, code generation does comes at a cost to usability. Look at it this way: anything you could generate from the server, a skilled developer could also hand code. The reverse is not true; given enough time and talent, it's always possible to build a custom solution that's superior in terms of usability. So, to be worthwhile, the framework must add enough value in terms of productivity and support for non-experts, to be compensated for the drop in usability. Whether this can be achieved really depends on two things: how much users will gain from a custom-built application, and how much of a boost the framework will give you. On the second point, consider a few counter-arguments to the benefits above:
An interesting variant of Server-Side Code Generation is "Browser-Side Code Generation"; the Backbase framework (http://backbase.com) is a case in point. With Backbase, the server outputs a specialized markup language, BXML, and the browser converts it into HTML, CSS, and JavaScript. I expect the full-featured frameworks to become particularly prominent on intranet applications, where new functionality is often more critical than usability, and users can be trained to work around problems. Hand-coded HTML and JavaScript is more likely for public dot-coms where alternatives are abundant and the pressure of competition means it's critical to optimize the user interface. In those environments, there is still some role for Server-Side Code Generation, but mainly as a helper for very specific tasks and with some flexibility, rather than as the overarching architectural style. 12.1.5. Real-World ExamplesThese examples describe frameworks that support this pattern in different ways. 12.1.5.1. Echo2Echo2 (http://www.nextapp.com/products/echo2/) is an open source framework by NextApp, which takes the "whole hog" approach and generates all HTML and JavaScript from Java source code. An online demo (http://demo.nextapp.com/InteractiveTest/ia) shows how Echo2's user-interface widget classes manifest themselves in the browser (Figure 12-2). Figure 12-2. Echo2 demo12.1.5.2. Ruby On Rails frameworkRuby On Rails (http://rubyonrails.com) is a web framework that embeds Ruby inside web pages. That in itself is not new, but Rails offers built-in helper classes to speed up page construction. They often lead to the Scriptaculous library being invoked, but the programmer doesn't use it directly. For example, you can issue an XMLHttpRequest Call followed by Display Morphing, using the following embedded Ruby call (http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html): <%= link_to_remote( "click here", :update => "time_div", :url =>{ :action => :say_when }) %> 12.1.5.3. BackbaseBackbase (http://backbase.com/) is a commercial framework that extends standard XHTML with Backbase-specific tags (BXML). A Backbase client-side framework translates the BXML to HTML, CSS, and JavaScript, making it easy to implement many standard Ajax features. So there's a widget tag that looks like this: <b:panel> and another tag for various visual effects: <s:fxstyle> There are several innovative demos available from the Backbase homepage (http://www.backbase.com/#home/pulldown/demos.xml[2]) (Figure 12-3). On the server, Backbase offers programming interfaces for both .NET and JSF and offers visual development tools for Visual Studio .NET as well. As with the other tools here, the developer doesn't have to deal with HTML or JavaScript, but the framework also lets people customize the generation for specialized browser appearances and behavior. Note that, as mentioned earlier in the "Solution," Backbase is actually a kind of client-side, rather than server-side, code generation. Figure 12-3. Backbase Travel demo12.1.5.4. AjaxTags libraryAjaxTags (http://ajaxtags.sourceforge.net/) is a collection of JSP tags to ease development of Ajax interaction. There's an <autocomplete> tag for Suggestion and an <ajax:update> field to perform a Display Morphing (Chapter 5) with the response of an XMLHttpRequest Call (Chapter 6). 12.1.5.5. Comfort.ASP libraryComfort.ASP (http://www.daniel-zeiss.de/ComfortASP/) takes an unusual approach by automatically adding Web Remoting (Chapter 6) to a conventional, non-Ajax application. By instrumenting the HTML, the framework can intercept standard form submissions and transform them into XMLHttpRequest Calls. By monitoring server output, Comfort's server-side script can respond to these calls by sending back only deltasthe difference between the current HTML and the desired HTML. 12.1.6. Code Example: Echo2 Number GuessEcho2 (http://www.nextapp.com/products/echo2/) provides full source for a tutorial application, Number Guess (http://www.nextapp.com/products/echo2/doc/tutorial/application.html). The user guesses a number between 1 and 100, the application tells them if it's higher or lower, the user tries again, and so on. Note that the code is available, but there's no online demo at present. An Echo2 application is run as a Java servlet extending Echo2's WebContainerServlet. The superclass takes care of most interaction; the concrete servlet must do just one thing: declare an ApplicationInstance. In Echo2, an ApplicationInstance object is the application state for a given user: /** * Guess-a-number Tutorial Application Servlet Implementation. */ public class NumberGuessServlet extends WebContainerServlet { /** * @see nextapp.echo2.webcontainer.WebContainerServlet#newApplicationInstance( ) */ public ApplicationInstance newApplicationInstance( ) { return new NumberGuessApp( ); } } The main application object initializes a new window and controls two top-level user-interface elements: a GamePane on startup, which is where the main action takes place, and a CongratulationsPane upon victory:[*]
public class NumberGuessApp extends ApplicationInstance { private Window mainWindow; public Window init( ) { mainWindow = new Window( ); mainWindow.setTitle("Echo2 Guess-A-Number"); startNewGame( ); return mainWindow; } void startNewGame( ) { ... mainWindow.setContent(new GamePane( )); } void congratulate(int numberOfTries) { mainWindow.setContent(new CongratulationsPane(numberOfTries)); } } class GamePane extends ContentPane implements ActionListener { ... } class CongratulationsPane extends ContentPane implements ActionListener { ... } The GamePane is built up by adding subelements and registering events. It acts as an ActionListener for the buttons it contains; hence, there's an actionPerformed event, which encapsulates the guess evaluation logic. The code illustrates that a framework like Echo2 paves the way for a style of web programming that's almost identical to traditional desktop coding. class GamePane extends ContentPane implements ActionListener { private int randomNumber = ((int) Math.floor(Math.random( ) * 100)) + 1; private int lowerBound = 1; private int upperBound = 100; private int numberOfTries = 0; private TextField guessEntryField; private Label statusLabel = new Label( ); private Label countLabel = new Label("You have made no guesses."); private Label promptLabel= new Label("Guess a number between 1 and 100: "); private int guess; GamePane( ) { super( ); Column layoutColumn = new Column( ); layoutColumn.setCellSpacing(new Extent(10)); add(layoutColumn); ... Button submitButton = new Button("Submit Your Guess"); submitButton.setActionCommand("submit guess"); submitButton.setForeground(Color.BLACK); submitButton.setBackground(Color.GREEN); submitButton.setWidth(new Extent(200)); submitButton.addActionListener(this); layoutColumn.add(submitButton); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand( ).equals("new game")) { ((NumberGuessApp) ApplicationInstance.getActive()).startNewGame( ); } else if (e.getActionCommand( ).equals("submit guess")) { ++numberOfTries; ... if (guess == randomNumber) { ((NumberGuessApp) ApplicationInstance.getActive( )) .congratulate(numberOfTries); } else if (guess < 1 || guess > 100) { statusLabel.setText("Your guess, " + guess + " was not between 1 and 100."); } else if (guess < randomNumber) { ... } ... } } } 12.1.7. Alternatives12.1.7.1. Browser-Side TemplatingBrowser-Side Templating (Chapter 11) is a form of Client-Side Code Generation, an alternative to Server-Side Code Generation. 12.1.8. Related Patterns12.1.8.1. HTML MessageServer-Side Code Generation produces HTML responses, so is technically one form of HTML Message (Chapter 9). It's also a form of JavaScript Response, the variant described in On-Demand JavaScript (Chapter 6). However, the emphasis in those patterns is on directly created HTML and JavaScript, rather than delegation to a generation framework. |