maandag 27 augustus 2012

JSTL Velocity or Freemarker

Introduction:

 After a couple of years of experience, I tried different ways to deal with beans and pages. There are many ways to deal with this. Most of the times I used JSTL, Freemarker, Velocity or the spring Taglibs. Now i am trying to get clear what is the best way of dealing I can use.

Why jstl:

I used jstl a lot for the coupling of the beans and the jsp's. This still gives you the freedom to use also the java  <%%> tags. In my opinion it is not wise to do this simply of the fact, that you run into the risk of starting to use business logic in the jsp's which is straight against the
mvc pattern and the multi tier architecture. The only real downside of the JSTL's for me: is that for different functions you need different libraries declared in your jsp:

- Core tags
- Formatting tags
- Sql tags
- xml tags



  • The only taglib I do not like to use is the sql tags. I believe that this kind of functionality should be left to handled by the persistence tier. 

    The conclusion for using JSTL is: It is a very usefull set of libraries which can help you to create a good separation of your model and view. It still offers a lot of freedom which should be handled thoughtfully. In an development tool as Eclipse you might experience that this tool does not see it as on the classpath and gives compile errors in that sense. At runtime this example will work.

    An examples:

    //This is the jstl import
    <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
    //Looping through a list of names in the items you have//
    //to declare the full path. In this case it a list in the customer class.//
    <c:forEach var="costumerNames" items="${com.my.customer.names}">
         //printing the names in al HTML list.//
        <LI> <c:out value="${customerNames.name}"/> </LI>
    </c:forEach> 


  • Why 
    velocity

    Velocity brings you the freedom to use their templates only or embed them in a Jsp. The bridging between the model and view. The plus of Velocity against the JSTL is that it works in different areas of your application. You can as easily use it for pages as for the layout for automated emails. It has a lot more
    functionality which makes it much more flexible to work with. Instead of bringing extra technology into the Jsp, there is an template created a .vm file, wich is compiled into a view. 

    The conclusion:
    If there is a need for a lot of flexibility even in a legacy system where there are allready Jsp's velocity is a  flexible tool.
    • It adapts to many application areas
    • It offers a simple, clear syntax for the template designer
    • It offers a simple programming model for the developer
    • Because templates and code are separate, you can develop and maintain them independently
    • The Velocity engine easily integrates into any Java application environment, especially servlets
    • Velocity enables templates to access any public method of data objects in the context

    an example for a web app:
    The servlet.xml example:


     <!--    register servlet   
             dont take this part to letterly. This is als depending on the frontend
             framework you are using.
     -->
        
        <servlet>
            <servlet-name>applicationServlet</servlet-name>
            <servlet-class>my.velocity.VelocityServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>applicationServlet</servlet-name>
            <url-pattern>/myApplication</url-pattern>
        </servlet-mapping>
        
        <!--    mapping all .vm files to velocity servlets  -->
        <servlet>
            <servlet-name>velocity</servlet-name>
            <servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class>
            <!--    load my toolbox -->
            <init-param>
                 <param-name>org.apache.velocity.toolbox</param-name>
                 <param-value>/WEB-INF/toolbox.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>velocity</servlet-name>
            <url-pattern>*.vm</url-pattern>
        </servlet-mapping>
     
    The toolbo.xml example (place it in the WEB-INF):
    <toolbox>
        <tool>
            <key>date</key>
            <scope>application</scope>
            <class>org.apache.velocity.tools.generic.DateTool</class>
        </tool>
    </toolbox>
    The java part:
    In this part you have to create a bean with a member "name"  that has getters and setters. With whatever framework you use as frontend technology (serlets, struts,spring, etc...) set this as a request parameter with the name "name". This, 
    ofcourse comes back in the html. 
    The html part:
    <h2> $name is using velocity</h2>
    Why freemarker
    Freemarker is an template engine, which might be seen as simular to Velocity. The difference in what they 
    can do sits in the functionality they have. If you have light requirements Velocity is the answer
    to your question on the other hand if you like one of the following functionalities out of the box 
    you might consider using Freemarker:
     
    Number and date support
    • You can perform arithmetic calculations and comparisons on arbitrary number types, including the arbitrary-precision types, not just integers.
    • You can compare and display (format) date/time values.
    Internationalization:
    • You can format numbers locale-sensitively, based on a variety of built-in and custom number-formatting patterns.
    • You can format dates locale- and timezone-sensitively, based on variety of built-in and custom date-formatting patterns.
    • Identifiers (variable names) can contain non-English letters like accented letters, Arabic letters, Chinese letters, etc.
    Loop handling:
    • You can break out of loops.
    • You can access control variables of outer loops from bodies of inner loops.
    • You can test whether you are in the last iteration of the loop.
    Array handling on the template language level:
    • You can access array elements, both primitive and non-primitive by index using the familiar [i] syntax.
    • You can query the length of an array.
    Macros:
    • Macro invocations can pass parameters either by position or by name.
    • Macro parameters can have default values which are effective when the parameter is omitted on invocation.
    • Macro invocations can have a nested body (<@myMacro>body</@myMacro>) that can be called by the macro for processing.
    • Macros are plain variables, so you can select the macro to execute based on an expression, or pass a macro to another macro as parameter.
    • Invoke a macro that is defined later in the template.
    • Local variables in macros, and recursive invocation of macros. In Velocity it is now possible with the currently (Feb. 2005) not officially documented #local function.
    Name-spaces:
    • You can use multiple name-spaces for variables. This is invaluable when you build "macro libraries", because you can prevent name collisions with application specific variables or with variables of other macro libraries.
    Java-independent string, list, and map manipulations with built-in functions/operators:
    • You can turn a string upper-, lower-, or title-case, turn upper-/lowercase only the first letter, convert (escape) the string to HTML, XML, or RTF, extract substrings, split strings, query string length, find/replace substring, ...etc.
    • Access elements of lists by index, extract sublists, concatenate lists, query size of a lists, sort lists.
    • Access map elements by variable key, check if the map is empty, obtain the key or value list.
    Expose typos and other mistakes in template:
    • When you try to access an undefined variable, FreeMarker will not accept that silently. You can configure FreeMarker to stop template rendering with an error message, or skip the wrong part. In either case, FreeMarker will log the problem, so it does not remain hidden.
    • FreeMarker will throw an exception if you mistype a directive name, and will not print the statement silently to the output (unless you use the now deprecated non-strict syntax).
    Advanced rendering control:
    • You can enclose a block of template in a set of tags that will cause it to apply HTML escaping or XML escaping (or any other transformation you can express as a FreeMarker expression for that matter) on all interpolations (${foo}) in the block.
    • FreeMarker has transforms, which are blocks of template that when rendered, go through a transforming filter. Built-in transforms include whitespace compressor, HTML and XML escaper. Best of all, you can implement your own transformers as well (i.e. if you generate Java source code, you can write a Java code pretty-printer transform and insert it into the template). Naturally, transforms can be nested.
    • You can explicitly flush the output writer with a built-in flush-directive.
    • You can stop the rendering with a built-in stop-directive.
    Literals:
    • Beside the usual string, number, and boolean literals you can define list and map literals as well inside templates.
    • There is a support for all Java string literal escapes: \b, \t, \n, \f, \r, \", \', \\, also we support \xXXXX to specify characters with their UNICODE code.
    Advanced white-space removal:
    • FreeMarker consistently removes white-space (spaces, tabs and line-break) from lines that contain non-outputting FreeMarker tags only, thus eliminates most annoying, obviously superfluous white-space.
    • There are directives to explicitly trim lines from needless white-space, just for the extreme cases, when white-space is a real problem.
    Integration with other technologies:
    • You can use JSP custom tag libraries in templates.
    • You can work directly on Python objects.
    Powerful XML transformation capabilities:
    • As of version 2.3, FreeMarker has powerful new XML transformation capabilities that make it a viable replacement for XSLT. Though there have been some attempts to make Velocity more capable in this domain (i.e. DVSL) Velocity is not really competitive in this regard. In our view, it never will be unless certain improvements to the core engine are made, such as support for macro libraries mapped to namespaces, and local variables in macros.
    Advanced template metaprogramming:
    • You can capture the output of an arbitrary part of the template into a context variable.
    • You can interpret arbitrary context variable as if it were a template definition.
    • You can imagine what can you do when you combine the two...
     
      An example:

     The java class:
         //Freemarker configuration object
            Configuration cfg = new Configuration();
            try {
                //Load template from source folder
                Template template = cfg.getTemplate("src/helloworld.ftl");
                 
                // Build the data-model
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("message", "Hello World!");
                //List parsing
                List<String> countries = new ArrayList<String>();
                countries.add("India");
                countries.add("United States");
                countries.add("Germany");
                countries.add("France");
                 
                data.put("countries", countries);
                 
                // Console output
                Writer out = new OutputStreamWriter(System.out);
                template.process(data, out);
                out.flush();
                // File output
                Writer file = new FileWriter (new File("C:\\FTL_helloworld.txt"));
                template.process(data, file);
                file.flush();
                file.close();
                 
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TemplateException e) {
                e.printStackTrace();
            }
        }

    The ftl Code:

    <#list countries as country>
        ${country_index + 1}. ${country}
    </#list>
    The output:
       1. India
       2. United States
       3. Germany
       4. France
    I hope this helps to choose the tool you need. I started out a new project and decided to use the jstl and the spring taglibs. They provided me with all I need.
    But if I need something heavier the next time I might use Velocity or Freemarker to suit my needs.
    Have fun!
     
    
    

    maandag 6 augustus 2012

    resizing images on the fly

    Intro:

    After determining where the files are and how to move them into another folder as I showed in my previous post Howto create a set of files on the fly, It is fun to resize the files which are images in this case (makes it easier).

    The problem:

    We have a set of images, which might change and dont want to resize them by hand everytime.

    The solution:

    The solution lies hidden in Java as many times. The following example shows howto resize:



    private void createIcons(String path){
        int width=100;
        int height = 100;
        File imageInput = File(path);
       ImageIcon imageIcon = new ImageIcon(path);
       BufferedImage imageResize =
      new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
      Graphics2D graphics2d = imageResize.createGraphics();
      graphics2d.addRenderingHints(
       new RenderingHints(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY));
       graphics2d.drawImage(imageIcon.getImage(), 0, 0, height, width,
       null);
       String iconName = path.replaceAll(
       IMAGES, ICONS);
       try {
          ImageIO.write(imageResize,
          "png", new File(iconName));
        }
        catch (IOException ioe) {
          LOGGER.error("The image " + iconName + " could not be saved!");
        }
    }

     In my previous post I had a line "String filePath =path.replace(IMAGES, ICONS); " all you have to do is to replace that line with:  "createIcons(image.getAbsolutePath());" and you be on your way with a full subset of folders and resized images. The only kind of images I had it never working with was BMP.

    A working version or the sources you can download from:
    http://sourceforge.net/projects/imageicon/files/imageicon-1.0-SOURCES.jar/download

    Or check out the sources from:
    ssh://git.code.sf.net/p/imageicon/code

     have fun.