KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > yan > Component


1 /*****************************************************************************
2  * Copyright (C) Codehaus.org. All rights reserved. *
3  * ------------------------------------------------------------------------- *
4  * The software in this package is published under the terms of the BSD *
5  * style license a copy of which has been included with this distribution in *
6  * the LICENSE.txt file. *
7  *****************************************************************************/

8 /*
9  * Created on Feb 27, 2005
10  *
11  * Author Ben Yu
12  * ZBS
13  */

14 package jfun.yan;
15
16 import java.beans.IntrospectionException JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import jfun.yan.factory.Factory;
20 import jfun.yan.factory.Pool;
21
22
23 /**
24  * Responsible for component instance creation and verification.
25  * <p>
26  * Component is immutable.
27  * All update functions such as the ones started with "with"
28  * are functional-update,
29  * which means a new Component object is created to reflect the change,
30  * while the state of the old object remains the same. </p>
31  * <p>
32  * Component is the core of Yan in the sense that most customizations
33  * of instance creation strategy can be done by
34  * combining existing Component objects. </p>
35  * <p>
36  * This is called a "combinator" approach where complex components can be
37  * constructed by combining simpler components who may be combinations of yet simpler components.
38  * </p>
39  * <p>
40  * Common combinators are included in this class to make the syntax
41  * simpler for combining components. For example: <br>
42  * <code>
43  * comp1.withArguments(args) rather than Components.withArguments(comp1, args)
44  * </code>
45  * </p>
46  *
47  * Codehaus.org.
48  *
49  * @author Ben Yu
50  * @see Components
51  * @see jfun.yan.Monad
52  */

