Question

I am trying to create a source code generator for JSF web projects using FreeMarker. The project is still in its infancy.

The generator parses a JSON string to create the different components (pom.xml, web.xml, controllers, and views).

So far I've been able to generate two types of JSF projects:

  • a simple JSF project that displays Hello, World!
  • a "Hello, [NAME]" JSF project with a form receiving the name and redirecting it to another view.

But I have a problem with the views. Although the current implementation is very flexible (using some sort of Decorator Pattern on the ViewContent) and works, the json string has to have the whole page. For simple pages such as the ones I've generated, it's ok. But as the projects I try to generate become more complex, so will the views.

For instance, this is the json string I have for the simple "Hello World" app:

{
  "name":"simplehello",
  "pomFile": {"groupId":"br.com.revo", "artifactId":"simplehello", "description":"the simplest JSF Project", "javaVersion":"1.7"},
  "beans":[
    {"name":"Hello", "scope":"VIEW", "fields":[{"type":"String", "name":"hello", "value":"\"Hello World!\""}]}
  ],
  "views":[
    {"name":"hello", "welcomeFile":true, "content":
      {"name":"html","properties":{"xmlns":"http://www.w3.org/1999/xhtml","xmlns:h":"http://java.sun.com/jsf/html"},
       "contents":[
        {"name":"h:head","contents":[{"name":"title","value":"Simple Hello"}]},
        {"name":"h:body", "value":"#{helloBean.hello}"}
      ]}
    }
  ]
}

So what can I do to use a custom DSL on my json string and let the Generator handle the view creation? I've been googling around and this are the possibilities I've seen:

  1. Use FreeMarker's <#include> to insert the JSF components I need:

    <#if content.text>
        <#include text.ftl>
    <#elseif content.form>
        <#include form.ftl>
    // etc...
    </#if>
    
  2. Generate a bean that programatically designs the pages.

    see Programmatic usage of Facelets

How can I effectively use FreeMarker to create views?

Here's the Use Case, Class and Activity diagrams for my project:

Use Case Diagram Class Diagram Activity Diagram

Was it helpful?

Solution

I solved it by refactoring the ViewFile to use list of actions (ViewAction) instead of its contents.

Since the projects I'm trying to generate so far have standard actions (displaying a message, assigning a value to a variable, redirecting to a page, etc), the ViewAction has an enum with the ActionType and a String with the value:

ViewAction

public class ViewAction {
    private ActionType actionType;
    private String value;

    // getters and setters
}

ActionType

public enum ActionType {
    DISPLAY,
    ASSIGN,
    BUTTON,
    LINK,
    CRUD
}

now I can use FreeMarker's <#include> directive according to the ActionType. This is less flexible, but now the Parser does not need to know how to code JSF views,

Plus it allowed to simplify my code even more. Instead of separating beans, views and models, I can define a single (or a list of) Model class and the JSFServiceFactory creates the services accordingly. Now the json for the HelloWorld app is way simpler:

{
  "name":"simplehello",
  "pomFile": {"groupId":"br.com.revo", "artifactId":"simplehello", "description":"the simplest JSF Project", "javaVersion":"1.7"},
  "models":[
    {"name":"Hello",
     "scope":"VIEW",
     "title":"Simple Hello",
     "mainPage":true,
     "fields":[{"type":"String", "name":"hello", "value":"\"Hello World!\""}],
     "actions":[{"actionType":"DISPLAY", "value":"#{helloBean.hello}"}]
    }
  ]
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top