KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > jmx > converter > ValueFactory


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

52
53
54
55 import java.util.Iterator JavaDoc;
56 import java.util.Map JavaDoc;
57 import java.util.TreeMap JavaDoc;
58 import org.apache.tools.ant.BuildException;
59
60
61 /**
62  * ValueFactory is a singleton implementation of ValueConverter
63  * and is considered the main entry point for ValueConverter clients.
64  * Clients should use this ValueFactory class rather than individual
65  * ValueConverter implementations.
66  *
67  * ValueConverter implementations are registered with ValueFactory
68  * using the
69  * Main factory for all ValueConverter implementations.
70  *
71  * @author <a HREF="mailto:bdueck@yahoo.com">Brian Dueck</a>
72  * @version $Id: ValueFactory.java,v 1.8 2003/05/28 22:28:26 bdueck Exp $
73  */

74 public class ValueFactory implements ValueConverter {
75
76     // map<typeName,ValueConverter>
77
//
78
private Map JavaDoc converterMap;
79     private static ValueFactory singleton = null;
80     private ValueConverter defaultConverter;
81     
82     /** Creates a new instance of ValueFactory */
83     private ValueFactory(ValueConverter defaultConverter) {
84         converterMap = new TreeMap JavaDoc();
85         this.defaultConverter = defaultConverter;
86     }
87         
88     private ValueFactory() {
89         this(new DefaultValueConverter());
90         converterMap = new TreeMap JavaDoc();
91     }
92     
93     /**
94      * Returns the singleton instance of ValueFactory.
95      *
96      */

97     public static ValueFactory getInstance() {
98         if (singleton == null) {
99             ValueConverter converter = new DefaultValueConverter();
100             singleton = new ValueFactory(converter);
101             singleton.registerValueConverter(converter);
102             singleton.registerValueConverter(new PropertiesValueConverter());
103             singleton.registerValueConverter(new SetValueConverter());
104         }
105         return singleton;
106     }
107     
108     /**
109      * Registers a ValueConverter with this ValueFactory.
110      * After the ValueConverter has been registered, the ValueFactory
111      * will automatically delegate calls to its valueOf() method
112      * to the appropriate ValueConverter for the type being referenced.
113      *
114      * @param converter The ValueConverter to register.
115      */

116     public void registerValueConverter(ValueConverter converter) {
117         if (converter != null) {
118             String JavaDoc[] types = converter.getSupportedTypes();
119             for (int counter = 0; counter < types.length; counter++) {
120                 converterMap.put(types[counter],converter);
121             }
122         }
123     }
124
125     /**
126      * Search up through the class hierarchy to find a suitable ValueConverter.
127      * Preferences is to find a ValueConverter that supports one of the
128      * classes in the implementation hierarchy, but an acceptable alternative
129      * is to find a ValueConverter that supports at least one of the interfaces.
130      *
131      * @param theClass The class to find a ValueConverter for.
132      * @return A compatible ValueConverter for theClass, or null if none can be found.
133      */

134     private ValueConverter findConverterForClass(Class JavaDoc theClass) {
135         
136         ValueConverter converter = (ValueConverter) converterMap.get(theClass.getName());
137         if (converter == null) {
138             // check to see if any of the types interfaces or supertypes are
139
// supported by a ValueConverter.
140
//
141
Class JavaDoc superClass = theClass.getSuperclass();
142             if (superClass != null) {
143                 converter = findConverterForClass(theClass);
144             }
145             Class JavaDoc[] interfaces = theClass.getInterfaces();
146             for (int counter = 0; counter < interfaces.length; counter++) {
147                 converter = findConverterForClass(interfaces[counter]);
148                 if (converter != null) {
149                     break;
150                 }
151             }
152         }
153
154         return converter;
155     }
156     
157     public Object JavaDoc valueOf(String JavaDoc value, String JavaDoc type) throws Exception JavaDoc {
158         // find the converter that supports the specified type
159
//
160
ValueConverter converter = (ValueConverter) converterMap.get(type);
161         if (converter == null) {
162             Class JavaDoc theClass = Thread.currentThread().getContextClassLoader().loadClass(type);
163             if ( (theClass != null) & (theClass.isArray()) ) {
164                 return valueOfArray(value,type);
165             } else {
166                 converter = findConverterForClass(theClass);
167             }
168         }
169         
170         if (converter == null) {
171             // use the defaultConverter
172
//
173
converter = defaultConverter;
174         }
175         
176         try {
177             return converter.valueOf(value,type);
178         } catch (Exception JavaDoc x) {
179             throw new org.apache.tools.ant.BuildException("Cannot convert property of type ["+type+"]. "
180              + "JMX4Ant provides support via reflection for any class with a static valueOf() method, and any class with a constructor "
181              + "with a single String argument. JMX4Ant also provides "
182              + "explicit support for values and arrays of the following types or subtypes: "
183              + converterMap.keySet().toString(),x);
184         }
185             
186         
187     }
188
189     /**
190      * Parses and converts a string representation of an array into an array of
191      * the specified type.
192      * For example, if the <code>value</code> parameter was set to
193      * <code>[red, blue, green]</code> and the <code>type</code> parameter was
194      * set to java.lang.String, this function would return an array of strings
195      * with length of three containing the values "red", "green" and "blue" in
196      *
197      * @param value The string representation of the array.
198      * @param type The class name for the array.
199      * @return The array.
200      * @throws Exception If an error occurs.
201      */

202     private Object JavaDoc[] valueOfArray(String JavaDoc value, String JavaDoc type) throws Exception JavaDoc {
203         Class JavaDoc arrayClass = Thread.currentThread().getContextClassLoader().loadClass(type);
204         if ( (arrayClass != null) & (arrayClass.isArray()) ) {
205             java.util.StringTokenizer JavaDoc tokenizer = new java.util.StringTokenizer JavaDoc(value," []{}\t\n");
206             java.util.ArrayList JavaDoc result = new java.util.ArrayList JavaDoc();
207             while (tokenizer.hasMoreTokens()) {
208                 String JavaDoc arrayValue = tokenizer.nextToken();
209                 result.add(valueOf(arrayValue,arrayClass.getComponentType().getName()));
210             }
211             
212             // convert the ArrayList to an actual array of the specified type
213
//
214
Object JavaDoc[] resultArray = (Object JavaDoc[])java.lang.reflect.Array.newInstance(arrayClass.getComponentType(), result.size());
215             Iterator JavaDoc it = result.iterator();
216             
217             int counter = 0;
218             while (it.hasNext()) {
219                 resultArray[counter] = it.next();
220                 counter++;
221             }
222             return resultArray;
223         } else {
224             throw new BuildException("Was expecting ["+type+"] to be an array.");
225         }
226     }
227
228     public String JavaDoc[] getSupportedTypes() {
229         return (String JavaDoc[]) converterMap.keySet().toArray();
230     }
231     
232     
233     
234     /**
235      * Stringifies an array.
236      */

237     public static String JavaDoc arrayToString(Object JavaDoc array) {
238         Object JavaDoc[] objectArray = (Object JavaDoc[]) array;
239         StringBuffer JavaDoc result = new StringBuffer JavaDoc("[");
240         
241         for (int counter = 0; counter < objectArray.length; counter++) {
242             result.append(objectArray[counter].toString());
243             if ((counter+1) < objectArray.length) {
244                 result.append("\t");
245             }
246         }
247         result.append("]");
248         return result.toString();
249                 
250     }
251     
252     /**
253      * Stringifies a value - can handle array and
254      * non-array values.
255      */

256     public static String JavaDoc toString(Object JavaDoc value) {
257         String JavaDoc stringValue = null;
258         if ( (value != null) && (value.getClass().isArray()) ) {
259             stringValue = arrayToString(value);
260         } else if (value != null) {
261             stringValue = value.toString();
262         }
263         
264         return stringValue;
265     }
266 }
267
268 /*
269  * $Log: ValueFactory.java,v $
270  * Revision 1.8 2003/05/28 22:28:26 bdueck
271  * *** empty log message ***
272  *
273  * Revision 1.7 2003/05/26 23:48:57 bdueck
274  * Removed debug messages
275  *
276  * Revision 1.6 2003/05/26 22:06:53 bdueck
277  * Improved error message to reflect new support for arrays.
278  *
279  * Revision 1.5 2003/05/26 22:04:58 bdueck
280  * Added support for arrays.
281  *
282  * Revision 1.4 2003/05/26 10:42:41 bdueck
283  * Minor reformatting of error message.
284  *
285  * Revision 1.3 2003/05/26 10:10:56 bdueck
286  * *** empty log message ***
287  *
288  * Revision 1.2 2003/04/21 15:29:45 bdueck
289  * Various changes in preparation for version 1.2.
290  *
291  *
292  */

293
Popular Tags