53 public abstract class Component<T> implements Creator<T>, Typeful, Stateful{
54   /**
55    * Gets the user state of this component.
56    * null is returned by default.
57    * Subclasses can either override this method to provide user states,
58    * or call Component.withState() to associate a user state.
59    * Component.withState() is preferable.
60    */

61   public Object JavaDoc getState() {
62     return null;
63   }
64   /**
65    * Create a new Component object with the specified user state.
66    * @param obj the user state object.
67    * @return the new Component object.
68    */

69   public Component<T> withState(Object JavaDoc obj){
70     return Components.withState(this, obj);
71   }
72   /**
73    * Get the type of instances that this component is responsible to create.
74    * null is returned if the type of the component cannot be determined at the time.
75    * This is typically for components that utilize late-binding strategy where
76    * the actual component type is resolved at creation time.
77    * @return the type of the component.
78    */

79   public abstract Class JavaDoc getType();
80
81   /**
82    * Create a new Component that utilizes singleton pattern when creating instance.
83    * This new component will still use whatever the creation strategy "this" has,
84    * But it guarantees that the result is properly cached so that next time create() is called,
85    * the same instance will be returned.
86    * @return the new Component.
87    */

88   public Component<T> singleton(){
89     return Components.singleton(this);
90   }
91   /**
92    * Create a new Component that utilizes singleton pattern
93    * within a scope specified by the provided Pool object when creating instance.
94    * <br>
95    * This new component will still use whatever the creation strategy "this" has,
96    * But it guarantees that the result is properly cached so that next time create() is called,
97    * the same instance will be returned.
98    * @param scope the scope of the singleton pattern.
99    * @return the new Component.
100    */

101   public Component<T> singleton(Pool scope){
102     return Components.singleton(this, scope);
103   }
104   /**
105    * Create a Component that instantiates a factory interface.
106    * 'this' component is used as the component for product object.
107    * All factory methods in the factory interface will delegate
108    * to the product component ('this' component) to create the product.
109    *
110    * @param factory_type the class object of the factory interface.
111    * @param loader the ClassLoader to load the proxy class.
112    * @param toString the string returned by the toString() method of the proxy.
113    * @return the factory component.
114    */

115   public <F> Component<F> factory(Class JavaDoc<F> factory_type, ClassLoader JavaDoc loader,
116       String JavaDoc toString){
117     return Components.factory(this, factory_type, loader, toString);
118   }
119   /**
120    * Create a Component that instantiates a factory interface.
121    * 'this' component is used as the component for product object.
122    * All factory methods in the factory interface will delegate
123    * to the product component ('this' component) to create the product.
124    *
125    * @param factory_type the class object of the factory interface.
126    * @param toString the string returned by the toString() method of the proxy.
127    * @return the factory component.
128    */

129   public <F> Component<F> factory(Class JavaDoc<F> factory_type, String JavaDoc toString){
130     return Components.factory(this, factory_type, toString);
131   }
132   /**
133    * Create a Component that instantiates a factory interface.
134    * 'this' component is used as the component for product object.
135    * All factory methods in the factory interface will delegate
136    * to the product component ('this' component) to create the product.
137    *
138    * @param factory_type the class object of the factory interface.
139    * @return the factory component.
140    */

141   public <F> Component<F> factory(Class JavaDoc<F> factory_type){
142     return factory(factory_type, factory_type.getName());
143   }
144   /**
145    * Create a Component that instantiates the {@link Factory} interface.
146    * 'this' component is used as the component for product object.
147    * The {@link Factory#create()} method delegates
148    * to the product component ('this' component) to create the product.
149    * @param toString the string returned by the toString() method of the factory.
150    * @return the factory component.
151    */

152   public Component<Factory<T>> factory(String JavaDoc toString){
153     return Components.factory(this, toString);
154   }
155   /**
156    * Create a Component that instantiates the {@link Factory} interface.
157    * 'this' component is used as the component for product object.
158    * The {@link Factory#create()} method delegates
159    * to the product component ('this' component) to create the product.
160    *
161    * @return the factory component.
162    */

163   public Component<Factory<T>> factory(){
164     return factory("factory");
165   }
166   /**
167    * Decorate this Component so that
168    * the new Component object guards against infinite dependency loop.
169    * @return the new Component object.
170    */

171   public Component<T> guard(){
172     return Components.guard(this);
173   }
174   /**
175    * Create a new Component object that
176    * uses a given Creator to create one of its parameters.
177    * @param i the ordinal position of the parameter.
178    * @param factory the creator object for creating that argument.
179    * @return the new Component object.
180    */

181   public Component withArgument(int i,
182       Creator factory){
183     return Components.withArgument(this, i, factory);
184   }
185   /**
186    * Create a new Component object that
187    * uses a given Part object to create one of its parameters.
188    * @param i the ordinal position of the parameter.
189    * @param part the Part object for creating that argument.
190    * @return the new Component object.
191    */

192   public Component<T> withArgument(int i,
193       Part part){
194     return Components.withArgument(this, i, part);
195   }
196   /**
197    * Create a new Component object that
198    * uses given Creator objects to create its parameters.
199    * For parameter i,
200    * factories[i] is used to create it if i is between 0 and factories.length.
201    * the default creation strategy is used otherwise.
202    * @param factories the creator objects for creating arguments.
203    * @return the new Component object.
204    */

205
206   public Component<T> withArguments(Creator... factories){
207     return Components.withArguments(this, factories);
208   }
209   /**
210    * Create a new Component object that
211    * uses given ParameterBinder object to create its parameters.
212    * For each parameter identified by an ordinal position
213    * and a type, the ParameterBinder object is called to get
214    * a new Creator object, which is used to create the argument.
215    * @param binder the ParameterBinder object for creating arguments.
216    * @return the new Component object.
217    */

218   public Component<T> bindArguments(ParameterBinder binder){
219     return Components.bindArguments(this, binder);
220   }
221   /**
222    * Create a new Component object that
223    * uses a given ParameterBinder object to create one of its argument
224    * identified by its ordinal position.
225    * @param k the ordinal position of the parameter.
226    * @param binder the ParameterBinder object for creating arguments.
227    * @return the new Component object.
228    */

229   public Component<T> bindArgument(int k, ParameterBinder binder){
230     return Components.bindArgument(this, k, binder);
231   }
232   /**
233    * Create a new Component object that
234    * uses the given Part object to create all its parameters.
235    * @param part the Part object.
236    * @return the new Component object.
237    */

238   public Component<T> withArguments(Part part){
239     return Components.withArguments(this, part);
240   }
241   /**
242    * Create a new Component object that
243    * uses a given Creator object to create one of its property value.
244    *
245    * @param k the property key.
246    * @param factory the Creator object.
247    * @return the new Component object.
248    */

249   public Component<T> withProperty(Object JavaDoc k, Creator factory){
250     return Components.withProperty(this, k, factory);
251   }
252   /**
253    * Create a new Component object that
254    * uses a given Part object to create one of its property values.
255    * @param k the property key.
256    * @param p the Part object.
257    * @return the new Component object.
258    */

259   public Component<T> withProperty(Object JavaDoc k, Part p){
260     return Components.withProperty(this, k, p);
261   }
262   /**
263    * Create a new Component object that
264    * uses given Creator objects to create some of its properties.
265    * @param props the map that contains mappings between property keys
266    * and Creator objects that creates the property value.
267    * This Map object is not modified within this method.
268    * It is allowed to subsequently change the Map object
269    * after this method is called.
270    * The new change will be picked up by the component
271    * when creating instances.
272    * If a property's key is not contained in the Map object,
273    * the creation strategy is not changed for this property.
274    * @return the new Component object.
275    */

276   public Component<T> withProperties(Map props){
277     return Components.withProperties(this, props);
278   }
279   /**
280    * Create a new Component object that
281    * uses given Creator objects to create some of its properties' value.
282    * For property identified by keys[i], creators[i] is used for creating value.
283    * The keys array and creators array has to be the same length.
284    * @param keys the property keys. Duplicate key is not allowed in this array.
285    * Keys are case-sensitive.
286    * @param creators the creators for creating property values.
287    * @return the new Component object.
288    */

289   public Component<T> withProperties(String JavaDoc[] keys, Creator[] creators){
290     return Components.withProperties(this, keys, creators);
291   }
292   /**
293    * Create a new Component object that
294    * uses given PropertyBinder object to create its properties.
295    * For each property identified by a key
296    * and a type, the PropertyBinder object is called to get
297    * a new Creator object, which is used to create the property value.
298    * @param binder the PropertyBinder object for creating properties.
299    * @return the new Component object.
300    */

301   public Component<T> bindProperties(PropertyBinder binder){
302     return Components.bindProperties(this, binder);
303   }
304   /**
305    * Create a new Component object that
306    * uses given PropertyBinder object to create one of its property
307    * identified by a property key.
308    * @param k the property key.
309    * @param binder the PropertyBinder object for creating properties.
310    * @return the new Component object.
311    */

312   public Component<T> bindProperty(Object JavaDoc k, PropertyBinder binder){
313     return Components.bindProperty(this, k, binder);
314   }
315   /**
316    * Create a new Component object that uses a Part object
317    * to create all of its property values.
318    * @param p the Part object.
319    * @return the new Component object.
320    */

321   public Component<T> withProperties(Part p){
322     return Components.withProperties(this, p);
323   }
324   /**
325    * Create a new Component object that returns the given type
326    * as its component instance type when getType() or verify(Dependency) is called.
327    * If the component is not late-bound (where getType() returns null),
328    * the given type has to be same or super type of the component instance type of "this"
329    * @param type the target type.
330    * @return the new Component object.
331    */

332   public <Super> Component<Super> subsume(Class JavaDoc<Super> type){
333     return Components.subsume((Component)this, type);
334   }
335   /**
336    * Create a new Component object that returns the given type
337    * as its component instance type when getType() or verify(Dependency) is called.
338    * Unlike subsume(), this method allows "down-cast"
339    * where the current component instance type is a subtype of the given type.
340    * It also allows "stupid-cast" where the current
341    * component instance type has no is-a relationship with the target type.
342    * @param type the target type.
343    * @return the new Component object.
344    */

345   public <X> Component<X> cast(Class JavaDoc<X> type){
346     return Components.cast(this, type);
347   }
348   /**
349    * Create a new Component object that uses dynamic proxy
350    * to transform the return value 'this' Component creates
351    * to a dynamic proxy.
352    * @param itfs the interfaces to proxy to.
353    * @return the new Component object.
354    */

355   public Component proxy(Class JavaDoc... itfs){
356     return Components.proxy(this, itfs);
357   }
358   /**
359    * Create a new Component object that uses dynamic proxy
360    * to transform the return value 'this' Component creates
361    * to a dynamic proxy.
362    * @param itf the interface to proxy to.
363    * @return the new Component object.
364    */

365   public <I> Component<I> proxy(Class JavaDoc<I> itf){
366     return Components.proxy(this, itf);
367   }
368   /**
369    * Create a new Component object that uses dynamic proxy
370    * to transform the return value 'this' Component creates
371    * to a dynamic proxy.
372    * The dynamic proxy will implement all the public interfaces
373    * that the type of "this" component implements.
374    * @return the new Component object.
375    */

376   public Component proxy(){
377     return Components.proxy(this);
378   }
379   /**
380    * Create a new Component that upon creation,
381    * transforms the component instance
382    * to another instance.
383    * @param m the Map object.
384    * @return the new Component object.
385    */

386   public <To> Component<To> map(jfun.yan.Map<T,To> m){
387     return Monad.map(this, m);
388   }
389   /**
390    * Create a new Component that upon creation,
391    * mutates the component instance
392    * before it is returned.
393    * @param m the Mutation object.
394    * @return the new Component object.
395    */

396   public Component<T> mutate(Mutation<T> m){
397     return Components.mutate(this, m);
398   }
399   /**
400    * By default, all components depended by this component
401    * will be verified when this component is verified.
402    * incomplete() creates a new Component object that
403    * suppresses the verification of dependency.
404    * @return the new Component object.
405    */

406   public Component<T> incomplete(){
407     return Components.incomplete(this);
408   }
409   
410    /**
411    * Label the frame for this Component so that whenever a YanException is thrown,
412    * the provided label will be populated in the resolution trace.
413    * @param lbl the label.
414    * @return the new Component object.
415    */

416   public Component<T> label(Object JavaDoc lbl){
417     return Components.label(this, lbl);
418   }
419   /**
420    * Label the frame for this Component so that whenever a YanException is thrown,
421    * the component itself will be populated in the resolution trace.
422    * <br>
423    * It is equivalent as label(this).
424    * @return the new Component object.
425    */

426   public Component<T> label(){
427     return label(this);
428   }
429
430   /**
431    * Ignore the property identified by a key and use the default mechanism.
432    * Equivalent as this.withProperty(key, Components.useDefault()).
433    * @param key the property key.
434    * @return the new Component object.
435    */

436   public Component<T> ignoreProperty(Object JavaDoc key){
437     return withProperty(key, Components.useDefault());
438   }
439   
440   
441   /**
442    * Make a property identified by a key optional,
443    * so that when the property cannot be resolved or any of its
444    * subcomponent cannot be resolved, the default value is used instead.
445    * @param key the property key.
446    * @return the new Component object.
447    */

448   public Component<T> optionalProperty(Object JavaDoc key){
449     return Components.optionalProperty(this, key);
450   }
451   /**
452    * Make sure the properties are optional.
453    * @return the new Component object.
454    */

455   public Component<T> optionalProperties(){
456     return Components.optionalProperties(this);
457   }
458   /**
459    * Make a parameter optional,
460    * so that when the argument cannot be resolved or any of its
461    * subcomponent cannot be resolved, the default value is used instead.
462    * @param ind the ordinal position of the parameter.
463    * @return the new Component object.
464    */

465   public Component<T> optionalParameter(int ind){
466     return Components.optionalParameter(this, ind);
467   }
468   /**
469    * Make sure the parameters are optional.
470    * @return the new Component object.
471    */

472   public Component<T> optionalParameters(){
473     return Components.optionalParameters(this);
474   }
475   /**
476    * Create a Component object that will use an alternative Creator object
477    * when a certain property is passed in as default.
478    *
479    * @param key the property key.
480    * @param def the alternative Creator object.
481    * @return the new Component object.
482    */

483   public Component<T> withDefaultProperty(Object JavaDoc key, Creator def){
484     return Components.withDefaultProperty(this, key, def);
485   }
486   /**
487    * Create a Component object that will use an alternative Creator object
488    * when a certain parameter is passed in as default.
489    *
490    * @param ind the ordinal position of the parameter.
491    * @param def the alternative Creator object.
492    * @return the new Component object.
493    */

494   public Component<T> withDefaultArgument(int ind, Creator def){
495     return Components.withDefaultArgument(this, ind, def);
496   }
497   
498   /**
499    * Creates an optional Component.
500    * If this component fails, it returns the special default value indicator.
501    * @return the new Component object.
502    */

503   public Component<T> optional(){
504     return Monad.mplus(this, Components.useDefault());
505   }
506   /**
507    * Creates an optional Component.
508    * If this component fails, it uses the provided value as return value.
509    * @param val the alternative value.
510    * @return the new Component object.
511    */

512   public Component<T> option(T val){
513     return Monad.mplus(this, Components.value(val));
514   }
515   /**
516    * Create a new Component object that will recover errors
517    * happened from this Component.
518    * @param r the Recovery object.
519    * @return the new Component object.
520    */

521   public Component<T> recover(Recovery<T> r){
522     return Monad.recover(this, r);
523   }
524   /**
525    * Monadic 'bind' operation.
526    * It creates a new Component object.
527    * Upon instance creation, this Component object will
528    * <p>
529    * 1. invokes this component object to create an instance. <br>
530    * 2. feed the instance to the Binder object to get a second Creator object. <br>
531    * 3. Invoke the second Creator object to get a second instance. <br>
532    * 4. return the second instance as the instance of this Component. <br>
533    * </p>
534    * Since the actual component type is not known until creation time,
535    * null is returned for getType().
536    * @param binder the Binder object.
537    * @return the new Component object.
538    */

539   public <To> Component<To> bind(Binder<T,To> binder){
540     return Monad.bind(this, binder);
541   }
542   /**
543    * Monadic 'bind' operation.
544    * It creates a new Component object.
545    * Upon instance creation, this Component object will
546    * <p>
547    * 1. invokes this component object to create an instance. <br>
548    * 2. feed the instance to the Binder object to get a second Creator object. <br>
549    * 3. Invoke the second Creator object to get a second instance. <br>
550    * 4. return the second instance as the instance of this Component. <br>
551    * </p>
552    * Since the actual component type is not known until creation time,
553    * null is returned for getType().
554    * <br>
555    * The ComponentBinder object will also verifies the component
556    * type of this component when verifying.
557    * @param binder the ComponentBinder object.
558    * @return the new Component object.
559    */

560   public <To> Component<To> bind(ComponentBinder<T,To> binder){
561     return Monad.bind(this, binder);
562   }
563   /**
564    * Create a Component object according to the boolean value returned from this Component.
565    * @param yes the Component when the condition is true.
566    * @param no the Component when the condition is false;
567    * @return the conditional Component.
568    */

569   public <R> Component<R> ifelse(Component<R> yes, Component<R> no){
570     return Monad.ifelse((Component<Boolean JavaDoc>)this, yes, no);
571   }
572   /**
573    * Create a staged component.
574    * On instantiation, it first creates the base object using this component,
575    * then the {@link jfun.yan.ComponentBinder} object is used
576    * to do certain side-effect to complete the work.
577    * The object created by this component is finally returned as the instance.
578    * <br>
579    * Bean component, for example, is an application of staged component.
580    * <br>
581    * The {@link jfun.yan.ComponentBinder} object also takes care of verification
582    * of the base component type.
583    *
584    * @param binder the ComponentBinder object to do the side effect.
585    * @return the new Component object.
586    */

587   public Component<T> followedBy(ComponentBinder<T,?> binder){
588     return Monad.followedBy(this, binder);
589   }
590   /**
591    * Create a staged component.
592    * On instantiation, it first creates the base object using this component,
593    * then the {@link jfun.yan.Binder} object is used
594    * to do certain side-effect to complete the work.
595    * The object created by this component is finally returned as the instance.
596    * <br>
597    * Bean component, for example, is an application of staged component.
598    *
599    * @param binder the Binder object to do the side effect.
600    * @return the new Component object.
601    */

602   public Component<T> followedBy(Binder<T, ?> binder){
603     return Monad.followedBy(this, binder);
604   }
605   /**
606    * Create a staged component.
607    * On instantiation, it first creates the base object using this component,
608    * then another Creator object is used
609    * to do certain side-effect to complete the work.
610    * The object created by this component is finally returned as the instance.
611    * <br>
612    * Bean component, for example, is an application of staged component.
613    * @param c2 the Component object to do the side-effect.
614    * @return the new Component object.
615    */

616   public Component<T> followedBy(Creator<?> c2){
617     return Monad.followedBy(this, c2);
618   }
619
620   /**
621    * Monadic 'sequence' operation.
622    * It sequentially execute this component and then another one
623    * and keep the result of the second component.
624    * @param c2 the next component.
625    * @return the new Component object.
626    */

627   public <R> Component<R> seq(Creator<R> c2){
628     return Monad.seq(this, c2);
629   }
630   /**
631    * Redirects resolution of arguments to properties.
632    * So that a parameter-based component (such as ctor or method)
633    * can be used as if it were a bean component,
634    * for which withProperty, withProperties can be used to customize.
635    * <br>
636    * It is useful when applying a parameter-based component to an algorithm
637    * that relies on property-based component.
638    * @param keys the property keys for parameters.
639    * The ordinal position of each key indicates the position of the parameter.
640    * @return the redirected Component object.
641    */

642   public Component<T> fromProperties(Object JavaDoc... keys){
643     return Components.fromProperties(this, keys);
644   }
645   /**
646    * Redirects resolution of properties to arguments.
647    * So that a property-based component (such as bean)
648    * can be used as if it were a parameter-based on,
649    * for which withArgument, withArguments can be used to customize.
650    * <br>
651    * It is useful when applying a property-based component to an algorithm
652    * that relies on argument-based component.
653    * The factory() combinator, for example, relies on parameter-based component.
654    * @param keys the property keys to redirect.
655    * The ordinal position of each key indicates the position of the parameter.
656    * @return the redirected Component object.
657    */

658   public Component<T> fromArguments(Object JavaDoc... keys){
659     return Components.fromArguments(this, keys);
660   }
661   
662   /**
663    * Create a sealed component.
664    * A sealed component assumes responsibility to
665    * resolve its own dependencies.
666    * It does not attempt to look up the container
667    * to resolve any unresolved dependency.
668    * <br>
669    * seal can be used to disable auto-wiring at component level.
670    * @return the sealed Component object.
671    */

672   public Component<T> seal(){
673     return Components.seal(this);
674   }
675   /**
676    * Create a Component object
677    * that calls Java Bean setters after an instance
678    * is created by this Component object.
679    * <br>
680    * The Java Bean setters used to create the component instance are
681    * determined by the return value of this.getType() method.
682    * That means, if getType() returns Type1 while the actual instance created is
683    * a subtype of Type1, only the setters of Type1 are used.
684    * However, if this component is late-bound, where the getType() returns null,
685    * the Java Bean setters are resolved at creation time.
686    * <br>
687    * It should be noted that,
688    * for a singleton bean component obtained by calling singleton() method
689    * against the bean component, it does not cause infinite loop
690    * if any property of the component is depending on this same singleton bean componet.
691    * This is because the singleton bean component caches the instance
692    * before any of the properties are set.
693    * @return the new Component object.
694    * @throws IntrospectionException if java bean introspection fails.
695    */

696   public Component<T> bean()
697   throws java.beans.IntrospectionException JavaDoc{
698     return Components.bean(this);
699   }
700   /**
701    * Create a Component object
702    * that calls Java Bean setters after an instance is created by this Component.
703    * <br>
704    * The Java Bean setters used to create the component instance are
705    * determined by the return value of getType() method.
706    * That means, if getType() returns Type1 while the actual instance created is
707    * a subtype of Type1, only the setters of Type1 are used.
708    * However, if the base component is late-bound, where the getType() returns null,
709    * the Java Bean setters are resolved at creation time.
710    * <br>
711    * It should be noted that,
712    * for a singleton bean component obtained by calling singleton() method
713    * against the bean component, it does not cause infinite loop
714    * if any property of the component is depending on this same singleton bean componet.
715    * This is because the singleton bean component caches the instance
716    * before any of the properties are set.
717    * @param props the names of the properties used.
718    * @return the new Component object.
719    * @throws IntrospectionException if java bean introspection fails.
720    * @throws IllegalPropertyNameException if a name specified in
721    * the props Set is not a valid property name.
722    * @throws NonWritablePropertyException
723    * if a property specified has no setter.
724    * @throws IllegalArgumentException if the props array has any duplicate name.
725    */

726   public Component<T> bean(String JavaDoc... props)
727   throws java.beans.IntrospectionException JavaDoc, IllegalPropertyNameException,
728   NonWritablePropertyException, IllegalArgumentException JavaDoc{
729     return Components.bean(this, props);
730   }
731   /**
732    * Create a Component object
733    * that calls Java Bean setters after an instance is created by this Component.
734    * <br>
735    * The Java Bean setters used to create the component instance are
736    * determined by the return value of getType() method.
737    * That means, if getType() returns Type1 while the actual instance created is
738    * a subtype of Type1, only the setters of Type1 are used.
739    * However, if the base component is late-bound, where the getType() returns null,
740    * the Java Bean setters are resolved at creation time.
741    * <br>
742    * It should be noted that,
743    * for a singleton bean component obtained by calling singleton() method
744    * against the bean component, it does not cause infinite loop
745    * if any property of the component is depending on this same singleton bean componet.
746    * This is because the singleton bean component caches the instance
747    * before any of the properties are set.
748    * @param props the names of the properties used.
749    * @return the new Component object.
750    * @throws IntrospectionException if java bean introspection fails.
751    * @throws IllegalPropertyNameException if a name specified in
752    * the props Set is not a valid property name.
753    * @throws NonWritablePropertyException
754    * if a property specified has no setter.
755    */

756   public Component<T> bean(java.util.Set JavaDoc props)
757   throws java.beans.IntrospectionException JavaDoc,
758   IllegalPropertyNameException, NonWritablePropertyException{
759     return Components.bean(this, props);
760   }
761   /**
762    * Creates a Component that will call a certain method
763    * against the instance created by this Component.
764    * The return value of the method is used as the result of the
765    * created Component.
766    * @param mtd the method to call against the instance.
767    * @return the new Component object.
768    */

769   public Component method(final java.lang.reflect.Method JavaDoc mtd){
770     return Components.bindMethod(this, mtd);
771   }
772   /**
773    * Creates a Component that will call a certain public method
774    * against the instance created by this Component.
775    * The return value of the method is used as the result of the
776    * created Component.
777    * <br>
778    * If the type of the first component is statically known (getType()!=null),
779    * The method is statically resolved.
780    * Otherwise, it is resolved when the actual component instantiation happens.
781    * @param name the method name.
782    * @return the new Component object.
783    * @throws IllegalArgumentException if the static resolution of the method
784    * fails.
785    */

786   public Component method(final String JavaDoc name)
787   throws IllegalArgumentException JavaDoc{
788     return method(name, false);
789   }
790   /**
791    * Creates a Component that will call a certain method
792    * against the instance created by this Component.
793    * The return value of the method is used as the result of the
794    * created Component.
795    * <br>
796    * If the type of the first component is statically known (getType()!=null),
797    * The method is statically resolved.
798    * Otherwise, it is resolved when the actual component instantiation happens.
799    * @param name the method name.
800    * @param suppress_security whether access to non-public methods is allowed.
801    * @return the new Component object.
802    * @throws IllegalArgumentException if the static resolution of the method
803    * fails.
804    */

805   public Component method(final String JavaDoc name, boolean suppress_security)
806   throws IllegalArgumentException JavaDoc{
807     return Components.bindMethod(this, name, suppress_security);
808   }
809   
810   /**
811    * Creates a Component that will read a certain field
812    * from the instance created by this Component.
813    * @param fld the field to read.
814    * @return the new Component object.
815    */

816   public Component field(final java.lang.reflect.Field JavaDoc fld){
817     return Components.bindField(this, fld);
818   }
819   /**
820    * Creates a Component that will read a public field
821    * from the instance created by this Component.
822    * <br>
823    * If the type of the first component is statically known (getType()!=null),
824    * The field is statically resolved.
825    * Otherwise, it is resolved when the actual component instantiation happens.
826    * @param name the field name.
827    * @return the new Component object.
828    * @throws IllegalArgumentException if the static resolution of the field
829    * fails.
830    */

831   public Component field(String JavaDoc name)
832   throws IllegalArgumentException JavaDoc{
833     return field(name, false);
834   }
835   /**
836    * Creates a Component that will read a field
837    * from the instance created by this Component.
838    * <br>
839    * If the type of the first component is statically known (getType()!=null),
840    * The field is statically resolved.
841    * Otherwise, it is resolved when the actual component instantiation happens.
842    * @param name the field name.
843    * @param suppress_security whether access to non-public field is allowed.
844    * @return the new Component object.
845    * @throws IllegalArgumentException if the static resolution of the field
846    * fails.
847    */

848   public Component field(final String JavaDoc name, boolean suppress_security)
849   throws IllegalArgumentException JavaDoc{
850     return Components.bindField(this, name, suppress_security);
851   }
852   
853   /**
854    * Creates a Component that will call a certain public method
855    * against the instance created by this Component.
856    * The return value of the method is used as the result of the
857    * created Component.
858    * <br>
859    * If the type of the first component is statically known (getType()!=null),
860    * The method is statically resolved when bindMethod() is called.
861    * Otherwise, it is resolved when the actual component instantiation happens.
862    * @param name the method name.
863    * @param param_types the parameter types of the method. null indicates
864    * a parameter-less method.
865    * @return the new Component object.
866    * @throws IllegalArgumentException if the static resolution of the method
867    * fails.
868    */

869   public Component method(final String JavaDoc name, final Class JavaDoc... param_types)
870   throws IllegalArgumentException JavaDoc{
871     return method(name, param_types, false);
872   }
873   /**
874    * Creates a Component that will call a certain method
875    * against the instance created by this Component.
876    * The return value of the method is used as the result of the
877    * created Component.
878    * <br>
879    * If the type of the first component is statically known (getType()!=null),
880    * The method is statically resolved when bindMethod() is called.
881    * Otherwise, it is resolved when the actual component instantiation happens.
882    * @param name the method name.
883    * @param param_types the parameter types of the method. null indicates
884    * a parameter-less method.
885    * @param suppress_security whether access to non-public method is allowed.
886    * @return the new Component object.
887    * @throws IllegalArgumentException if the static resolution of the method
888    * fails.
889    */

890   public Component method(final String JavaDoc name, final Class JavaDoc[] param_types,
891       boolean suppress_security)
892   throws IllegalArgumentException JavaDoc{
893     return Components.bindMethod(this, name, param_types, suppress_security);
894   }
895   /**
896    * Create a Component that will return a bean property
897    * of the instance created by this component.
898    * @param name the property name.
899    * @return the new Component object.
900    * @throws IntrospectionException if introspection fails.
901    */

902   public Component getter(String JavaDoc name)
903   throws IntrospectionException JavaDoc{
904     return Components.bindGetter(this, name);
905   }
906   /**
907    * Create a Component that will set a bean property
908    * of the instance created by this component.
909    * <br>
910    * The bean instance will still be used as the result.
911    * @param name the property name.
912    * @return the new Component object.
913    * @throws IntrospectionException if introspection fails.
914    */

915   public Component<T> setter(String JavaDoc name)
916   throws IntrospectionException JavaDoc{
917     return Components.bindSetter(this, name);
918   }
919   /**
920    * Create a Component that will get an indexed property
921    * of the Java Bean instance created by this component.
922    * @param name the property name.
923    * @param ind the index.
924    * @return the new Component object.
925    * @throws IntrospectionException if introspection fails.
926    */

927   public Component getter(String JavaDoc name, final int ind)
928   throws IntrospectionException JavaDoc{
929     return Components.bindGetter(this, name, ind);
930   }
931   /**
932    * Create a Component that will set an indexed property
933    * of the Java Bean instance created by this component.
934    * <br>
935    * The bean instance will still be used as the result.
936    * @param name the property name.
937    * @param ind the index.
938    * @return the new Component object.
939    * @throws IntrospectionException if introspection fails.
940    */

941   public Component<T> setter(String JavaDoc name, int ind)
942   throws IntrospectionException JavaDoc{
943     return Components.bindSetter(this, name, ind);
944   }
945   /**
946    * Create a new Component that repeatedly call this Component for
947    * certain amount of times.
948    * @param times the number of times to repeat.
949    * @return the new Component object.
950    */

951   public Component<T> repeat(int times){
952     return Components.repeat(this, times);
953   }
954   /**
955    * Create a Component that the "create()" method is put in a
956    * synchronized block to ensure thread safety.
957    * @return the Component object that is "synchronized".
958    */

959   public Component<T> synchronize(){
960     return Components.synchronizedComponent(this);
961   }
962 }
963
Popular Tags