KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > idaremedia > antx > starters > IterationConfigurator


1 /**
2  * $Id: IterationConfigurator.java 180 2007-03-15 12:56:38Z ssmc $
3  * Copyright 2004-2005 iDare Media, Inc. All rights reserved.
4  *
5  * Originally written by iDare Media, Inc. for release into the public domain. This
6  * library, source form and binary form, is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License (LGPL) as published
8  * by the Free Software Foundation; either version 2.1 of the License, or (at your option)
9  * any later version.<p>
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU LGPL for more details.<p>
14  *
15  * You should have received a copy of the GNU Lesser General Public License along with this
16  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
17  * 330, Boston, MA 02111-1307 USA. The GNU LGPL can be found online at
18  * http://www.fsf.org/copyleft/lesser.html<p>
19  *
20  * This product has been influenced by several projects within the open-source community.
21  * The JWare developers wish to acknowledge the open-source community's support. For more
22  * information regarding the open-source products used within JWare, please visit the
23  * JWare website.
24  *----------------------------------------------------------------------------------------*
25  * WEBSITE- http://www.jware.info EMAIL- inquiries@jware.info
26  *----------------------------------------------------------------------------------------*
27  **/

28
29 package com.idaremedia.antx.starters;
30
31 import java.lang.reflect.Field JavaDoc;
32
33 import org.apache.tools.ant.BuildException;
34 import org.apache.tools.ant.Project;
35
36 import com.idaremedia.antx.AssertableLibDefinition;
37 import com.idaremedia.antx.FixtureInitializer;
38 import com.idaremedia.antx.Iteration;
39 import com.idaremedia.antx.helpers.Tk;
40
41 /**
42  * Fixture administrator that initializes an (internal) iteration field. Iteration
43  * configurators make it possible to support a variety of extensions to iteration w/o
44  * polluting the class with public setters and other implementation-specific class
45  * signatures.
46  *
47  * @since JWare/AntX 0.5
48  * @author ssmc, &copy;2004-2005 <a HREF="http://www.jware.info">iDare&nbsp;Media,&nbsp;Inc.</a>
49  * @version 0.5
50  * @.safety special (object setters are single, injection is guarded)
51  * @.group impl,infra
52  * @.pattern Fowler.DependencyInjection
53  * @see Iteration
54  **/

