001    /*
002     * ============================================================================
003     * GNU Lesser General Public License
004     * ============================================================================
005     *
006     * Beanlet - JSE Application Container.
007     * Copyright (C) 2006  Leon van Zantvoort
008     * 
009     * This library is free software; you can redistribute it and/or
010     * modify it under the terms of the GNU Lesser General Public
011     * License as published by the Free Software Foundation; either
012     * version 2.1 of the License, or (at your option) any later version.
013     * 
014     * This library is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
017     * Lesser General Public License for more details.
018     * 
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
022     * 
023     * Leon van Zantvoort
024     * 243 Acalanes Drive #11
025     * Sunnyvale, CA 94086
026     * USA
027     *
028     * zantvoort@users.sourceforge.net
029     * http://beanlet.org
030     */
031    package org.beanlet;
032    
033    import java.lang.annotation.ElementType;
034    import java.lang.annotation.Retention;
035    import java.lang.annotation.RetentionPolicy;
036    import java.lang.annotation.Target;
037    
038    
039    /**
040     * <p>Members marked with this annotation are injected by the application 
041     * container during beanlet instance creation.</p>
042     * 
043     * <p>Dependency injection is supported for all member types - constructors, 
044     * methods, and fields. Constructor dependency injection is used for 
045     * injecting one or more objects into the constructor of a beanlet, resulting in 
046     * a new beanlet instance. Alternatively, beanlet instances can be created by a 
047     * (static) factory method. This factory method may defined by any class.
048     * Only one constructor or factory method may be marked with this annotation to
049     * avoid ambiguoutiy.
050     * </p>
051     *
052     * <p>Setter dependency injection is applied to all fields and (non-static) 
053     * methods that are marked with this annotation.</p>
054     * 
055     * <p>Dependency injection is performed before any lifecycle methods are invoked
056     * on the beanlet instance. All members that are marked for (non-optional) 
057     * dependency injection are guaranteed to be injected, otherwise beanlet 
058     * instance creation fails.</p>
059     * 
060     * <p><h3>Injectant Resolution</h3>
061     * <p>
062     * This section explains the process of finding the object to be injected - 
063     * further referred to as injectant - for a member that is target to dependency 
064     * injection. The following steps are performed by the application container 
065     * in listed order.
066     * </p>
067     * <p>
068     * <b>(1)</b> First step is explicit dependency injection. The {@code Inject}
069     * annotation specifies a value to be injected through the 
070     * {@link #value}, {@link #collection} or {@link #map} methods.
071     * </p>
072     * <p>
073     * <b>(2)</b> The container performs step two of injectant resulution if and 
074     * only if step one does not result in an injectant. During step two the 
075     * container checks if the member to be injected expresses a framework class.
076     * These classes include: {@link BeanletApplicationContext}, 
077     * {@link BeanletContext}, {@link BeanletMetaData}, {@link BeanletFactory} and 
078     * {@link BeanletReference}. If the target matches 
079     * {@code BeanletApplicationContext} the instance returned
080     * by {@code BeanletApplicationContext.instance()} is injected. If the target
081     * matches {@code BeanletContext} or {@code BeanletMetaData} the context or meta 
082     * data of the underlying beanlet is injected. Note that it is allowed to 
083     * parameterize the target is the parameterized type is assignable from this 
084     * beanlet.<br>
085     * If the target is assignable from {@code BeanletFactory} or
086     * {@code BeanletReference} the container will lookup the factory or reference
087     * of the beanlet referred to by the target. This process is described by the
088     * next paragraph - Beanlet Name Resolution. Once again, the target is allowed 
089     * to be parameterized as long as the parameterized type can be assigned from 
090     * the referred beanlet.
091     * </p>
092     * <p>
093     * <b>(3)</b> The final step of injectant resolution, named implicit wiring, is 
094     * only executed if the {@link Wiring} annotation is applied with the 
095     * appropiate wiring modes.</br>
096     * <br>
097     * There are three flavors of implicit wiring; 
098     * {@code BY_INFO}, {@code BY_NAME} and {@code BY_TYPE}.<br>
099     * The {@code BY_INFO} mode is used to allow injection through the info map
100     * {@code BeanletFactory.create(Map)}, 
101     * {@code BeanletApplicationContext.create(String, Map)}. If the name inferred 
102     * from the target is contained in the info map its value is injected.<br>
103     * For the {@code BY_NAME} mode, the container looks up the beanlet, which name 
104     * is inferred from the target.<br>
105     * The final wiring mode is wiring {@code BY_TYPE}. This mode looks up a beanlet
106     * that matches the target's type. Injection only succeeds if exactly one 
107     * beanlet is compliant to the target, it fails if either none or multiple 
108     * beanlets are found.
109     * </p>
110     * <p>
111     * Finally, if the three previously described steps did not result in an 
112     * injection, a {@link BeanletWiringException} is thrown by the application 
113     * container, unless the {@link #optional} method returns {@code true}.
114     * </p>
115     * 
116     * <p><h3>Beanlet Name Resolution</h3>
117     * The name of the beanlet is determined as follows:<br>
118     * <br>
119     * First, the beanlet name is extracted from the member that is to be injected.
120     * If the member is a field, the name of the field declaration is used.<br>
121     * If the member is a (setter) method, the beanlet name is derived from the 
122     * method name. The beanlet name is a substring of the method name, starting at 
123     * fourth character of the method name, cutting of {@code "set"}. The first 
124     * character of this substring is converted to lowercase.<br>
125     * Note that it is not possible to infer a beanlet name from a constructor.<br>
126     * <br>
127     * Next, the beanlet name - previously derived from the member - is overridden 
128     * if {@link #name} is set to a value other than {@code ""}.<br>
129     *
130     * <p><h3>Examples</h3>
131     * In case of the following three example classes and {@code beanlet.xml}
132     * configuration file, beanlet {@code "bar"} is injected into field {@code foo}. 
133     * As a result, beanlet {@literal "example"} has a dependency on beanlet 
134     * {@literal "bar"}.<br>
135     * <br>
136     * <b>(A)</b> Example of Constructor Dependency Injection:
137     * <pre>
138     * &#64;Wiring(BY_NAME)
139     * public class Example {
140     *     
141     *     private final Object foo;
142     *
143     *     &#64;Inject(name="foo")
144     *     public Example(Object foo) {
145     *         this.foo = foo;
146     *     }
147     *
148     *     public void someBusinessMethod() {
149     *     }
150     * }
151     * </pre>
152     *
153     * <b>(B)</b> Example of Setter Dependency Injection:
154     * <pre>
155     * &#64;Wiring(BY_NAME)
156     * public class Example {
157     *     
158     *     private Object foo;
159     *
160     *     &#64;Inject 
161     *     public void setFoo(Object foo) {
162     *         this.foo = foo;
163     *     }
164     *
165     *     public void someBusinessMethod() {
166     *     }
167     * }
168     * </pre>
169     *
170     * <b>(C)</b> Example of Field Dependency Injection:
171     * <pre>
172     * &#64;Wiring(BY_NAME)
173     * public class Example {
174     *     
175     *     &#64;Inject 
176     *     private Object foo;
177     *
178     *     public void someBusinessMethod() {
179     *     }
180     * }
181     * </pre>
182     *
183     * <p><h3>XML Representation</h3>The following xml-fragment shows how to express this annotation in xml.<br><pre><tt>&lt;beanlets xmlns="http://beanlet.org/schema/beanlet"
184     *          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
185     *          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd"&gt;
186     *  &lt;beanlet name="foo" type="com.acme.Foo"&gt;
187     *    <b>&lt;inject <i>field="bar"</i> name="" optional="false" 
188     *            value="" type="java.lang.Object" ref="" 
189     *            nill="false"/&gt;</b>
190     *  &lt;/beanlet&gt;
191     *&lt;/beanlets&gt;
192     * 
193     *&lt;beanlets xmlns="http://beanlet.org/schema/beanlet"
194     *          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
195     *          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd"&gt;
196     *  &lt;beanlet name="foo" type="com.acme.Foo"&gt;
197     *    <b>&lt;inject <i>field="bar"</i>&gt;
198     *      &lt;value value="" type="java.lang.Object" ref="" 
199     *             nill="false"/&gt;
200     *    &lt;/inject&gt;</b>
201     *  &lt;/beanlet&gt;
202     *&lt;/beanlets&gt;
203     *
204     *&lt;beanlets xmlns="http://beanlet.org/schema/beanlet"
205     *          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
206     *          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd"&gt;
207     *  &lt;beanlet name="foo" type="com.acme.Foo"&gt;
208     *    <b>&lt;inject <i>field="bar"</i>&gt;
209     *      &lt;collection type="java.util.ArrayList" synced="false" unmodifiable="false"&gt;
210     *        &lt;value value="" type="java.lang.Object" ref="" 
211     *               nill="false"/&gt;
212     *      &lt;/collection&gt;
213     *    &lt;/inject&gt;</b>
214     *  &lt;/beanlet&gt;
215     *&lt;/beanlets&gt;
216     *
217     *&lt;beanlets xmlns="http://beanlet.org/schema/beanlet"
218     *          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
219     *          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd"&gt;
220     *  &lt;beanlet name="foo" type="com.acme.Foo"&gt;
221     *    <b>&lt;inject <i>field="bar"</i>&gt;
222     *      &lt;map type="java.util.HashMap" synced="false" unmodifiable="false"&gt;
223     *        &lt;entry&gt;
224     *          &lt;key value="" type="java.lang.Object" ref="" 
225     *               nill="false"/&gt;
226     *          &lt;value value="" type="java.lang.Object" ref="" 
227     *                 nill="false"/&gt;
228     *        &lt;/entry&gt;
229     *        &lt;entry key="" value=""/&gt;
230     *      &lt;/map&gt;
231     *    &lt;/inject&gt;</b>
232     *  &lt;/beanlet&gt;
233     *&lt;/beanlets&gt;
234     *
235     *&lt;beanlets xmlns="http://beanlet.org/schema/beanlet"
236     *          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
237     *          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd"&gt;
238     *  &lt;beanlet name="foo" type="com.acme.Foo"&gt;
239     *    <b>&lt;inject <i>field="bar"</i>&gt;
240     *      &lt;beanlet name="innerFoo" type="com.acme.InnerFoo"/&gt;
241     *    &lt;/inject&gt;</b>
242     *  &lt;/beanlet&gt;
243     *&lt;/beanlets&gt;</tt></pre></p>
244     *
245     * @see Wiring
246     * @author Leon van Zantvoort
247     */
248    @Retention(RetentionPolicy.RUNTIME)
249    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD, 
250            ElementType.PARAMETER})
251    public @interface Inject {
252        
253        /**
254         * {@code true} if injection is optional, {@code false} otherwise.
255         */
256        boolean optional() default false;
257     
258        /**
259         * Overrides the name inferred from the marked member, unless it returns
260         * an empty string (""). How this name is used depends on the selected type 
261         * of wiring.
262         */
263        String name() default "";
264        
265        /**
266         * Overrides the type inferred from the marked member, unless it returns
267         * the Object class (Object.class). How this type is used depends on the 
268         * selected type of wiring.
269         */
270        Class<?> type() default Object.class;
271        
272        /**
273         * Returns the name of the beanlet to be injected. 
274         * 
275         * <p>Shortcut for {@code &#64;Inject(&#64;Value(ref=""))}</p>
276         */
277        String ref() default "";
278    
279        /**
280         * Used to inject a value as specified by this {@code Value} annotation.
281         */
282        Value value() default @Value;
283    
284        /**
285         * Used to inject a {@code Collection} or array as specified by this
286         * {@code CollectionValue} annotation.
287         */
288        CollectionValue collection() default @CollectionValue;
289        
290        /**
291         * Used to inject a {@code Map} as specified by this
292         * {@code MapValue} annotation.
293         */
294        MapValue map() default @MapValue;
295    }