|
|||||
|
|||||
Extending Nuts
Nut classNuts is extensible because users can define their own tags by implementing Nut classes. There are certain rules to follow when defining Nut classes:
There are many pre-defined helper classes to make the job of creating your own Nut class easier. Writing my ownIn the Overview section, we claimed that one can define his own "repeat" tag to repeatedly run a Component for x number of times. Here we'll just use this as an example to show the process of creating customized Nut class. First, let's lay out the desired xml syntax. We hope we can do: <repeat times="100"> <ctor class="A" singleton="false"/> </repeat> This calls the constructor for 100 times. <ctor id="a" class="A" singleton="false"/> <repeat times="100" component="$a"/> Secondly, let's analyze the syntax.
Now let's start coding: public class RepeatNut extends ComponentNut{ private int times = -1; private Component action; public void setTimes(int times){ this.times = times; } public void setComponent(Component action){ this.action = action; } public void add(Component a){ if(this.action!=null) raise("component already set"); this.action = a; } public Component eval(){ if(times<0) throw raise("attribute times should be set"); if(action==null) throw raise("component should be set"); return action.repeat(times); } } ComponentNut class extends from Nut. It can be inherited by any Nut class that evaluates to a Component. As you may have noticed, there are many tediouos checkings to make sure things like "mandatory attributes should be set", "an attribute and a sub-element cannot be both set". Fortunately, there's a DelegatingNut super class that already handles most of these tediousness. By extending it, the RepeatNut class becomes: public class RepeatNut extends DelegatingNut{ private int times = -1; public void setTimes(int times){ this.times = times; } public Component eval(){ if(times<0) throw raise("attribute times should be set"); final Component action = getMandatory(); return action.repeat(times); } } Use itafter writing this RepeatNut class, (let's assume it is in com.ajoo package), inside the xml config file, we can load it using the <nut> tag: <module name="my test"> <nut name="repeat" class="com.ajoo.RepeatNut"/> <body> <repeat times="100"> <ctor class="A"/> </repeat> </body> </module> When this class is in a jar file that's not in the current class path, we can: <module name="my test"> <nut name="repeat" class="com.ajoo.RepeatNut" classpath="/home/mynuts.jar"/> <body> <repeat times="100"> <ctor class="A"/> </repeat> </body> </module> Life cycle for Nut objectsHere's how a Nut object is used:
SummaryExtensible Nuts tag imakes a useful tool to deal with various dependency injection models in disparate systems. For example, we could implement the annotation based, Java EE 5 dependency injection model by creating a Ejb3Nut class that's aware of the Java EE 5 annotations. We then can override the default <bean> tag using this Ejb3Nut class. Without a single line of code changed in the core to be dependent on Java EE 5, Nuts is nicely extended to be Java EE 5 compliant. The same technique is used in Nuts' Spring integration. Specific spring-aware Nut classes are built to handle Spring factory bean and various Spring's proprietary marker interfaces. These custom Nut classes are then registered to override the default <ctor>, <bean> tags and add Spring support. |
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||