tags:

views:

403

answers:

2

As part of a project I'm working on, we're migrating from Velocity to JSP. I need to turn the set of existing Velocity templates into JSPs. We could spend hours discussing why this was decided (partly my fault), which one is better and the best way to dissuade management from this path, but that would be a waste of time as they are committed to having this done.

So, what I'm looking for is a set of patterns, best practices, what have you, to help me out. There's a lot of Velocity macros in the global library file which are used across a variety of templates. I'm thinking of converting each macro to a JSP scriptlet and translating the macro to Java. Then I would include that file with all the scriptlets into each JSP either via the include directive or jsp:include. I was also thinking of converting each call to a macro into a scriptlet. These macros have parameters that are beans defined in the Spring ModelAndView class.

Preliminary tests seems to indicate that this approach won't work. I seem to be getting JSP compile errors. But, I might be missing an error on my part.

I'm running this web app on OC4J version 10.1.3.4.0.

Here's a simple example of what I have to deal with. This is in the VM_global_library.vm file:

#macro( showObjectErrors $objectName)
  #if ($request.errorSystem.hasErrors($objectName))
    <table>
      #foreach ($error in $request.errorSystem.getErrors($objectName))
        <tr>
          <td class="acError">$error</td>
        </tr>
      #end
    </table>
  #end
#end

And it's called in other files like so:

#showObjectErrors( "logonForm" )

Note that the "request" object is not an HttpServletRequest, but an application class. There are much more complex examples that are too much to show.

+1  A: 

Convert the Macros to JSP tag includes. Here's an example of a tag file from sun

shipDate.tag under WEB-INF/tags:

<%@ attribute name="shipping" required="true" %>

<jsp:useBean id="now" class="java.util.Date" />
<jsp:useBean id="shipDate" class="java.util.Date" />
<c:choose>
  <c:when test="${shipping == 'QuickShip'}">
    <c:set var="days" value="2" />
  </c:when>
  <c:when test="${shipping == 'NormalShip'}">
    <c:set var="days" value="5" />
  </c:when>
  <c:when test="${shipping == 'SaverShip'}"> 
    <c:set var="days" value="7" />
  </c:when>
</c:choose>
<jsp:setProperty name="shipDate" property="time"
  value="${now.time + 86400000 * days}" />
<fmt:formatDate value="${shipDate}" type="date"
  dateStyle="full"/>.<br><br>

The JSP:

<%@ taglib prefix="sc" tagdir="/WEB-INF/tags" %>
<h3><fmt:message key="ThankYou"/> ${param.cardname}.</h3><br>
<fmt:message key="With"/> 
<em><fmt:message key="${param.shipping}"/></em>,  
<fmt:message key="ShipDateLC"/>
<sc:shipDate shipping="${param.shipping}" />

Your code should work like this on the JSP:

#showObjectErrors( "logonForm" ) 
===>
<%@ taglib prefix="errorLib" tagdir="/WEB-INF/errorLib" %>
...
<errorLib:showObjectErrors objectName="logonForm" />

I assume $request.errorSystem.hasErrors would be an object in the request context, so you would retrieve it with:

${errorSystem.hasErrors}
stevedbrown
This seems like the best fit. I haven't used JSP 2.0 so those tag files are new to me. It'll be fun to try them out.BTW, "hasErrors" is actually a method, not an object, and it requires a param, so I'll have to create a regular custom tag for that.
Gary Kephart
You should create a JSTL function for that probably, then it's more like ${fn:hasErrors(objectName)}. They'r pretty cool. The best place to read up on this is the oreily book really, safari.oreilly.com has free trials.
stevedbrown
A: 

If you want to do things in piecemeal fashion, you may be able to make use of the VelocityViewTag in VelocityTools 2.0. It will let you put Velocity code right into your jsp files.

<velocity:view>
#if( $foo ) this is #trickyMacroStuff() for some reason #end

#parse('whatever.vm')
</velocity:view>

Put some ${jstl} here: <fmt:message key="bar"/>

<velocity:view template="sometemplate.vm"/>
Nathan Bubna