Sunday September 30, 2007
FreeMarker: Baked into NetBeans IDE 6.0 (Part 2)
In Part 1, I talked about FreeMarker support in NetBeans IDE 6. It is definitely very cool in the context of code generation. I'm pretty sure that it has a big impact on chapter 19 of Rich Client Programming: Plugging into the NetBeans Platform. There, a whole bunch of Wicket-related artifacts are generated at the end of the New Web Application wizard. At the time, in the absence of FreeMarker, we had to create a pretty clumsy artifice that replaces macros in template files with values set by the user in the wizard. Now, however, with FreeMarker, not only will we be using an external approach to this, i.e., not an internal hacked approach, but also many things are much easier than before, which I hope to illustrate in this blog entry.
Let's say we have this wizard:
Now, the info from that wizard could be the input for a wide variety of outputs. Here's the FreeMarker template that defines my output:
Notice especially the highlighted bit, because there we have a bit of iteration going on! That's really cool, because now I don't have to handle that in my code. FreeMarker does it for me. I simply need to send some kind of array called 'types' (or anything else, of course, so long as the object I send has a name that is the same as the name used in the FreeMarker template) and then FreeMarker will iterate through it for me. I like that. I like that a lot.
Now, how to assign the above template to the wizard? Here's how my template is defined in the layer, notice the two bits in bold. The first bit points to the location of the template, which is in the same folder, in this case, as the layer file. The second highlighted bit tells the IDE to treat the template as a FreeMarker template:
<folder name="Other">
<file name="letter.html" url="letter.template">
<attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.newfiletemplate.Bundle"/>
<attr name="instantiatingIterator" newvalue="org.netbeans.modules.newfiletemplate.letter.LetterWizardIterator"/>
<attr name="template" boolvalue="true"/>
<attr name="templateWizardURL" urlvalue="nbresloc:/org/netbeans/modules/newfiletemplate/letter/letter.html"/>
<attr name="javax.script.ScriptEngine" stringvalue="freemarker"/>
</file>
</folder>
A second thing to discuss is how the values from the wizard end up being used in the FreeMarker template. If you use the Wizard wizard to generate the basic artifacts required by every NetBeans wizard, one of your new classes will be an iterator. In the iterator's instantiate() method, the generation process takes place, by means of the createFromTemplate(dataFolder, targetName) method. However, now you can include a map containing the objects that you want to pass. And where are they passed? To the FreeMarker template of course. Here's the instantiate() method for the above template:
public Set instantiate() throws IOException {
FileObject dir = Templates.getTargetFolder(wizard);
String targetName = Templates.getTargetName(wizard);
DataFolder df = DataFolder.findFolder(dir);
Object[] data = (Object[]) wizard.getProperty(LetterVisualPanel1.PRODUCTS.toString());
hashMap = new HashMap();
hashMap.put("url", wizard.getProperty(LetterVisualPanel1.URL));
hashMap.put("name", wizard.getProperty(LetterVisualPanel1.NAME));
hashMap.put("types", data);
FileObject template = Templates.getTemplate(wizard);
DataObject dTemplate = DataObject.find(template);
DataObject dobj = dTemplate.createFromTemplate(df, targetName, hashMap);
FileObject createdFile = dobj.getPrimaryFile();
return Collections.singleton(createdFile);
}
Note the line in bold above. There my hashMap is included. And the map consists of a "url", a "name", and a "types", which are used in the FreeMarker template. Now, when the user completes the wizard, for the values shown above, they will see this:
There's quite a bit more possible with FreeMarker, and obviouly we need syntax coloring and so on, that I'm still investigating, such as something to do with the product license that I need to figure out. But I can already see the benefits of FreeMarker support in NetBeans IDE 6.0. And it's all really pretty cool and clever.
Sep 30 2007, 02:22:50 AM PDT Permalink
Wicked cool! Thanks for sharing this.
Posted by Rohan Ranade on September 30, 2007 at 07:04 AM PDT #


