StringConverter.Color at revision 31322

While the idea to provide a converter from String to Color was found in GeoTools, the code has been rewritten using a different strategy (types are resolved more accurately when searching for a converter, and the various kind of conversions are separated in different convert(S) methods, so there is no sequences of ifelse statements). The only common code is the following line (indirectly, through InternalUtilities.parseColor(source)), inside a trycatch block performing a different work in case of failure:

return Color.decode(rgba);

There is no reasonable way to write the above line differently.

The code performing bitmask operation on the RGBA value in order to get the alpha value appears also in Geotoolkit.org (NumberConverter.Color). But again this is very classical operation found everywhere.

EDIT: this converter has not been ported to Apache SIS anyway, because we try to avoid direct dependency to java.awt.

The table below compares the GeoTools code with the Geotoolkit.org one.

Command line:

svn cat -r31322 https://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/util/ColorConverterFactory.java
Revision 31322Geotoolkit.org
/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.util;

import java.awt.Color;

import org.geotools.factory.Hints;

/**
 * ConverterFactory for handling color conversions.
 * <p>
 * Supported conversions:
 * <ul>
 * <li>"#FF0000" (String) -> Color.RED
 * <li>"false" -> Boolean.FALSE
 * <li>0xFF0000FF (Integer) -> RED with Alpha
 * </ul>
 * </p>
 * <p>
 * This code was previously part of the SLD utility class, it is being made
 * available as part of the Converters framework to allow for broader use.
 * </p>
 * @author Jody Garnett (Refractions Research)
 * @since 2.5
 */
public class ColorConverterFactory implements ConverterFactory {

    public Converter createConverter(Class source, Class target, Hints hints) {
        if ( target.equals( Color.class ) ) {
            // string to color
            if ( source.equals( String.class ) ) {
                return new Converter() {
                    public Object convert(Object source, Class target) throws Exception {
                        String rgba = (String) source;
                        try {
                            return Color.decode(rgba);
                        } catch (NumberFormatException badRGB) {
                            // unavailable
                            return null;
                        }
                    }
                };
            }

            // integer to color
            if ( source.equals( Integer.class ) ) {
                return new Converter() {
                    public Object convert(Object source, Class target) throws Exception {
                        Integer rgba = (Integer) source;
                        int alpha = 0xff000000 & rgba;
                        return new Color(rgba, alpha != 0 );
                    }
                };
            }
        }
        return null;
    }

}
/**
 * Converter from {@link java.lang.String} to {@link java.awt.Color}.
 * If the string begins with a leading {@code '#'} character (as in HTML codes),
 * then the remaining is understood as an hexadecimal number.
 *
 * @author Justin Deoliveira (TOPP)
 * @author Martin Desruisseaux (Geomatys)
 * @version 3.19
 *
 * @since 2.4
 */
@Immutable
static final class Color extends StringConverter<java.awt.Color> {
    private static final long serialVersionUID = 5294622747871370401L;
    public static final Color INSTANCE = new Color();
    private Color() {
    }

    @Override
    public Class<java.awt.Color> getTargetClass() {
        return java.awt.Color.class;
    }

    @Override
    public java.awt.Color convert(String source) throws NonconvertibleObjectException {
        if (source == null) {
            return null;
        }
        source = source.trim();
        try {
            return new java.awt.Color(InternalUtilities.parseColor(source), true);
        } catch (NumberFormatException e) {
            throw new NonconvertibleObjectException(e);
        }
    }

    /** Returns the singleton instance on deserialization. */
    protected Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}