001    /*
002     *  Copyright 2004 The Apache Software Foundation
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.apache.commons.convert;
017    
018    /**
019     * Converter is the central class that holds a set of registered converters
020     * together and allows conversion to occur.
021     * <p>
022     * This class allows applications to add their own converters. This is achieved
023     * by creating a new instance and using that within the application. Generally,
024     * the instance is stored in a static variable in the application.
025     * <p>
026     * In this way, the application remains independent of other converters used
027     * by other applications or libraries.
028     *
029     * @author Stephen Colebourne
030     * @version $Id: Converter.java 155441 2005-02-26 13:19:22Z dirkv $
031     * @since 1.0
032     */
033    public class Converter {
034    
035        /* The converter registry */
036        private final ConversionRegistry registry;
037    
038        /**
039         * Constructs a new instance of the Converter useful to create a set
040         * of conversions separate from the default set.
041         * <p>
042         * The created converter has no conversions registered.
043         */
044        public Converter() {
045            this(false);
046        }
047    
048        /**
049         * Constructs a new instance of the Converter useful to create a set
050         * of conversions separate from the default set.
051         * 
052         * @param addDefaults  whether to add the default conversions
053         */
054        public Converter(boolean addDefaults) {
055            super();
056            registry = createRegistry();
057            if (addDefaults) {
058                registry.addDefaultConversions();
059            }
060        }
061    
062        /**
063         * Factory method for subclasses to change the registry implementation.
064         * 
065         * @return a new, non-null, registry
066         */
067        protected ConversionRegistry createRegistry() {
068            return new ConversionRegistry();
069        }
070    
071        //-----------------------------------------------------------------------
072        /**
073         * Convert the specified input object into an output object
074         * of the another type.
075         *
076         * @param value  the input value to be converted
077         * @param fromClass  the class to convert from, useful if null passed in
078         * @param toClass  the class to convert to
079         * @return the converted value
080         * @throws ConversionException (runtime) if conversion fails
081         */
082        public Object convert(Object value, Class fromClass, Class toClass) {
083            return doConversion(value, fromClass, toClass);
084        }
085    
086        /**
087         * Convert the specified input object into an output object
088         * of the another type.
089         *
090         * @param value  the input value to be converted
091         * @param toClass  the class to convert to
092         * @return the converted value
093         * @throws ConversionException (runtime) if conversion fails
094         */
095        public Object convert(Object value, Class toClass) {
096            return doConversion(value, null, toClass);
097        }
098    
099        /**
100         * Convert the specified input object into a <code>String</code>.
101         *
102         * @param value  the input value to be converted
103         * @param fromClass  the class to convert from, useful if null passed in
104         * @return the converted value
105         * @throws ConversionException (runtime) if conversion fails
106         */
107        public String convertToString(Object value, Class fromClass) {
108            return (String) doConversion(value, fromClass, String.class);
109        }
110    
111        /**
112         * Convert the specified input object into a <code>String</code>.
113         *
114         * @param value  the input value to be converted
115         * @return the converted value
116         * @throws ConversionException (runtime) if conversion fails
117         */
118        public String convertToString(Object value) {
119            return (String) doConversion(value, null, String.class);
120        }
121    
122        //-----------------------------------------------------------------------
123        /**
124         * Convert the specified input object into an output object of another type.
125         * <p>
126         * This implementation uses {{@link #doConversion(Conversion, Object)}.
127         *
128         * @param value  the input value to be converted
129         * @param fromClass  the class to convert from, useful if null passed in
130         * @param toClass  the class to convert to
131         * @return the converted value
132         * @throws ConversionException (runtime) if conversion fails
133         */
134        protected Object doConversion(Object value, Class fromClass, Class toClass) {
135            Class valueClass = (value == null ? fromClass : value.getClass());
136            Conversion conv = getRegistry().getConversion(value, valueClass, toClass);
137            if (conv == null) {
138                throw new ConversionException("No Converter found to convert " + valueClass + " to " + toClass);
139            }
140            return doConversion(conv, value);
141        }
142    
143        /**
144         * Convert the specified input object into an output object using the conversion.
145         * <p>
146         * This implementation catches exceptions and wraps them in a <code>ConversionException</code>.
147         * 
148         * @param conversion  the conversion to use
149         * @param value  the value to convert
150         * @return the converted value
151         * @throws ConversionException (runtime) if conversion fails
152         */
153        protected Object doConversion(Conversion conversion, Object value) {
154            try {
155                return conversion.convert(value, this);
156    
157            } catch (ConversionException ex) {
158                throw ex;
159            } catch (Exception ex) {
160                throw new ConversionException(conversion.toString(), ex);
161            }
162        }
163    
164        //-----------------------------------------------------------------------
165        /**
166         * Gets the converter registry used for adding and removing converters.
167         *
168         * @return the converter registry, never null
169         */
170        public ConversionRegistry getRegistry() {
171            return registry;
172        }
173    
174        //-----------------------------------------------------------------------
175        /**
176         * Returns a string describing this object.
177         *
178         * @return a string describing this object
179         */
180        public String toString() {
181            return "Converter";
182        }
183    
184    }