KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > yan > xml > nut > Nut


1 package jfun.yan.xml.nut;
2
3
4 import java.net.MalformedURLException JavaDoc;
5
6 import jfun.yan.Component;
7 import jfun.yan.ParameterBinder;
8 import jfun.yan.PropertyBinder;
9 import jfun.yan.xml.ConfigurationException;
10 import jfun.yan.xml.Location;
11 import jfun.yan.xml.NutEnvironment;
12 import jfun.yan.xml.NutsUtils;
13
14 /**
15  * The super class of all Nut classes.
16  * <p>
17  * Nut stands for Name based User defineable Tag.
18  * A method whose name and signature is of a certain pre-defined pattern is
19  * called when a sub-element with corresponding name is interpreted
20  * inside the xml tag.
21  * </p>
22  * <p>
23  * For example, for the following tag:<br>
24  * <pre>
25  * &lt;ctor class="A"&gt;
26  * &lt;arg ind="0" val="1"&gt;
27  * &lt;/ctor&gt;
28  * </pre>
29  * </p>
30  * <p>
31  * Method <code>setClass</code> is called for the "class" attribute,
32  * which is of course same as the standard Java Bean convention.
33  * In fact, a Nut class is always a Java Bean because it has to
34  * have a default public constructor and some setters to
35  * set attributes.
36  * </p>
37  * <p>
38  * Method <code>addArg</code> is called for each sub-element.
39  * And the parameter type of addArg should be another Nut class
40  * to support further "tagging".
41  * </p>
42  * <p>
43  * For tags simply with a list of sub-elements whose names are
44  * irrelevant, the <code>set</code> method with an array parameter is called.
45  * <br>
46  * For example:
47  * <pre>
48  * &lt;array&gt;
49  * &lt;return val="1"&gt;
50  * &lt;ctor class="B"&gt;
51  * &lt;method class="C" name="f"&gt;
52  * &lt;/array&gt;
53  * </pre>
54  * </p>
55  * <p>
56  * Finally, a Nut class can optionally have a method named <code>"eval"</code>.
57  * If this method exist, it is invoked when the tag is evaluated.
58  * If the return type is void or the "eval" method does not exist,
59  * the Nut object itself is used as the evaluation result.
60  * Otherwise, the return value of the "eval" method is used.
61  * </p>
62  * @author Ben Yu
63  * Nov 9, 2005 10:08:11 PM
64  */

