KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > ant > AntJobRtc


1 /*
2  * This source code is heavily based on source code from the Apache
3  * Ant project. As such the following is included:
4  * ------------------------------------------------------------------
5  *
6  * The Apache Software License, Version 1.1
7  *
8  * Copyright (c) 2000,2002-2003 The Apache Software Foundation. All rights
9  * reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in
20  * the documentation and/or other materials provided with the
21  * distribution.
22  *
23  * 3. The end-user documentation included with the redistribution, if
24  * any, must include the following acknowlegement:
25  * "This product includes software developed by the
26  * Apache Software Foundation (http://www.apache.org/)."
27  * Alternately, this acknowlegement may appear in the software itself,
28  * if and wherever such third-party acknowlegements normally appear.
29  *
30  * 4. The names "Ant" and "Apache Software
31  * Foundation" must not be used to endorse or promote products derived
32  * from this software without prior written permission. For written
33  * permission, please contact apache@apache.org.
34  *
35  * 5. Products derived from this software may not be called "Apache"
36  * nor may "Apache" appear in their names without prior written
37  * permission of the Apache Group.
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This software consists of voluntary contributions made by many
54  * individuals on behalf of the Apache Software Foundation. For more
55  * information on the Apache Software Foundation, please see
56  * <http://www.apache.org/>.
57  */

58 package org.oddjob.ant;
59
60 import java.io.Serializable JavaDoc;
61 import java.util.ArrayList JavaDoc;
62 import java.util.Enumeration JavaDoc;
63 import java.util.HashMap JavaDoc;
64 import java.util.Hashtable JavaDoc;
65 import java.util.List JavaDoc;
66 import java.util.Locale JavaDoc;
67 import java.util.Map JavaDoc;
68 import java.util.Vector JavaDoc;
69
70 import org.apache.tools.ant.IntrospectionHelper;
71 import org.apache.tools.ant.Project;
72 import org.oddjob.arooa.ArooaException;
73 import org.oddjob.arooa.PropertyHelper;
74 import org.oddjob.arooa.RuntimeConfiguration;
75 import org.oddjob.arooa.reflect.RegistryLookup;
76
77
78 /**
79  * Wrapper class that holds the attributes of an element, its children, and
80  * any text within it. It then takes care of configuring that element at
81  * runtime.
82  * <p>
83  * Based on an original by <b>Stefan Bodewig</b>
84  */

