You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by jo...@apache.org on 2001/03/03 09:23:52 UTC

cvs commit: jakarta-velocity/xdocs/ymtd/images hello-jsp.gif hello-jsp2.gif hello-velocity.gif jsp-nasa-crash.gif

jon         01/03/03 00:23:51

  Added:       xdocs/ymtd ymtd-conclusion.xml ymtd-embedded.xml
                        ymtd-error-handling.xml ymtd-generation.xml
                        ymtd-implementation.xml ymtd-javabeans.xml
                        ymtd-sampleapp.xml ymtd-saying-hello.xml
                        ymtd-taglibs.xml ymtd.xml
               xdocs/ymtd/images hello-jsp.gif hello-jsp2.gif
                        hello-velocity.gif jsp-nasa-crash.gif
  Log:
  first round checkin of you make the decision. woo hoo!
  
  Revision  Changes    Path
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-conclusion.xml
  
  Index: ymtd-conclusion.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Conclusion</title>
    </properties>
  
  <body>
  
  <section name="Conclusion">
  
  <p>
  We hope that you enjoyed this little excursion into the land of
  alternatives. Every developer and user in the world has their own
  opinion on the "right way" to do things. The goal of this document is
  not to force anyone to believe that the Velocity way is the "Right Way",
  but instead to let people see the differences between the two approaches
  and allow one to develop their own opinions about the tools that are in
  use today.
  </p>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-implementation.html">Implementation</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd.html">Home</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-embedded.xml
  
  Index: ymtd-embedded.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Embedded Usage</title>
    </properties>
  
  <body>
  
  <section name="Embedded Usage">
  
  <p>
  This is an example of using Velocity within an application.
  </p>
  
  <source><![CDATA[
      OutputStreamWriter writer = new OutputStreamWriter(output, encoding);
      Template template = RunTime.getTemplate(filename);
      template.merge( context, writer );
  ]]></source>
  
  <p>
  In other words, the above is translated into:
  </p>
  
  <ol type="1" start="1">
  	<li>Create a Writer.</li>
  	<li>Ask the Velocity RunTime to retrieve the Template.</li>
  	<li>Merge the Context with the Template.</li>
  </ol>
  
  <p>
  Velocity templates can contain *any* type of data. It can be XML, SQL,
  HTML, plain text, internationalized text, anything. The parser is very
  robust in terms of only parsing out what it cares about and ignoring the
  rest. As demonstrated above, it is possible to embed Velocity's template
  engine into any other Java code. The advantage of this is that it
  provides users with a single template system for all sorts of uses.
  </p>
  
  <p>
  For example, in the <a
  href="http://java.sun.com/j2ee/blueprints/sample_application/index.html">PetStore
  example</a> on the J2EE website, there is a JavaBean which sends an
  email confirmation when an order is complete. The unfortunate part about
  this example is that in order to change the contents of the email, one
  needs to edit Java code. Of course this example could have been done
  differently to use a JSP based template as the base format. However, the
  implementation of this is more difficult than simply creating a <a
  href="http://www.working-dogs.com/turbine/cvsweb/index.cgi/turbine/src/java/org/apache/turbine/util/velocity/">Java
  object</a> which resides in the Context that can take as arguments the
  template to render.
  </p>
  
  <p>
  Another example of this is the <a
  href="http://jakarta.apache.org/velocity/texen.html">Texen</a> and <a
  href="http://jakarta.apache.org/velocity/anakia.html">Anakia</a> tools
  that come with Velocity. The advantage again is the ability to use
  Velocity as an embedded tool to produce other useful applications that
  are not bound strictly to a web application. While it is most likely
  possible to do this with the JSP engine, it is significantly more
  difficult to do so.
  </p>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-taglibs.html">Taglibs</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-implementation.html">Implementation</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-error-handling.xml
  
  Index: ymtd-error-handling.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Error Handling</title>
    </properties>
  
  <body>
  
  <section name="Error Handling">
  
  <p>
  This is a good one and a fundamental design issue with JSP. The question
  is: How many different types of errors can one get when using JSP? For
  example, because the JSP Servlet is auto generated from a .jsp text file
  and then compiled with a compiler, what happens when there is a
  generation/parsing error or a compile error? The unnecessary complexity
  of JSP actually increases the number of ways to get errors!
  </p>
  
  <p>
  The ugliest aspect of all of this is the fact the errors are reported
  via two different mechanisms. The parser can throw its own set of errors
  and the javac compiler can throw a whole different set of errors and 
  as a result of the layers of generation, errors from the compiler generally
  do not make any sense whatsoever. For example, can you tell me what 
  this error is from?
  </p>
  
  <source><![CDATA[
  org.apache.jasper.JasperException: Unable to compile class: Invalid type
  expression.
                  out.println("JSP is great!")
                             ^
  : Invalid declaration.
                  out.write("\r\n\r\n\r\n");
                           ^
  2 errors
  ]]></source>
  
  <p>
  If you guessed that the error was a result of a missing <code>;</code>
  after the first out.println(), you were correct! Now, put yourself in
  the shoes of someone who has never written or seen a line of Java code.
  Do you think that person could have figured out the error quickly and
  easily? Compound that with the fact that if the error had been on a less
  deterministic part of the file, it is now much harder to find the source
  of the error because there is a level of abstraction from the original
  .jsp file and because there is an intermediate .java file that gets
  generated.
  </p>
  
  <p>
  Again, Velocity does not suffer from these same problems because there
  is no intermediate step and no layers of abstraction.
  </p>
  
  <source><![CDATA[
  <%@ page errorPage="/error.jsp" %>
  ]]></source>
  
  <p>
  JSP also allows one to define an error page that is used if an Throwable 
  exception is thrown during the processing of a page. Doesn't this 
  again break the MVC model?
  </p>
  
  <source><![CDATA[
  <% throw new Exception("oops"); %>
  ]]></source>
  
  <p>
  In order to throw an Exception somewhere in a JSP page, one needs to
  first embed it within a statement. Note: that in this specific case, if
  optimizations are turned on in the compiler, chances are that the entire
  exception would be compiled out. Therefore, a more concrete object must
  be used instead of the "true". This can actually prove difficult if
  using a strict MVC model because instantiation of objects breaks the
  View.
  </p>
  
  <source><![CDATA[
  <%
    if (true) {
      throw new Exception("oops");
    }
  %>]]></source>
  
  <p>
  The reason is that JSP will generate an additional <code>out.println
  ("\r\n");</code> after the Exception. When javac attempts to compile the
  page, another hard to debug error will be reported:
  </p>
  
  <source><![CDATA[
  org.apache.jasper.JasperException: Unable to compile class for
    JSPC:\engines\jakarta-tomcat\work\localhost_8080%2Fjsp\
    _0002ferrorMaker_0002ejsperrorMaker_jsp_3.java:75:
  Statement not reached.
                  out.write("\r\n");
                  ^]]></source>
  
  <p>
  Taking a direct quote out of Jason's book (I couldn't say it better myself):
  </p>
  
  <source><![CDATA[
  In fact, there are many such "gotchas" when using scriptlets with JSP. 
  If you accidentally write a scriptlet instead of an expression (by
  forgetting the equal sign), declare a static variable inside a scriptlet
  (where statics aren't allowed), forget a semi-colon (they're not needed
  in expressions but are needed in scriptlets), or write anything but
  perfect Java code, you're likely to get a confusing error message
  because the compiler is acting on the generated Java code, not on the
  JSP file.  To demonstrate the problem, picture if <%= name %> were
  replaced by <% name %> in errorTaker.jsp.  Tomcat generates this error:
  
  org.apache.jasper.JasperException: Unable to compile class for
    JSPC:\engines\jakarta-tomcat\work\localhost_8080%2Fjsp\
    _0002ferrorTaker_0002ejsperrorTaker_jsp_6.java:91:
  Class name not found.
                   name 
                   ^
  
  Debugging an error like this often requires a programmer to look at the
  generated code to reconstruct what caused the error.]]></source>
  
  <p>
  Velocity does not have of these same problems because it does not allow
  the author to place any Java code within a template. The only things allowed
  in the template are Velocity Template Language (VTL). Everything else is
  ignored by the parser. The only place where one could run into trouble
  within Velocity is if there is a call to a method which throws an
  exception during runtime. For example, this VTL defines a String
  <code>$foo</code> and then attempts to call its <code>substring()</code>
  method on it would throw an <code>IndexOutOfBoundsException</code>:
  </p>
  
  <source><![CDATA[
  #set ($foo = "bar")
  
  #set ($bar = $foo.substring(0,10))
  ]]></source>
  
  <p>
  When the exception is thrown, the parser will stop processing and throw
  that exception up the stack tree where it can be caught in the method
  that caused the parser to execute. At that point, the exception can be
  handled gracefully. This is one of the benefits of using Turbine
  combined with Velocity because of Turbine's design it easy to deal with
  Exceptions in a consistent manner. It is also possible to get this same
  functionality with by using Velocity's included VelocityServlet. The
  Exception will contain the line number and column number in the .vm file
  of where the error happened. Because there is no abstraction like with
  JSP, the line number and column matches up to the error. Also, the only
  tool that will throw the exception is the parser. No need to try to
  debug the cryptic javac messages which are a result of generated .java
  code.
  </p>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-generation.html">Generation?</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-javabeans.html">JavaBeans</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-generation.xml
  
  Index: ymtd-generation.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Generation?</title>
    </properties>
  
  <body>
  
  <section name="Generation?">
  
  <p>
  JSP touts as an advantage that it takes an existing .jsp page and
  compiles that into a Servlet for speed and efficiency reasons. What this
  means is that it first parses the .jsp page into the resulting mess
  below and then it uses javac or your favorite Java compiler (ie: Jikes)
  to compile that Servlet into a .class file which is then loaded by the
  Servlet Engine. Wow, just explaining all of that gave me a headache, how
  about you?
  </p>
  
  <p>
  The point being that using JSP is now a multi step process. The authors
  of JSP have done a good job of hiding this process stuff behind the
  scenes in such a way that you do not even notice it. One simply edits
  the .jsp page in their favorite editor and then uses their browser to
  call the page via a URI which starts the process of transforming it into
  a .class file.
  </p>
  
  <p>
  There are some fundamental issues that are being dealt with in the
  generated .jsp template. The first one is the class name. What happens
  is that the engine needs to produce a name that is unique in order to
  work around class loader issues that might crop up. Therefore, each and
  every time one modifies a .jsp page, a new file is created on disk in
  the temporary directory. Unfortunately, this directory ends up growing in
  size until someone decides to clean it up. The engine could probably do
  this for you, except then it might make the mistake of actually removing
  the wrong file.
  </p>
  
  <p>
  The point being that this whole process of
  edit->transform->compile->load->run is really unnecessary and in
  particular, a bad design. On the other hand, Velocity will simply load
  templates, parse them a single time and then store an Abstract Syntax
  Tree (AST) representation of the template in memory which can then be
  re-used over and over again. The process is simply edit->parse->run. The
  benefit is that Velocity ends up being much faster and it also removes
  the requirement of having a javac compiler and temporary scratch
  directory hanging around. In Velocity, when the template changes, the
  existing cached template is simply replaced with a freshly parsed version.
  </p>
  
  <p>
  Another advantage to Velocity's approach for templates is that the
  actual template data can be stored anywhere, including a database or
  remote URI. By using configurable template loaders, it is possible to
  create template loaders that can do anything that you want.
  </p>
  
  <p>
  A .jsp page is really nothing more than a Servlet. By default, there is
  not a single shred of innovation there with regards to things like error
  handling or overall Model 2 architecture.
  </p>
  
  <p>
  Even without Turbine, Velocity offers several ways to deal with errors.
  Where frameworks such as Struts and Turbine come handy is by providing
  ways of properly dealing with errors. However, due to the fact that
  Struts is based on top of JSP, it also inherits the same amount of
  problems associated with JSP. The next chapter will go into more details
  on that.
  </p>
  
  <p>
  A major problem with the generated code is that it does not check to
  make sure that the output stream is still open before attempting to
  write to it. It also has the issue that if the stream is closed or an
  IOException is thrown while attempting to output to the stream, there is
  no way to catch it without using a specially defined error handler.
  </p>
  
  <p>
  One final problem in the design shown below is that the JSP page only
  catches <code>Exception</code>'s. What if the JSP page throws another
  exception like <code>OutOfMemoryError</code>? The problem here is that
  OOME is based on <code>Throwable</code>, not <code>Exception</code>.
  Therefore, it is much more difficult to catch this exception with just a
  JSP page.
  </p>
  
  <p>
  This nice <a href="./images/jsp-nasa-crash.gif"
  target="newWindow">example</a> provided by our friends at NASA, which
  sends multi-billion dollar equipment through the heavens, is a perfect
  example of why JSP needs better error handling.
  </p>
  
  <p>
  Buffering is also another big issue as constantly writing to the output
  stream is not very efficient.
  </p>
  
  <source><![CDATA[
  <%@ page buffer="12kb" %>
  <%@ page autoFlush="true" %>
  ]]></source>
  
  <p>
  These are examples of telling JSP to buffer the output 12kb and to
  autoFlush the page. Struts+JSP has implemented the MVC model by
  providing the View portion through JSP templates. What part of the MVC
  model do you think that those tags belong? You guessed it, not the part
  where they are being used.
  </p>
  
  <p>
  Velocity's approach to dealing with this issue is by allowing the
  developer to pass a stream into the rendering engine. If there is an
  exception thrown, during rendering, then the exception can be caught and
  dealt with. Buffering is also handled by passing properly buffered
  stream to the parser. Again, if there is an error, then another stream
  can be easily substituted for the output.
  </p>
  
  <source><![CDATA[
  import javax.servlet.*;
  import javax.servlet.http.*;
  import javax.servlet.jsp.*;
  import javax.servlet.jsp.tagext.*;
  import java.beans.*;
  import java.io.*;
  import java.util.*;
  import org.apache.jasper.runtime.*;
  import org.apache.jasper.*;
  
  public class _0002fhello_00031_0002ejsphello1_jsp_0 extends HttpJspBase {
      private static boolean _jspx_inited = false;
  
      public _0002fhello_00031_0002ejsphello1_jsp_0() { }
  
      public final void _jspx_init() throws JasperException { }
  
      public void _jspService(HttpServletRequest request, 
                              HttpServletResponse response)
                                  throws IOException, ServletException {
  
          JspFactory _jspxFactory = null;
          PageContext pageContext = null;
          HttpSession session = null;
          ServletContext application = null;
          ServletConfig config = null;
          JspWriter out = null;
          Object page = this;
          String  _value = null;
          try {
              if (_jspx_inited == false) {
                  _jspx_init();
                  _jspx_inited = true;
              }
              _jspxFactory = JspFactory.getDefaultFactory();
              response.setContentType("text/html;charset=8859_1");
              pageContext = _jspxFactory.getPageContext(this, request, response,
                          "", true, 8192, true);
  
              application = pageContext.getServletContext();
              config = pageContext.getServletConfig();
              session = pageContext.getSession();
              out = pageContext.getOut();
  
              // HTML // begin [file="C:\\hello1.jsp";from=(0,0);to=(4,0)]
              out.write("<HTML>\r\n<HEAD><TITLE>Hello</TITLE></HEAD>\r\n<BODY>");
              out.write("\r\n<H1>\r\n");
              // end
  
              // begin [file="C:\\hello1.jsp";from=(4,2);to=(11,0)]
              if (request.getParameter("name") == null) {
                 out.println("Hello World");
              }
              else {
                out.println("Hello, " + request.getParameter("name"));
              }
              // end
  
              // HTML // begin [file="C:\\hello1.jsp";from=(11,2);to=(15,0)]
              out.write("\r\n</H1>\r\n</BODY></HTML>\r\n\r\n");
              // end
          } catch (Exception ex) {
              if (out.getBufferSize() != 0)
                  out.clearBuffer();
              pageContext.handlePageException(ex);
          } finally {
              out.flush();
              _jspxFactory.releasePageContext(pageContext);
          }
      }
  }]]></source>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-saying-hello.html">Saying Hello</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-error-handling.html">Error Handling</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-implementation.xml
  
  Index: ymtd-implementation.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Implementation</title>
    </properties>
  
  <body>
  
  <section name="Implementation">
  
  <subsection name="The first point: Standards">
  
  <p>
  One of the touted advantages of JSP is that it is a "standard" and quite
  a few people like to hold this in high regard. So much so that they
  refuse to use any technology that is not "standard." Digging into the
  reality of this statement reveals that the important correct terminology
  is that JSP is a "Sun Standard Specification" and not strictly a
  "standard." This is important because JSP is really no more "standard"
  than Micro$oft ASP or the PHP Group's PHP product. In other words,
  whatever tool you happen to be using becomes the "standard."
  </p>
  
  <p>
  A small group within the Java Community Process (JCP) defines what JSP
  is. The fact of the matter is that there is a fairly high barrier to
  joining the JCP because an NDA must be signed, the project leads must
  approve your entry and in some cases a fee must be paid. One could even
  stretch as far as to say that the JSP specification is really a
  proprietary product of Sun!
  </p>
  
  </subsection>
  
  <subsection name="The next point: Complexity">
  
  <p>
  JSP is both a specification as well as an implementation. There are
  various corporations (as well as Open Source) implementations of the
  specification. The JSP specification is not a particularly easy thing to
  implement. There are many complex systems involved, some of which even
  require special hooks into the Servlet Engine in order to obtain optimal
  performance.
  </p>
  
  <p>
  The JSP specification is relatively new (it is still in a 1.x phase).
  This means that the specification also has several places in it that are
  not as well defined as others, leaving some of the specific details to
  be determined by the implementation. Not only does this mean that there
  is plenty of places to make mistakes, but it also means that JSP
  template code has the possibility of not behaving the same across
  implementations. This makes testing JSP based applications a nightmare.
  </p>
  
  <p>
  Part of the founding reason for creating the Jakarta Project and having
  Sun release the source code to Jasper (the JSP reference implementation)
  is to encourage vendors to adopt a single base for their source code.
  Unfortunately, this has not happened. There is compatibility testing
  suites available, however there is no policy in place requiring vendors
  to pass the tests. Nor is there a place that shows vendors who do not
  pass the tests in order to publicly humiliate them into submission.
  </p>
  
  </subsection>
  
  <subsection name="The final point: Velocity">
  
  <p>
  Even though Velocity is lacking a specification document (it is on the
  TODO list and volunteers are welcome to help out) and is not a "Sun
  Specification Standard" (although it probably could be, but would it be
  really worth it?), that should not stop anyone from using it in
  production environments. The reason is that as shown above, the fact of
  the matter is that JSP is no more of a "standard" than anything else.
  </p>
  
  <p>
  Velocity is actually a more reliable implementation because there is
  currently only one implementation, the modifications to the code base
  are discussed in the open (anyone is welcome to participate) and the
  testing suite is strictly maintained.
  </p>
  </subsection>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-embedded.html">Embedded Usage</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-conclusion.html">Conclusion</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-javabeans.xml
  
  Index: ymtd-javabeans.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - JavaBeans</title>
    </properties>
  
  <body>
  
  <section name="JavaBeans">
  
  <p>
  JavaBeans are the way to use Java objects from JSP pages in order to
  follow the MVC design pattern. The point of doing this is to implement
  something similar to the <a
  href="http://jakarta.apache.org/turbine/pullmodel.html">Pull
  methodology</a>. For example:
  </p>
  
  <source><![CDATA[
  <jsp:useBean id="name" scope="page|request|session|application"
               class="className" type="typeName">
  ]]></source>
  
  <p>
  Examining the syntax of the above code, the first thing that pops up
  right away is the use of the scope attribute. How many HTML designers
  understand the programming concepts of scope? It is safe to suggest that
  a good portion of web designers barely understand the concept of how a
  CGI works. By stating this, we are not trying to slight people. Instead
  we are simply pointing out that having a degree in Design does not also
  imply that they also have a degree in Software Engineering or even web
  applications.
  </p>
  
  <p>
  The common response to an argument like this is that the designers
  should simply ignore these tags and let others define and implement
  them. The problem with that is that you have now given them the power to
  accidentally wreck your entire application in such a way that it is
  very difficult to debug because a complex scope issue might not show up
  right away.
  </p>
  
  <source><![CDATA[
  The Java code:
  
  public class HelloBean {
    private String name = "World";
  
    public void setName(String name) {
      this.name = name;
    }
  
    public String getName() {
      return name;
    }
  }
  
  The JSP code:
  
  <jsp:useBean id="hello" class="HelloBean">
    <jsp:setProperty name="hello" property="*" />
  </jsp:useBean>
  
  <HTML>
  <HEAD><TITLE>Hello</TITLE></HEAD>
  <BODY>
  <H1>
  Hello, <jsp:getProperty name="hello" property="name" />
  </H1>
  </BODY>
  </HTML>
  ]]></source>
  
  <p>
  Above, we have a very simple example of using a bean in a page. Pass it
  some properties and then retrieve the results. This is the right way to
  do things when using JSP. However, if we look at an example of doing the
  same exact thing in Velocity, the extra amount of needless typing that
  one needs to perform to simply retrieve a property seems a just bit
  absurd. Of course there are always GUI based drag and drop tools to make
  typing a thing of the past. Really.
  </p>
  
  <source><![CDATA[
  The Java code:
  
  context.put ("hello", new HelloBean());
  
  The Velocity code:
  
  $hello.setName("*")
  <HTML>
  <HEAD><TITLE>Hello</TITLE></HEAD>
  <BODY>
  <H1>
  Hello, $hello.Name
  </H1>
  </BODY>
  </HTML>
  ]]></source>
  
  <p>
  The example shows the creation of the HelloBean() object and then
  placing it into the Context. Then, during runtime execution of the
  template, that object is available as a $variable which uses the
  JavaBean specification to do introspection on the object. For example,
  Velocity uses Bean style introspection to permit the method call to be
  shortened from <code>$hello.getName()</code> to simply typing what is
  shown above.
  </p>
  
  <p>
  When Velocity is combined with Turbine, the HelloBean object can be
  added into the Context as a configuration option or it can be added at
  any point of the processing. This is what provides the "scope" of the
  object in the Context.
  </p>
  
  <p>
  Another "gotcha" with using JavaBeans in JSP is again quoted from Jason's 
  book:
  </p>
  
  <source><![CDATA[
  One thing to watch out for:  On some servers (including Tomcat 3.2) if
  you have a bean with a scope of "session" or "application" and you
  change the bean class implementation, you may get a ClassCastException
  on a later request. This exception occurs because the generated servlet
  code has to do a cast on the bean instance as it's retrieved from the
  session or application, and the old bean type stored in the session or
  application doesn't match the new bean type expected.  The simplest
  solution is to restart the server.
  ]]></source>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-error-handling.html">Error Handling</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-sampleapp.html">Sample Application</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-sampleapp.xml
  
  Index: ymtd-sampleapp.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Sample Application</title>
    </properties>
  
  <body>
  
  <section name="Sample Application">
  
  <source><![CDATA[
  <%-- toolview.jsp --%>
  
  <%
    String title = "Tool Listing";
    String deck = "A list of content creation tools";
    String desc = "Without tools, people are nothing more than animals.";
  %>
  
  <%@ include file="/header.jsp" %>
  
  <%@ page session="false" %>
  <%@ page errorPage="/errorTaker.jsp" %>
  
  <jsp:useBean id="toolbean" class="ToolBean" scope="application">
    <jsp:setProperty name="toolbean" property="toolsFile"
                  value='<%= application.getInitParameter("toolsFile") %>' />
  </jsp:useBean>
  
  <%
    Tool[] tools = toolbean.getTools(request.getParameter("state"));
  
    for (int i = 0; i < tools.length; i++) {
      Tool tool = tools[i];
  %>
    <HR SIZE=2 ALIGN=LEFT>
  
    <H3>
    <%= tool.name %>
  
    <% if (tool.isNewWithin(45)) { %>
      <FONT COLOR="#FF0000"><B> (New!) </B></FONT>
    <% } else if (tool.isUpdatedWithin(45)) { %>
      <FONT COLOR="#FF0000"><B> (Updated!) </B></FONT>
    <% } %>
  
    </H3>
    <A HREF="<%= tool.homeURL %>"><%= tool.homeURL %></A><BR>
  
    <%= tool.comments %>
  
  <% } %>
  
  <%@ include file="/footer.jsp" %>
  ]]></source>
  
  <source><![CDATA[
  Because of JSP whitespace preservation rules you must be careful when
  writing if/else statements with scriptlets.  The following code would
  *not* work:
  
    <% if (tool.isNewWithin(45)) { %>
      <FONT COLOR=#FF0000><B> (New!) </B></FONT>
    <% } %>
    <% else if (tool.isUpdatedWithin(45)) { %>
      <FONT COLOR=#FF0000><B> (Updated!) </B></FONT>
    <% } %>
  
  With this code the background servlet would attempt to print a new line
  between the if and else clauses, causing the obscure compile error:
  'else' without 'if'.
  ]]></source>
  
  <p>
  Another great Jason quote:
  </p>
  
  <source><![CDATA[
  One thing to watch out for:  On some servers (including Tomcat 3.XXX) if
  you have a bean with a scope of "session" or "application" and you
  change the bean class implementation, you may get a ClassCastException
  on a later request. This exception occurs because the generated servlet
  code has to do a cast on the bean instance as it's retrieved from the
  session or application, and the old bean type stored in the session or
  application doesn't match the new bean type expected.  The simplest
  solution is to restart the server.
  ]]></source>
  
  <p>
  It is the belief of the Velocity developers that you should not have to
  specially code your applications to work around issues that are related
  directly to Java.
  </p>
  
  <hr noshade="true" size="1"/>
  
  <p>
  On to the Velocity version...
  </p>
  
  <source><![CDATA[
  ## toolview.vm
  
  #set ($title = "Tool Listing")
  #set ($deck = "A list of content creation tools")
  #set ($desc = "Without tools, people are nothing more than animals." )
  
  #parse ("header.vm")
  
  $toolbean.setToolsFile($application.getInitParameter("toolsFile"))
  
  #set ($tools = $toolbean.getTools($request.getParameter("state")))
  
  #foreach ($tool in $tools)
    <HR SIZE=2 ALIGN=LEFT>
  
    <H3>
    $tool.Name
  
    #if ($tool.isNewWithin(45))
      <FONT COLOR="#FF0000"><B> (New!) </B></FONT>
    #elseif (tool.isUpdatedWithin(45))
      <FONT COLOR="#FF0000"><B> (Updated!) </B></FONT>
    #end
    </H3>
    <A HREF="$tool.homeURL">$tool.homeURL</A><BR>
  
    $tool.comments
  #end
  
  #parse ("footer.vm")
  ]]></source>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-javabeans.html">JavaBeans</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-taglibs.html">Taglibs</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-saying-hello.xml
  
  Index: ymtd-saying-hello.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Saying Hello</title>
    </properties>
  
  <body>
  
  <section name="Saying Hello">
  
  <p>
  Ok, lets start off with some easy examples. These examples really do not
  even touch on the basics of correct design. However, they still make
  good examples because correct design is often harder than showing a
  simple example. We will show better examples further along in this
  essay.
  </p>
  
  <p>
  For the first example, we show that there are two different approaches
  of doing the same exact thing using both JSP and Velocity. This is an
  example of printing out a parameter with JSP:
  </p>
  
  <source><![CDATA[
  <html>
  <head><title>Hello</title></head>
  <body>
  <h1>
  <%
  if (request.getParameter("name") == null) {
     out.println("Hello World");
  }
  else {
    out.println("Hello, " + request.getParameter("name"));
  }
  %>
  </h1>
  </body></html>]]></source>
  
  <p>
  This is an example of doing the same thing with Velocity:
  </p>
  
  <source><![CDATA[
  <html>
  <head><title>Hello</title></head>
  <body>
  <h1>
  #if ($request.getParameter("name") == null)
     Hello World
  #else
     Hello, $request.getParameter("name")
  #end
  </h1>
  </body></html>]]></source>
  
  <ul>
  <li><a href="./images/hello-jsp.gif" target="newWindow">Hello JSP Screen shot</a></li>
  <li><a href="./images/hello-velocity.gif" target="newWindow">Hello Velocity Screen shot</a></li>
  </ul>
  
  <p>
  <font size="-1">[ These two screen shots demonstrate the idea that one
  cannot easily look at what the code is doing in a browser when using
  JSP. ]</font>
  </p>
  
  <hr noshade="true" size="1"/>
  
  <p>
  The primary difference between the two is the way that output is
  performed. With JSP, one needs to embed "code" within <code>&lt;%
  %&gt;</code> tags and for Velocity, one does not need to do that.
  </p>
  
  <p>
  The benefit (and detriment) of the embedded code is that the JSP code
  within a page will not show up when the file is simply loaded into
  the browser. On the other hand, there might be a case where one may
  desire it to show up (for example, in debugging).
  </p>
  
  <p>
  Another issue with JSP is the fact that even the most basic examples
  start to blow the whole MVC paradigm right out of the water. The reason
  is that embedding HTML code within Java code is a bad design decision
  because it makes it more difficult to modify the look and feel of an
  application at a later date. It also destroys the concept of MVC
  separation where the View (ie: HTML) display of the page is separated
  from the Model and Controller. For example, if just the word "Hello"
  needed to be in bold, we would need to embed <code>&lt;b&gt;
  &lt;/b&gt;</code> tags into the <code>out.println()</code> statement.
  </p>
  
  <p>
  Of course, <i>people in the know</i>, would recommend that we write JSP like
  this:
  </p>
  
  <source><![CDATA[
  <html>
  <head><title>Hello</title></head>
  <body>
  <h1>
  <% if (request.getParameter("name") == null) {  %>
     Hello World
  <% } else { %>
    Hello, <% out.println (request.getParameter("name")); } %>
  </h1>
  </body></html>]]></source>
  
  <ul>
  <li><a href="./images/hello-jsp2.gif" target="newWindow">Hello JSP Screen shot</a></li>
  </ul>
  
  <p>
  <font size="-1">[ This is the new JSP screen shot showing the above
  example when loaded directly into the browser. ]</font>
  </p>
  
  <hr noshade="true" size="1"/>
  
  <p>
  The point that needs to be made is that in order to make JSP "pure",
  one really needs to jump through hoops. In other words, it is much
  easier to type the out.println() then to embed the necessary <code>&lt;%
  %&gt;</code> tags everywhere. It is also important to remember to add
  that extra "<code>; }</code>" at the end of the last out.println()
  because JSP will not be able to compile the page (we will get into the
  problems with debugging JSP pages in a later chapter).
  </p>
  
  <p>
  As you can see from the example image, there is now a bit more
  information in the displayed page, except that it is also missing all of
  the logic which was used to build the page. In this simple example, it
  is not very clear why this is beneficial. However, in more complex
  examples (like with a <code>for/foreach</code> loop) it becomes much
  more clear why it can be advantageous to see the logic in the page.
  </p>
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd.html">Home</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-generation.html">Generation?</a> ]
  </strong></p>
  
  </section>
  
  </body>
  </document>
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd-taglibs.xml
  
  Index: ymtd-taglibs.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision - Taglibs</title>
    </properties>
  
  <body>
  
  <section name="Taglibs">
  <p>
  Taglibs are intended to be the savior for JSP. They are billed as the
  way to allow one to extend JSP so that there is a nice MVC abstraction
  while still adding functionality to the base "language". This is where
  Struts has concentrated a good portion of its efforts by providing a
  nice taglib library for people to use.
  </p>
  
  <p>
  The advantage of using taglibs is that they allow you to extend the
  "language" syntax of JSP to provide the things that are missing from it,
  but are available in Java. In other words, instead of encouraging people
  to embed Java code within their pages, this has been now abstracted to
  encouraging people to embed XML tags in their page. How is this any
  better than what ColdFusion did with their product? JSP is on the
  cutting edge of re-inventing the broken wheel. Yea!
  </p>
  
  <p>
  This is an example that shows how logic would be embedded into your JSP
  page. It is borrowed directly from the Struts documentation.
  </p>
  
  <source><![CDATA[
  <%@ page language="java" %>
  <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
  
  
  <!-- Is the number guess right? -->
  <logic:equal parameter="number" value="7">
    You guessed right! You win a high speed blender!
  </logic:equal>
  
  
  <!-- If the number guessed was wrong -->
  <logic:notEqual parameter="number" value="7">
    <!-- Less Than -->
    <logic:lessThan parameter="number" value="7">
           A little higher...
    </logic:lessThan>
    <!-- Greater Than -->
    <logic:greaterThan parameter="number" value="7">
           A little lower...
    </logic:greaterThan>
  </logic:notEqual>
  ]]></source>
  
  <p>
  The same example using Velocity would be written like this:
  </p>
  
  <source><![CDATA[
  <!-- Is the number guess right? -->
  #if ( $number = 7 )
    You guessed right! You win a high speed blender!
  #end
  
  <!-- If the number guessed was wrong -->
  #if ( $number != 7 )
      <!-- Less Than -->
      #if ( $number < 7 )
           A little higher...
      <!-- Greater Than -->
      #elseif ( $number > 7 )
           A little lower...
      #end
  #end
  ]]></source>
  
  <p>
  This really falls into a preferences situation. In other words, which
  syntax would someone prefer to use? It seems as though the amount of
  typing required to implement the taglibs approach would be a major
  deciding factor for many people. One reason is that the more typing that
  needs to be done, the more chances for errors. Lets continue with
  another example taken from the Struts documentation:
  </p>
  
  <source><![CDATA[
  <%@ page language="java" %>
  <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
  <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
  
  <%
  java.util.ArrayList list = new java.util.ArrayList();
    list.add("First");
    list.add("Second");
    list.add("Third");
    list.add("Fourth");
    list.add("Fifth");
    pageContext.setAttribute("list", list, PageContext.PAGE_SCOPE);
  %>
  
  <logic:iterate id="myCollectionElement" name="list">
    Element Value: <bean:write name="myCollectionElement" /><br />
  </logic:iterate>
  ]]></source>
  
  <p>
  It is clear from the Struts example above that the whole strict MVC
  model has been broken again because a call to
  <code>java.util.ArrayList</code> and creating an Object is embedding
  Java code within a template. Compound that with the idea that one needs
  to place that <code>ArrayList</code> into the <code>pageContext</code>
  is even more confusing. Not only that but the designer has to remember
  to use a bunch of cryptic code at the top of the file that makes
  references to some taglib document as well as declare a prefix
  attribute. Why do things need to be so overly complicated?
  </p>
  
  <p>
  The same example using Velocity would be written like this:
  </p>
  
  <source><![CDATA[
  #set ( $list = ["First", "Second", "Third", "Fourth", "Fifth"] )
  
  #foreach ( $item in $list )
    Element Value: $item<br />
  #end
  ]]></source>
  
  <p>
  Moving on with examples, we come back to the previous <a
  href="./ymtd-sampleapp.html">sample application</a> provided in Jason
  Hunter's book that was shown before. This time it has been implemented
  entirely within the Struts framework.
  </p>
  
  <source><![CDATA[
  <%-- toolview-tag.jsp --%>
  
  <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>
  
  <%
    String title = "Tool Listing";
    String deck = "A list of content creation tools";
    String desc = "Without tools, people are nothing more than animals.";
  %>
  
  <%@ include file="/header.jsp" %>
  
  <%@ page session="false" %>
  <%@ page errorPage="/errorTaker.jsp" %>
  
  <%-- Fetch the tools array as a request attribute --%>
  <jsp:useBean id="tools" class="Tool[]" scope="request"/>
  
  <struts:iterate id="tool" collection="<%= tools %>">
    <HR SIZE=2 ALIGN=LEFT>
  
    <H3>
    <%-- Automatically HTML-escapes values --%>
    <struts:property name="tool" property="name" />
  
    <% if (((Tool)tool).isNewWithin(45)) { %>
      <FONT COLOR=#FF0000><B> (New!) </B></FONT>
    <% } else if (((Tool)tool).isUpdatedWithin(45)) { %>
      <FONT COLOR=#FF0000><B> (Updated!) </B></FONT>
    <% } %>
  
    </H3>
    <A HREF="<struts:property name="tool" property="homeURL"/>">
             <struts:property name="tool" property="homeURL"/></A><BR>
  
    <%-- Assume don't want HTML in comments --%>
    <struts:property name="tool" property="comments" />
  
  </struts:iterate>
  
  <%@ include file="/footer.jsp" %>
  ]]></source>
  
  <p>
  At this point, we now have a combination of standard JSP tags as well as
  Struts specific tags. The use of Struts has appeared to clean things up
  significantly with regards to embedded scriptlets. Note that quite a 
  few of JSP's warts are still shining through. Is it as easy to grok
  as the Velocity version?
  </p>
  
  
  <p>
  You make the decision.
  </p>
  
  <p>
  <strong>[ <a href="ymtd-sampleapp.html">Sample App</a> &lt;- Previous | 
      Next -&gt; <a href="./ymtd-embedded.html">Embedded Usage</a> ]
  </strong></p>
  </section>
  
  </body>
  </document>
  
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/ymtd.xml
  
  Index: ymtd.xml
  ===================================================================
  <?xml version="1.0"?>
  <document>
  
    <properties>
      <author email="jon@latchkey.com">Jon S. Stevens</author>
      <title>You make the decision</title>
    </properties>
  
  <body>
  
  <section name="You make the decision.">
  
  <p>
  The title of this essay is called "You make the decision." The point of
  this essay is to explore what it is like to develop a web application
  using a couple popular tools that are available today. In order to do
  this, examples of using these technologies will be shown. This will give
  a nice first person account of what it is like to use these technologies
  on a daily basis.
  </p>
  
  <p>
  The audience of this document is aimed at the people who are looking for
  alternatives to JSP as well as people who are currently using JSP and
  JSP based technologies and may not realize that there are other
  solutions out there that also address the many issues of developing web
  applications.
  </p>
  
  <p>
  <strong>It is possible to navigate through the essay by simply clicking
  on the links at the bottom of each page.</strong> To return to this page
  at any time, click YMTD on the left side navigation.
  </p>
  </section>
  
  <section name="What are we comparing?">
  <p>
  This multi page document will compare usage of Turbine/Velocity and
  Struts/JSP. In both cases, we have a framework of reusable code that
  makes life easier for building web applications by providing the "Model"
  and "Controller" portions of the MVC paradigm (Turbine and Struts).
  There is also a template language that provides the "View" portion (JSP
  and Velocity).
  </p>
  
  <p>
  The design concepts mentioned above that we will be exploring have been
  documented in detail in various locations, for more information, please
  refer to some of these reference URL's:
  </p>
  
  <ul>
  <li><a href="http://www.caucho.com/articles/jsp_templates.xtp" target="reference">Caucho MVC JSP</a></li>
  <li><a href="http://www.nwconnection.com/2000_09/web/" target="reference">Novell Connection MVC JSP</a></li>
  <li><a href="http://developer.novell.com/research/devnotes/1999/december/03/02.htm" target="reference">Novell Connection MVC JSP</a></li>
  <li><a href="http://www.webmacro.org/tutorial/mvc.html" target="reference">Webmacro MVC</a></li>
  <li><a href="http://www.javaworld.com/jw-01-2001/jw-0119-freemarker.html" target="reference">Freemarker MVC</a></li>
  <li><a href="http://javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html" target="reference">Model 2</a></li>
  <li><a href="http://java.apache.org/turbine/pullmodel.html" target="reference">The Pull Model</a></li>
  </ul>
  
  </section>
  
  <section name="Credits">
  <p>
  We would first like to thank the entire <a
  href="../contributors.html">Velocity</a> and <a
  href="/turbine/contributors.html">Turbine</a> teams for creating such
  kick ass products. These groups are a 100% volunteer organization and
  some very talented engineers have come together from around the world to
  help make these products a reality and a success. They deserve a round
  of thanks and appreciation for their hard work and dedication.
  </p>
  
  <p>
  Examples, comments as well as the some of the flow of this document has
  been borrowed with permission from <a
  href="http://www.servlets.com/">Jason Hunter</a>, author of the
  excellent <a href="http://www.oreilly.com/catalog/jservlet2/">O'Reilly
  Java Servlet Programming, 1st and 2nd Edition book</a>. We do hope that
  you purchase his next book when it is released in order to support Java
  Servlets as well as Jason for his hard work.
  </p>
  
  <p>
  Jason's book includes chapters covering JSP, Velocity, and other MVC
  technologies.  We definitely encourage you to read the book to learn JSP
  and Velocity and see how they compare.  What we do here (that Jason
  couldn't do in the book) is put JSP/Struts and Velocity/Turbine on the
  same page together for a direct side-by-side comparison.
  </p>
  
  </section>
  
  <section name="Revisions / Corrections / Additions">
  
  <p>
  It is very important to accurately compare these technologies.
  Therefore, a lot of effort has gone into this essay to state things as
  fairly and accurately as possible. Therefore, this entire essay is
  checked into CVS and it is possible for you to provide feedback, but
  also patches that fix any mistakes. In other words, this is a community
  driven document. It is currently stored in the <a
  href="http://jakarta.apache.org/site/cvsindex.html">CVS tree</a> for the
  Velocity project in the xdocs directory.
  </p>
  
  <p>
  If there are any changes that need to be made to this document, please
  do not hesitate to contact <a href="jon@apache.org">Jon Stevens</a>.
  </p>
  
  <p>
  On to the rest of the essay...
  </p>
  
  <p>
  <strong>[ Next -&gt; <a href="./ymtd-saying-hello.html">Saying Hello</a> ]</strong>
  </p>
  
  </section>
  
  </body>
  </document>
  
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/images/hello-jsp.gif
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/images/hello-jsp2.gif
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/images/hello-velocity.gif
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity/xdocs/ymtd/images/jsp-nasa-crash.gif
  
  	<<Binary file>>