55
56 public abstract class IterationConfigurator extends AssertableLibDefinition
57     implements FixtureInitializer
58 {
59     /**
60      * Initializes a new iteration configurator.
61      * @param iam CV-label (non-null)
62      **/

63     protected IterationConfigurator(String JavaDoc iam)
64     {
65         super(iam);
66     }
67
68
69
70     /**
71      * Initializes a new iteration configurator to setup the
72      * named field.
73      * @param iam CV-label (non-null)
74      * @param fieldName iteration field name (non-null)
75      **/

76     protected IterationConfigurator(String JavaDoc iam, String JavaDoc fieldName)
77     {
78         super(iam);
79         setInjectionFieldName(fieldName);
80     }
81
82
83
84     /**
85      * Set the name of the field this configuration initializes.
86      * @param fieldName iteration field name (non-null)
87      **/

88     protected void setInjectionFieldName(String JavaDoc fieldName)
89     {
90         require_(fieldName!=null,"setField- nonzro field");
91         m_fieldName = fieldName;
92     }
93
94
95
96     /**
97      * Returns the name of the field this configuration will
98      * try to initialize. Will return <i>null</i> if never set
99      * explicitly.
100      **/

101     protected final String JavaDoc getInjectionFieldName()
102     {
103         return m_fieldName;
104     }
105
106
107
108     /**
109      * Factory method for this configurator's iteration field
110      * value. The returned object is usually configured via normal
111      * Ant reflection mechanisms. The configurator subclass must
112      * ensure that the returned field object and the declared
113      * field's type are compatible.
114      * @param currentValue the current value of the context field
115      * @return the field value to be injected
116      * @see com.idaremedia.antx.Defaults#mergeBehavior()
117      **/

118     protected abstract Object JavaDoc newInjectionField(Object JavaDoc currentValue);
119
120
121
122     /**
123      * Ensures this configurator has been assigned a valid field
124      * name. Subclasses will usually check that the current installed
125      * Iteration is of expected class.
126      * @throws BuildException if field name not initialized
127      **/

128     protected void verifyCanExecute_(String JavaDoc calr)
129     {
130         verifyInProject_(calr);
131
132         if (m_fieldName==null) {
133             String JavaDoc e = uistrs().get("fixture.ioc.unknown.field",
134                                    Tk.leafNameFrom(getClass()));
135             log(e,Project.MSG_ERR);
136             throw new BuildException(e,getLocation());
137         }
138     }
139
140
141
142     /**
143      * Filter method to block automatic injection mechanism.
144      * By default returns <i>true</i> (always update), but subclasses
145      * may have "opt-out" mechanisms to prevent (re)injection.
146      * This method is called <em>before</em> the standard verification
147      * method, {@linkplain #verifyCanExecute_ verifyCanExecute(&#8230;)}.
148      **/

149     protected boolean doInjection()
150     {
151         return true;
152     }
153
154
155
156     /**
157      * Called before the (current) iteration's field is set by
158      * the injection process. Does nothing by default.
159      * @param context the current iteration object (non-null)
160      * @param currentValue the current value of the context field
161      **/

162     protected void verifyInitialFieldState(Iteration context,
163         Object JavaDoc currentValue)
164     {
165         //nothing
166
}
167
168
169
170     /**
171      * Called after the (current) iteration's field has been
172      * initialized. Subclasses can do specified usage checks on
173      * installed field (via Iteration public interface). Does
174      * nothing by default.
175      **/

176     protected void verifyAfterInjection()
177     {
178         //nothing
179
}
180
181
182
183     /**
184      * If indicated, tries to create and initialize our custom
185      * iteration field. If the condition method {@linkplain #doInjection}
186      * returns <i>false</i> this method will <em>not</em> try to alter
187      * the iteration's field(s).
188      * @throws BuildException if unable to initialize field for
189      * any reason.
190      **/

191     public void execute()
192     {
193         if (doInjection()) {
194             verifyCanExecute_("exec");
195             
196             Iteration context = Iteration.get();
197             try {
198                 Field JavaDoc f = Tk.findField(context.getClass(),m_fieldName);
199                 boolean open = openField(f);
200                 try {
201                     //- guard against concurrent modification to our field,
202
//- particularly if subclass can do merging if needed!!
203

204                     synchronized(context.getConfigLock(m_fieldName)) {
205                         Object JavaDoc current = f.get(context);
206                         verifyInitialFieldState(context,current);
207                         f.set(context,newInjectionField(current));
208                     }
209                     
210                 } finally {
211                     closeField(f,open);
212                 }
213                 
214             } catch(NoSuchFieldException JavaDoc nfX) {
215                 String JavaDoc e = uistrs().get("fixture.ioc.bad.field",
216                             Tk.leafNameFrom(context.getClass()),m_fieldName);
217                 log(e,Project.MSG_ERR);
218                 throw new BuildException(e,nfX,getLocation());
219             } catch(IllegalAccessException JavaDoc iaX) {
220                 throw new BuildException(iaX,getLocation());
221             } catch(IllegalArgumentException JavaDoc baX) {
222                 throw new BuildException(baX,getLocation());
223             }
224     
225             verifyAfterInjection();
226         }
227     }
228
229
230
231     /**
232      * Make the given iteration field accessible for update.
233      * @param f the field (non-null)
234      * @return <i>true</i> if the field was already accessible
235      **/

236     private boolean openField(Field JavaDoc f)
237     {
238         boolean is = f.isAccessible();
239         if (!is) {
240             f.setAccessible(true);
241         }
242         return is;
243     }
244
245
246
247     /**
248      * Reset the given field back to its accessibility state
249      * when {@linkplain #openField openField} was called.
250      * @param f the field (non-null)
251      * @param was <i>true</i> if the field was initially accessible
252      **/

253     private void closeField(Field JavaDoc f, boolean was)
254     {
255         if (!was) {
256             f.setAccessible(false);
257         }
258     }
259
260
261     private String JavaDoc m_fieldName;
262 }
263
264
265 /* end-of-IterationConfigurator.java */
Popular Tags