85 public class AntJobRtc
86 implements RuntimeConfiguration, Serializable JavaDoc {
87
88
89     /** Name of the element to configure. */
90     private String JavaDoc elementTag = null;
91
92     /** List of child element wrappers. */
93     private final Vector JavaDoc/*<RuntimeConfigurable>*/ children = new Vector JavaDoc();
94
95     /** The element to configure. It is only used during
96      * maybeConfigure.
97      */

98     private final Object JavaDoc wrappedObject;
99
100     /** Attribute names and values. While the XML spec doesn't require
101      * preserving the order ( AFAIK ), some ant tests do rely on the
102      * exact order. The following code is copied from AttributeImpl.
103      * We could also just use SAX2 Attributes and convert to SAX1 ( DOM
104      * attribute Nodes can also be stored in SAX2 Attributes )
105      * XXX under JDK 1.4 you can just use a LinkedHashMap for this purpose -jglick
106      */

107     private List JavaDoc/*<String>*/ attributeNames = null;
108
109     /** Map of attribute names to values */
110     private Map JavaDoc/*<String,PropertyHelper>*/ attributeMap = null;
111
112     /** Text appearing within the element. */
113     private StringBuffer JavaDoc characters = null;
114
115     /** Indicates if the wrapped object has add any configured children added */
116     private boolean proxyConfigured = false;
117
118     private transient RegistryLookup registry;
119
120     private boolean nullAllowed = true;
121     
122     private final Project project;
123     
124     /**
125      * Sole constructor creating a wrapper for the specified object.
126      *
127      * @param proxy The element to configure. Must not be <code>null</code>.
128      * @param elementTag The tag name generating this element.
129      * Should not be <code>null</code>.
130      */

131     public AntJobRtc(Project project, Object JavaDoc proxy, String JavaDoc elementTag) {
132         this.project = project;
133         this.wrappedObject = proxy;
134         this.elementTag = elementTag;
135     }
136     
137     /**
138      * Get the object for which this RuntimeConfigurable holds the configuration
139      * information
140      *
141      * @return the object whose configure is held by this instance.
142      */

143     public Object JavaDoc getWrappedObject() {
144         return wrappedObject;
145     }
146
147     public void setNullAllowed(boolean value) {
148         nullAllowed = value;
149     }
150     
151     public boolean isNullAllowed() {
152         return nullAllowed;
153     }
154     
155     /**
156      * Set an attribute to a given value
157      *
158      * @param name the name of the attribute.
159      * @param value the attribute's value.
160      */

161     public void setAttribute(String JavaDoc name, String JavaDoc value) {
162         if (attributeNames == null) {
163             attributeNames = new ArrayList JavaDoc();
164             attributeMap = new HashMap JavaDoc();
165         }
166         attributeNames.add(name);
167         PropertyHelper ph = new PropertyHelper(value);
168         attributeMap.put(name, ph);
169         // if it's constant - set it immediately.
170
if (ph.isConstant()) {
171             IntrospectionHelper ih =
172                 IntrospectionHelper.getHelper(wrappedObject.getClass());
173             ih.setAttribute(project, wrappedObject, name.toLowerCase(Locale.US), value);
174         }
175     }
176
177     /**
178      * Get the PropertyHelper for an attribute.
179      *
180      * @param name The attribute name.
181      * @return The attribute's PropertyHelper.
182      */

183     public String JavaDoc getAttribute(String JavaDoc name) {
184         if (attributeMap == null) {
185             return null;
186         }
187         Object JavaDoc value = attributeMap.get(name);
188         if (value == null) {
189             return null;
190         }
191         return ((PropertyHelper)value).getValue();
192     }
193
194     /** Return the attribute map.
195      *
196      * @return Attribute name to attribute value map
197      */

198     public Hashtable JavaDoc getAttributeMap() {
199         if (attributeMap != null) {
200             return new Hashtable JavaDoc(attributeMap);
201         } else {
202             return new Hashtable JavaDoc(1);
203         }
204     }
205
206
207     /**
208      * Adds a child element to the wrapped element.
209      *
210      * @param child The child element wrapper to add to this one.
211      * Must not be <code>null</code>.
212      */

213     public void addChild(RuntimeConfiguration child) {
214         children.add(child);
215     }
216
217     /**
218      * Returns the child wrapper at the specified position within the list.
219      *
220      * @param index The index of the child to return.
221      *
222      * @return The child wrapper at position <code>index</code> within the
223      * list.
224      */

225     RuntimeConfiguration getChild(int index) {
226         return (RuntimeConfiguration) children.get(index);
227     }
228
229     /**
230      * Returns an enumeration of all child wrappers.
231      * @return an enumeration of the child wrappers.
232      */

233     public Enumeration JavaDoc getChildren() {
234         return children.elements();
235     }
236
237     /**
238      * Adds characters from #PCDATA areas to the wrapped element.
239      *
240      * @param data Text to add to the wrapped element.
241      * Should not be <code>null</code>.
242      */

243     public void addText(String JavaDoc data) {
244         if (data.length() == 0) {
245             return;
246         }
247         if (characters != null) {
248             characters.append(data);
249         } else {
250             characters = new StringBuffer JavaDoc(data);
251         }
252     }
253
254     /**
255      * Adds characters from #PCDATA areas to the wrapped element.
256      *
257      * @param buf A character array of the text within the element.
258      * Must not be <code>null</code>.
259      * @param start The start element in the array.
260      * @param count The number of characters to read from the array.
261      *
262      */

263     public void addText(char[] buf, int start, int count) {
264         if (count == 0) {
265             return;
266         }
267         if (characters == null) {
268             characters = new StringBuffer JavaDoc(count);
269         }
270         characters.append(buf, start, count);
271     }
272
273     /** Get the text content of this element. Various text chunks are
274      * concatenated, there is no way ( currently ) of keeping track of
275      * multiple fragments.
276      *
277      * @return the text content of this element.
278      */

279     public StringBuffer JavaDoc getText() {
280         if (characters != null) {
281             return characters;
282         } else {
283             return new StringBuffer JavaDoc(0);
284         }
285     }
286
287     /**
288      * Returns the tag name of the wrapped element.
289      *
290      * @return The tag name of the wrapped element. This is unlikely
291      * to be <code>null</code>, but may be.
292      */

293     public String JavaDoc getElementTag() {
294         return elementTag;
295     }
296
297     /**
298      * Configure with preset or no properties.
299      *
300      * @throws ArooaException If it can't be configured.
301      */

302     public void configure()
303     throws ArooaException {
304         if (registry == null) {
305             throw new NullPointerException JavaDoc("ResgistryLookup must be set");
306         } else {
307             configure(this.registry, nullAllowed);
308         }
309     }
310     
311     /**
312      * Configures the wrapped element. The attributes and text for
313      * the wrapped element are configured. Each time the wrapper is
314      * configured, the attributes and text for it are reset.
315      *
316      * If the element has an <code>id</code> attribute, a reference
317      * is added to the project as well.
318      *
319      * @param p The project containing the wrapped element.
320      * Must not be <code>null</code>.
321      *
322      * @param configureChildren Whether to configure child elements as
323      * well. if true, child elements will be configured after the
324      * wrapped element.
325      *
326      * @exception ArooaException if the configuration fails, for instance due
327      * to invalid attributes or children, or text being added to
328      * an element which doesn't accept it.
329      */

330
331     public void configure(RegistryLookup registry, boolean nullAllowed)
332             throws ArooaException {
333
334         IntrospectionHelper ih =
335             IntrospectionHelper.getHelper(wrappedObject.getClass());
336
337         if (attributeNames != null) {
338             for (int i = 0; i < attributeNames.size(); i++) {
339                 String JavaDoc name = (String JavaDoc) attributeNames.get(i);
340                 PropertyHelper propHelper = (PropertyHelper) attributeMap.get(name);
341                 // constant value will be set already.
342
if (!propHelper.isConstant()) {
343                     // reflect these into the target
344
Object JavaDoc newValue = propHelper.replaceProperties(registry, nullAllowed);
345                     // do what ant does with null properties and put them in unparsed
346
if (newValue == null) {
347                         newValue = propHelper.getValue();
348                     }
349                     ih.setAttribute(project, wrappedObject, name.toLowerCase(Locale.US), newValue.toString());
350                 }
351             }
352         }
353
354         if (characters != null) {
355             ih.addText(project, wrappedObject, characters.substring(0));
356         }
357
358         Enumeration JavaDoc e = getChildren();
359         while (e.hasMoreElements()) {
360             RuntimeConfiguration child
361                     = (RuntimeConfiguration) e.nextElement();
362
363             child.configure(registry, nullAllowed);
364             // only want to add elements once.
365
if (!proxyConfigured) {
366                 ih.storeElement(project, wrappedObject, child.getWrappedObject(), child.getElementTag());
367             }
368         }
369
370         proxyConfigured = true;
371     }
372
373     /**
374      * @return Returns the properties.
375      */

376     public RegistryLookup getRegistryLookup() {
377         return registry;
378     }
379     
380     /**
381      * @param properties The properties to set.
382      */

383     public void setRegistryLookup(RegistryLookup registry) {
384         this.registry = registry ;
385     }
386     
387 }
388
Popular Tags