Author: tchemit Date: 2010-05-11 13:07:24 +0200 (Tue, 11 May 2010) New Revision: 1848 Url: http://nuiton.org/repositories/revision/nuiton-utils/1848 Log: Evolution #594: Creates a org.nuiton.util.converter to move Converter api + deprecates Converter api in org.nuiton.util Added: trunk/src/main/java/org/nuiton/util/converter/ConverterUtil.java trunk/src/main/java/org/nuiton/util/converter/EnumConverter.java trunk/src/main/java/org/nuiton/util/converter/URIConverter.java trunk/src/main/java/org/nuiton/util/converter/URLConverter.java trunk/src/main/java/org/nuiton/util/converter/VersionConverter.java Copied: trunk/src/main/java/org/nuiton/util/converter/ConverterUtil.java (from rev 1847, trunk/src/main/java/org/nuiton/util/ConverterUtil.java) =================================================================== --- trunk/src/main/java/org/nuiton/util/converter/ConverterUtil.java (rev 0) +++ trunk/src/main/java/org/nuiton/util/converter/ConverterUtil.java 2010-05-11 11:07:24 UTC (rev 1848) @@ -0,0 +1,205 @@ +/* + * #%L + * Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * This program 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, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.util; + +import java.lang.reflect.Method; +import java.util.ServiceLoader; +import org.apache.commons.beanutils.ConvertUtils; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Une classe contenant des méthodes utiles sur les converters et les conversions + * + * @author tchemit <chemit@codelutin.com> + */ +public class ConverterUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ConverterUtil.class); + + /** + * le paquetage où chercher les implentations de Converter, si non présents + * dans le système + */ + protected static final String CONVERTER_PACKAGE = "org.nuiton.util"; + + /** un drapeau pour savoir si on doit charger les converters specifiques */ + protected static Boolean WAS_INIT = Boolean.FALSE; + + /** + * Cherche un converter pour un <code>type</code> donné. + * <p/> + * Recherche dans un premier temps dans les converteurs déjà connus. + * <p/> + * Si le type est une énum et qu'aucun converter, n'a été trouvé, on + * enregistre un nouveau convert d'enum. + * <p/> + * Sinon on tente d'instancier un converteur dans le paquetage dédié aux + * converteurs {@link #CONVERTER_PACKAGE}. + * + * @param <T> le type a convertir + * @param type le type a convertir + * @return le converter trouvé, ou null si non trouvé + */ + public static <T> Converter getConverter(Class<T> type) { + if (!WAS_INIT) { + initConverters(); + } + Converter converter = ConvertUtils.lookup(type); + if (converter != null) { + return converter; + } + if (type.isEnum()) { + registerEnumConverter(type); + return ConvertUtils.lookup(type); + } + // on essaye de trouver un converter dans le paquetage des converters + try { + registerConverter0(type); + converter = ConvertUtils.lookup(type); + } catch (Exception e) { + throw new RuntimeException(e); + } + return converter; + } + + /** + * Convertir une valeur! + * + * @param <T> le type de donnee recherchee + * @param type le type de donnee recherchee + * @param toConvert l'object a convertir + * @return la nouvelle instance de l'objet converti type ou null + */ + @SuppressWarnings({"unchecked"}) + public static <T> T convert(Class<T> type, Object toConvert) { + if (!WAS_INIT) { + initConverters(); + } + T result = null; + Converter converter = getConverter(type); + if (converter != null) { + return (T) converter.convert(type, toConvert); + } + return result; + } + + public static void registerConverter(Class<?> type) + throws IllegalAccessException, + InstantiationException, + ClassNotFoundException { + if (ConvertUtils.lookup(type) == null) { + registerConverter0(type); + } + } + + protected static void registerConverter0(Class<?> type) + throws IllegalAccessException, + InstantiationException, + ClassNotFoundException { + Class<?> aClass = Class.forName( + CONVERTER_PACKAGE + "." + type.getSimpleName() + "Converter"); + Converter converter = (Converter) aClass.newInstance(); + log.info("for type : " + type + " : " + converter); + ConvertUtils.register(converter, type); + } + + /** + * Enregistre un nouveau converter pour un type d'enum donné, avec une + * valeur par defaut. + * + * @param type le type d'enum à convertir + * @param defaultValue la valeur par defaut. + */ + public static void registerEnumConverter(Class<?> type, + Object defaultValue) { + if (EnumConverter.isEnabled(type, type) && + ConvertUtils.lookup(type) == null) { + Converter converter = new EnumConverter(type, defaultValue); + log.info("for type : " + type + " : " + converter); + ConvertUtils.register(converter, type); + } + } + + /** + * Enregistre un nouveau converter pour un type d'enum donné, sans utiliser + * de valeur par defaut. + * + * @param type le type d'enum à convertir + */ + public static void registerEnumConverter(Class<?> type) { + registerEnumConverter(type, null); + } + + public static byte[] convert(char[] chars) { + byte[] bytes = new byte[chars.length]; + for (int i = 0; i < chars.length; i++) { + bytes[i] = (byte) (chars[i] & 0xff); + } + return bytes; + } + + public static synchronized void deregister() { + ConvertUtils.deregister(); + WAS_INIT = false; + } + + public static synchronized void initConverters() { + if (WAS_INIT != null && WAS_INIT) { + return; + } + ServiceLoader<Converter> converters = + ServiceLoader.load(Converter.class); + for (Converter converter : converters) { + if (log.isDebugEnabled()) { + log.debug("discovered converter " + converter); + } + try { + Method m = converter.getClass().getDeclaredMethod("getType"); + m.setAccessible(true); + try { + Class<?> returnType = (Class<?>) m.invoke(converter); + log.info("register converter " + converter); + ConvertUtils.register(converter, returnType); + } catch (Exception ex) { + log.warn("could not obtain type of converter " + + converter + " for reason : " + ex.getMessage(), + ex); + } + } catch (NoSuchMethodException ex) { + log.warn("could not find method getType on converter " + + converter + ", will not be registred..."); + } catch (SecurityException ex) { + log.warn("could not find method getType on converter " + + converter + ", will not be registred..."); + } + + } + WAS_INIT = true; + } +} Property changes on: trunk/src/main/java/org/nuiton/util/converter/ConverterUtil.java ___________________________________________________________________ Added: svn:keywords + HeadURL Id Date Revision Author Added: svn:mergeinfo + Added: svn:eol-style + native Copied: trunk/src/main/java/org/nuiton/util/converter/EnumConverter.java (from rev 1847, trunk/src/main/java/org/nuiton/util/EnumConverter.java) =================================================================== --- trunk/src/main/java/org/nuiton/util/converter/EnumConverter.java (rev 0) +++ trunk/src/main/java/org/nuiton/util/converter/EnumConverter.java 2010-05-11 11:07:24 UTC (rev 1848) @@ -0,0 +1,152 @@ +/* + * #%L + * Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * This program 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, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.util; + +import org.apache.commons.beanutils.ConversionException; +import static org.apache.commons.logging.LogFactory.getLog; +import static org.nuiton.i18n.I18n._; + +import java.util.EnumSet; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; + +/** + * classe pour convertir une chaine en un objet Enum type-safe en + * connaissant le type d'enumération utilisée {@link #enumType}. + * <p/> + * Il est possible aussi de convertir une Enum à partir de sa valeur ordinal. + * <p/> + * Pour enregister un nouveau convertissemnt pour un type d'Enum utiliser les + * méthodes * {@link ConverterUtil#registerEnumConverter(Class)}, + * et {@link ConverterUtil#registerEnumConverter(Class,Object)} . + * + * @author tchemit <chemit@codelutin.com> + * @see Enum + * @see Enum#ordinal() + */ +public class EnumConverter implements Converter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static Log log = getLog(EnumConverter.class); + + /** valeur par default à utiliser, si pas non trouvée et {@link #useDefault} actif. */ + protected Object defaultValue; + + /** flag pour utiliser la valeur par defaut {@link #defaultValue} si non trouvé. */ + protected boolean useDefault; + + /** le type de l'énumération à convertir */ + protected Class<?> enumType; + + @Override + public Object convert(Class aClass, Object value) { + if (value == null) { + if (useDefault) { + return defaultValue; + } + throw new ConversionException( + _("nuitonutil.error.convertor.noValue", this)); + } + if (isEnabled(aClass, enumType)) { + Object result; + if (isEnabled(value.getClass(), enumType)) { + result = value; + return result; + } + if (value instanceof String) { + try { + result = valueOf(aClass, value); + } catch (IllegalArgumentException e) { + // try an ordinal conversion + result = convertFromOrdinal(aClass, value); + } + return result; + } + if (value instanceof Integer) { + // try a ordinal conversion + result = convertFromOrdinal(aClass, value); + return result; + } + } + throw new ConversionException( + _("nuitonutil.error.no.convertor", aClass.getName(), value)); + } + + public EnumConverter(Class<?> enumType, Object defaultValue) { + this.enumType = enumType; + this.defaultValue = defaultValue; + useDefault = defaultValue != null; + if (log.isDebugEnabled()) { + log.debug(toString() + '<' + enumType + '>'); + } + } + + public EnumConverter(Class<?> enumType) { + this(enumType, null); + } + + protected static boolean isEnabled(Class<?> aClass, Class<?> enumType) { + return aClass != null && aClass.isEnum() && aClass == enumType; + } + + protected Object convertFromOrdinal(Class<?> aClass, Object value) { + Object result = null; + try { + int ordinal = Integer.valueOf(value + ""); + EnumSet<?> vals = allOf(aClass); + if (ordinal > -1 && ordinal < vals.size()) { + for (Enum<?> val : vals) { + if (val.ordinal() == ordinal) { + result = val; + break; + } + } + } + } catch (NumberFormatException e1) { + // quiet conversion + result = null; + } + return result; + } + + protected Object valueOf(Class<?> aClass, Object value) { + Object result; + result = Enum.valueOf((Class<Enum>) aClass, (String) value); + return result; + } + + protected EnumSet<?> allOf(Class<?> aClass) { + EnumSet<?> vals; + vals = EnumSet.allOf((Class<Enum>) aClass); + return vals; + } + + public Class<?> getType() { + return enumType; + } + + +} Property changes on: trunk/src/main/java/org/nuiton/util/converter/EnumConverter.java ___________________________________________________________________ Added: svn:keywords + HeadURL Id Date Revision Author Added: svn:mergeinfo + Added: svn:eol-style + native Copied: trunk/src/main/java/org/nuiton/util/converter/URIConverter.java (from rev 1847, trunk/src/main/java/org/nuiton/util/URIConverter.java) =================================================================== --- trunk/src/main/java/org/nuiton/util/converter/URIConverter.java (rev 0) +++ trunk/src/main/java/org/nuiton/util/converter/URIConverter.java 2010-05-11 11:07:24 UTC (rev 1848) @@ -0,0 +1,92 @@ +/* + * #%L + * Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * This program 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, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.util; + +import org.apache.commons.beanutils.ConversionException; +import static org.apache.commons.logging.LogFactory.getLog; +import static org.nuiton.i18n.I18n._; + +import java.net.URI; +import java.net.URISyntaxException; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; + +/** + * classe pour convertir une chaine en un objet URI. + * + * @author tchemit <chemit@codelutin.com> + */ +public class URIConverter implements Converter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static Log log = getLog(URIConverter.class); + + @Override + public Object convert(Class aClass, Object value) { + if (value == null) { + throw new ConversionException( + _("nuitonutil.error.convertor.noValue", this)); + } + if (isEnabled(aClass)) { + Object result; + if (isEnabled(value.getClass())) { + result = value; + return result; + } + if (value instanceof String) { + result = valueOf((String) value); + return result; + } + } + throw new ConversionException( + _("nuitonutil.error.no.convertor", aClass.getName(), value)); + } + + protected URI valueOf(String value) { + try { + URI result; + result = new URI(value); + return result; + } catch (URISyntaxException e) { + throw new ConversionException( + _("nuitonutil.error.url.convertor", value, this, e.getMessage())); + } + } + + public URIConverter() { + if (log.isDebugEnabled()) { + log.debug(this); + } + } + + protected boolean isEnabled(Class<?> aClass) { + return URI.class.equals(aClass); + } + + public Class<?> getType() { + return URI.class; + } +} Property changes on: trunk/src/main/java/org/nuiton/util/converter/URIConverter.java ___________________________________________________________________ Added: svn:keywords + HeadURL Id Date Revision Author Added: svn:mergeinfo + Added: svn:eol-style + native Copied: trunk/src/main/java/org/nuiton/util/converter/URLConverter.java (from rev 1847, trunk/src/main/java/org/nuiton/util/URLConverter.java) =================================================================== --- trunk/src/main/java/org/nuiton/util/converter/URLConverter.java (rev 0) +++ trunk/src/main/java/org/nuiton/util/converter/URLConverter.java 2010-05-11 11:07:24 UTC (rev 1848) @@ -0,0 +1,92 @@ +/* + * #%L + * Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * This program 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, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.util; + +import org.apache.commons.beanutils.ConversionException; +import static org.apache.commons.logging.LogFactory.getLog; +import static org.nuiton.i18n.I18n._; + +import java.net.MalformedURLException; +import java.net.URL; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; + +/** + * classe pour convertir une chaine en un objet URL. + * + * @author tchemit <chemit@codelutin.com> + */ +public class URLConverter implements Converter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static Log log = getLog(URLConverter.class); + + @Override + public Object convert(Class aClass, Object value) { + if (value == null) { + throw new ConversionException( + _("nuitonutil.error.convertor.noValue", this)); + } + if (isEnabled(aClass)) { + Object result; + if (isEnabled(value.getClass())) { + result = value; + return result; + } + if (value instanceof String) { + result = valueOf((String) value); + return result; + } + } + throw new ConversionException( + _("nuitonutil.error.no.convertor", aClass.getName(), value)); + } + + protected URL valueOf(String value) { + try { + URL result; + result = new URL(value); + return result; + } catch (MalformedURLException e) { + throw new ConversionException( + _("nuitonutil.error.url.convertor", value, this, e.getMessage())); + } + } + + public URLConverter() { + log.info(this); + } + + protected boolean isEnabled(Class<?> aClass) { + return URL.class.equals(aClass); + } + + public Class<?> getType() { + return URL.class; + } + + +} Property changes on: trunk/src/main/java/org/nuiton/util/converter/URLConverter.java ___________________________________________________________________ Added: svn:keywords + HeadURL Id Date Revision Author Added: svn:mergeinfo + Added: svn:eol-style + native Copied: trunk/src/main/java/org/nuiton/util/converter/VersionConverter.java (from rev 1847, trunk/src/main/java/org/nuiton/util/VersionConverter.java) =================================================================== --- trunk/src/main/java/org/nuiton/util/converter/VersionConverter.java (rev 0) +++ trunk/src/main/java/org/nuiton/util/converter/VersionConverter.java 2010-05-11 11:07:24 UTC (rev 1848) @@ -0,0 +1,84 @@ +/* + * #%L + * Nuiton Utils + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * This program 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, either version 3 of the + * License, or (at your option) any later version. + * + * This program 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 General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.util; + +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import static org.nuiton.i18n.I18n._; + +/** + * classe pour convertir une chaine en un objet Version. + * + * @author tchemit <chemit@codelutin.com> + * @see Version + */ +public class VersionConverter implements Converter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static final Log log = LogFactory.getLog(VersionConverter.class); + + public VersionConverter() { + if (log.isDebugEnabled()) { + log.debug(this); + } + } + + @Override + public Object convert(Class aClass, Object value) { + if (value == null) { + throw new ConversionException( + _("nuitonutil.error.convertor.noValue", this)); + } + if (isEnabled(aClass)) { + Object result; + if (isEnabled(value.getClass())) { + result = value; + return result; + } + if (value instanceof String) { + try { + result = VersionUtil.valueOf((String) value); + return result; + } catch (IllegalArgumentException e) { + throw new ConversionException( + _("nuitonutil.error.version.convertor", value, this, e.getMessage()), e); + } + } + } + throw new ConversionException( + _("nuitonutil.error.no.convertor", aClass.getName(), value)); + } + + protected boolean isEnabled(Class<?> aClass) { + return Version.class.equals(aClass); + } + + public Class<?> getType() { + return Version.class; + } +} Property changes on: trunk/src/main/java/org/nuiton/util/converter/VersionConverter.java ___________________________________________________________________ Added: svn:keywords + HeadURL Id Date Revision Author Added: svn:mergeinfo +