001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.util;
017:
018: import java.util.Arrays;
019: import java.util.Collection;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Set;
023:
024: import org.geotools.factory.CommonFactoryFinder;
025: import org.geotools.factory.FactoryCreator;
026: import org.geotools.factory.FactoryRegistry;
027: import org.geotools.factory.GeoTools;
028: import org.geotools.factory.Hints;
029: import org.geotools.resources.LazySet;
030:
031: /**
032: * Convenience class for converting an object from one type to an object of another.
033: *
034: * @author Justin Deoliveira, The Open Planning Project
035: * @since 2.4
036: */
037: public final class Converters {
038:
039: /**
040: * Cached list of converter factories
041: */
042: static Collection factories;
043:
044: /**
045: * The service registry for this manager.
046: * Will be initialized only when first needed.
047: */
048: private static FactoryRegistry registry;
049:
050: /**
051: * Returns the service registry. The registry will be created the first
052: * time this method is invoked.
053: */
054: private static FactoryRegistry getServiceRegistry() {
055: assert Thread.holdsLock(Converters.class);
056: if (registry == null) {
057: registry = new FactoryCreator(Arrays
058: .asList(new Class[] { ConverterFactory.class, }));
059: }
060: return registry;
061: }
062:
063: private static Hints addDefaultHints(final Hints hints) {
064: final Hints completed = GeoTools.getDefaultHints();
065: if (hints != null) {
066: completed.add(hints);
067: }
068: return completed;
069: }
070:
071: /**
072: * Returns a set of all available implementations for the {@link ConverterFactory} interface.
073: *
074: * @param hints An optional map of hints, or {@code null} if none.
075: * @return Set of available ConverterFactory implementations.
076: */
077: public static synchronized Set getConverterFactories(Hints hints) {
078: hints = addDefaultHints(hints);
079: return new LazySet(getServiceRegistry().getServiceProviders(
080: ConverterFactory.class, null, hints));
081: }
082:
083: /**
084: * Convenience for {@link #convert(Object, Class, Hints)}
085: *
086: * @since 2.4
087: */
088: public static Object convert(Object source, Class target) {
089: return convert(source, target, null);
090: }
091:
092: /**
093: * Converts an object of a particular type into an object of a differnt type.
094: * <p>
095: * This method uses the {@link ConverterFactory} extension point to find a converter capable
096: * of performing the conversion. The first converter found is the one used. Using this class
097: * there is no way to guarantee which converter will be used.
098: * </p>
099: * @param source The object to convert.
100: * @param target The type of the converted value.
101: * @param hints Any hints for the converter factory.
102: *
103: * @return The converted value as an instnace of target, or <code>null</code> if a converter
104: * could not be found.
105: *
106: * @since 2.4
107: */
108: public static Object convert(Object source, Class target,
109: Hints hints) {
110: //cant convert null
111: if (source == null)
112: return null;
113:
114: //handle case of source being a direct instance of target
115: // up front
116: if (source.getClass().equals(target)) {
117: return source;
118: }
119:
120: for (Iterator i = factories().iterator(); i.hasNext();) {
121: ConverterFactory factory = (ConverterFactory) i.next();
122: Converter converter = factory.createConverter(source
123: .getClass(), target, hints);
124: if (converter != null) {
125: try {
126: Object converted = converter
127: .convert(source, target);
128: if (converted != null) {
129: return converted;
130: }
131: } catch (Exception e) {
132: //TODO: perhaps log this
133: }
134: }
135: }
136:
137: //a couple of final tries
138: if (String.class.equals(target)) {
139: return source.toString();
140: }
141: return null;
142: }
143:
144: /**
145: * Processed the {@link ConverterFactory} extension point.
146: *
147: * @return A collection of converter factories.
148: * @since 2.4
149: */
150: static Collection factories() {
151: if (factories == null)
152: factories = getConverterFactories(GeoTools
153: .getDefaultHints());
154: return factories;
155: }
156: }
|