65 public abstract class Nut implements java.io.Serializable JavaDoc{
66   private Location loc;
67   private NutEnvironment env;
68   private String JavaDoc tagname;
69   private String JavaDoc id;
70   private boolean globallyDefined;
71   private int seq_no;
72   /**
73    * Is this tag defined globally?
74    */

75   public boolean isGloballyDefined(){
76     return globallyDefined;
77   }
78   /**
79    * Dynamically register an object.
80    * @param key the key of the object.
81    * @param val the object.
82    * @param overridable whether this registration is overridable.
83    * @param overriding do we override when the same key is already used
84    * by another dynamically registered entry.
85    */

86   public void register(Object JavaDoc key, Object JavaDoc val,
87       boolean overridable, boolean overriding){
88     env.registerDynamic(key, val, overridable, overriding, loc);
89   }
90   /**
91    * Get the sequence number starting from 0.
92    * This number is relative to the order the tag is defined within the current scope.
93    */

94   public int getSequenceNumber(){
95     return seq_no;
96   }
97   /**
98    * Get the id of this tag.
99    * @return the id.
100    */

101   public String JavaDoc getId() {
102     return id;
103   }
104   /**
105    * Set the id of the tag.
106    * @param id the id.
107    */

108   public void setId(String JavaDoc id) {
109     this.id = id;
110   }
111   public String JavaDoc toString() {
112     return tagname;
113   }
114   /**
115    * Get this tag's location within the configuration file.
116    */

117   public Location getTagLocation(){
118     return loc;
119   }
120   /**
121    * To set the sequence number of the tag in the enclosing scope.
122    * @param seq the sequence number.
123    */

124   public void initSequenceNumber(int seq){
125     this.seq_no = seq;
126   }
127   /**
128    * To set whether the tag is defined globally.
129    * @param gd the flag.
130    */

131   public void initGloballyDefined(boolean gd){
132     this.globallyDefined = gd;
133   }
134   /**
135    * The framework calls this method to set the location.
136    * @param loc the location.
137    */

138   public void initTagLocation(Location loc){
139     this.loc = loc;
140   }
141   /**
142    * The framework calls this method to set the environment.
143    * @param env the environment.
144    */

145   public void initNutEnvironment(NutEnvironment env){
146     this.env = env;
147   }
148   /**
149    * Get the class loader used to load the component classes.
150    */

151   public ClassLoader JavaDoc getComponentClassLoader() {
152     return env.getComponentClassLoader();
153   }
154   /**
155    * Get a ClassLoader object that uses the current ClassLoader
156    * as parent, and tries an alternative classpath if the resource
157    * or class is not found.
158    *
159    * @param classpath the alternative classpath. null if unspecified.
160    * @return the ClassLoader object.
161    */

162   public ClassLoader JavaDoc getNutClassLoader(String JavaDoc classpath){
163     try{
164       return NutsUtils.getClassLoader(getClass().getClassLoader(),
165           classpath,
166           env.getBaseDir());
167     }
168     catch(MalformedURLException JavaDoc e){
169       throw new ConfigurationException("invalid classpath",
170           loc);
171     }
172   }
173   /**
174    * The framework calls this method to set the tag name.
175    * @param name the tag name.
176    */

177   public void initTagName(String JavaDoc name){
178     this.tagname = name;
179   }
180   /**
181    * Get the environment that the Nut object is running in.
182    */

183   public NutEnvironment getNutEnvironment() {
184     return env;
185   }
186
187   /**
188    * Convert an object to a target type.
189    * @param target_type the target type.
190    * @param v the object to be converted.
191    * @return the object of the target type.
192    */

193   public Object JavaDoc convert(Class JavaDoc target_type, Object JavaDoc v){
194     return env.convert(target_type, v, loc);
195   }
196   /**
197    * Transforms a Component so that the instantiated instance
198    * is converted to the target type.
199    * @param target_type the target type.
200    * @param c the component.
201    * @return the new Component with the conversion in effect.
202    */

203   public Component cast(final Class JavaDoc target_type, Component c){
204     return env.cast(target_type, c, this.getTagLocation());
205   }
206   /**
207    * Get the tag name.
208    */

209   public String JavaDoc getTagName() {
210     return tagname;
211   }
212   
213   /**
214    * Register a Component to be eagerly instantiated using the current tag's id.
215    * @param c the Component to be eagerly instantiated.
216    */

217   public void registerEagerInstantiation(Component c){
218     if(!globallyDefined){
219       raise("only global tags can be registered as eager instantiated");
220     }
221     /*
222     if(id==null){
223       raise("id is required to eager initialize a Component");
224     }*/

225     env.registerEagerInstantiation(seq_no, id, c);
226   }
227   /**
228    * Throws a ConfigurationException with the current tag name and location information.
229    * @param msg the error message.
230    * @return This method never returns. The return type is for
231    * callers to get around of the type system so that you can say
232    * "throw raise(...)".
233    */

234   public ConfigurationException raise(String JavaDoc msg){
235     throw new ConfigurationException(tagname+": " + msg, loc);
236   }
237   /**
238    * Throws a ConfigurationException with the current tag name and location information.
239    * @param e the nested exception.
240    * @return This method never returns. The return type is for
241    * callers to get around of the type system so that you can say
242    * "throw raise(...)".
243    */

244   public ConfigurationException raise(Throwable JavaDoc e){
245     throw new ConfigurationException(tagname+": " + e.getMessage(), e, loc);
246   }
247   
248   /**
249    * Make sure an object is not null.
250    * Proper error message is reported otherwise.
251    * @param attrname the name of the checked attribute.
252    * @param v the attribute value.
253    */

254   protected void checkMandatory(String JavaDoc attrname, Object JavaDoc v){
255     if(v==null)
256       raise("missing mandatory attribute <"+attrname +">");
257   }
258   /**
259    * Make sure at least one of two attributes is present.
260    * @param name1 the name of the first attribute.
261    * @param v1 the value of the first attribute.
262    * @param name2 the name of the second attribute.
263    * @param v2 the value of the second attribute.
264    */

265   protected void checkMandatory(String JavaDoc name1, Object JavaDoc v1,
266       String JavaDoc name2, Object JavaDoc v2){
267     if(v1==null&&v2==null)
268       raise("either <"+name1+"> or <"+ name2+ "> has to be specified.");
269   }
270   /**
271    * Makes sure that a certain attribute is not set yet
272    * to avoid duplicate setting.
273    * @param attrname the attribute name.
274    * @param v the attribute value.
275    */

276   protected void checkDuplicate(String JavaDoc attrname, Object JavaDoc v){
277     if(v!=null){
278       raise("attribute <"+attrname+"> already specified.");
279     }
280   }
281   /**
282    * Makes sure the array only contains one element.
283    * This is useful for tags accepting only one sub-element.
284    * @param vals the value array.
285    */

286   /*protected void checkSingleChild(Object[] vals){
287     if(vals.length>1)
288       throw raise("only one sub-element is allowed");
289   }*/

290   
291   /**
292    * To get the ParameterBinder object that encapsulates the auto-wiring strategy
293    * for a autowire mode specified by the mode name.
294    *
295    * @param mode the mode name.
296    * @return the ParameterBinder object for the auto-wiring strategy.
297    * null is returned if this indicates a manual-wire.
298    */

299   public ParameterBinder getParameterWiring(String JavaDoc mode){
300     return env.getParameterWiringMode(mode, loc);
301   }
302   /**
303    * To get the PropertyBinder object that encapsulates the auto-wiring strategy
304    * for a autowire mode specified by the mode name.
305    *
306    * @param mode the mode name.
307    * @return the PropertyBinder object for the auto-wiring strategy.
308    * null is returned if this indicates a manual-wire.
309    */

310   public PropertyBinder getPropertyWiring(String JavaDoc mode){
311     return env.getPropertyWiringMode(mode, loc);
312   }
313   
314   //should have a method eval(). return type can be anything.
315
}
316
Popular Tags