/* * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser General Public License * (LGPL) version 2.1 which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * * 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. * * Contributors: * bstefanescu */ package org.nuxeo.ecm.webengine.forms.validation; import java.lang.reflect.Array; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.nuxeo.ecm.webengine.WebEngine; import org.nuxeo.runtime.api.Framework; /** * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> * */ public abstract class TypeConvertor<T> { public abstract Class<?> getType(); public abstract T convert(String value) throws ValidationException; public Object[] newArray(int length) { return (Object[])Array.newInstance(getType(), length); } @SuppressWarnings("unchecked") public static <T> TypeConvertor<T> getConvertor(Class<T> type) { if (type == String.class) { return null; } TypeConvertor<?> result = null; if (type == Boolean.class) { result = BOOLEAN; } else if (type == Date.class) { result = DATE; } else if (type == Integer.class) { result = INTEGER; } else if (type == Float.class) { result = FLOAT; } else if (type == Long.class) { result = LONG; } else if (type == Double.class) { result = DOUBLE; } else if (type == Class.class) { result = CLASS; } else { throw new IllegalArgumentException("Unsupported type: "+type); } return (TypeConvertor<T>)result; } public static final TypeConvertor<Boolean> BOOLEAN = new TypeConvertor<Boolean>() { @Override public Class<?> getType() { return Boolean.class; } @Override public Boolean convert(String value) throws ValidationException { if("true".equals(value)) { return Boolean.TRUE; } else if ("false".equals(value)) { return Boolean.FALSE; } else { throw new ValidationException(); } } }; public static final TypeConvertor<Integer> INTEGER = new TypeConvertor<Integer>() { @Override public Class<?> getType() { return Integer.class; } @Override public Integer convert(String value) throws ValidationException { try { return Integer.valueOf(value); } catch (NumberFormatException e) { throw new ValidationException(); } } }; public static final TypeConvertor<Long> LONG = new TypeConvertor<Long>() { @Override public Class<?> getType() { return Long.class; } @Override public Long convert(String value) throws ValidationException { try { return Long.valueOf(value); } catch (NumberFormatException e) { throw new ValidationException(); } } }; public static final TypeConvertor<Float> FLOAT = new TypeConvertor<Float>() { @Override public Class<?> getType() { return Float.class; } @Override public Float convert(String value) throws ValidationException { try { return Float.valueOf(value); } catch (NumberFormatException e) { throw new ValidationException(); } } }; public static final TypeConvertor<Double> DOUBLE = new TypeConvertor<Double>() { @Override public Class<?> getType() { return Double.class; } @Override public Double convert(String value) throws ValidationException { try { return Double.valueOf(value); } catch (NumberFormatException e) { throw new ValidationException(); } } }; public static final TypeConvertor<Date> DATE = new TypeConvertor<Date>() { @Override public Class<?> getType() { return Date.class; } @Override public Date convert(String value) throws ValidationException { try { return parseDate(value); } catch (IllegalArgumentException e) { throw new ValidationException(); } } }; public static final TypeConvertor<Class<?>> CLASS = new TypeConvertor<Class<?>>() { @Override public Class<?> getType() { return Class.class; } @Override public Class<?> convert(String value) throws ValidationException { try { return loadClass(value); } catch (Exception e) { throw new ValidationException(); } } }; public static Class<?> loadClass(String name) throws Exception { return Framework.getLocalService(WebEngine.class).loadClass(name); } private static final Pattern PATTERN = Pattern.compile( "(\\d{4})(?:-(\\d{2}))?(?:-(\\d{2}))?(?:[Tt](?:(\\d{2}))?(?::(\\d{2}))?(?::(\\d{2}))?(?:\\.(\\d{3}))?)?([Zz])?(?:([+-])(\\d{2}):(\\d{2}))?"); /** * Parse the serialized string form into a java.util.Date * @param date The serialized string form of the date * @return The created java.util.Date */ public static Date parseDate(String date) { Matcher m = PATTERN.matcher(date); if (m.find()) { Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); int hoff = 0, moff = 0, doff = -1; if (m.group(9) != null) { doff = m.group(9).equals("-") ? 1 : -1; hoff = doff * (m.group(10) != null ? Integer.parseInt(m.group(10)) : 0); moff = doff * (m.group(11) != null ? Integer.parseInt(m.group(11)) : 0); } c.set(Calendar.YEAR, Integer.parseInt(m.group(1))); c.set(Calendar.MONTH, m.group(2) != null ? Integer.parseInt(m.group(2))-1 : 0); c.set(Calendar.DATE, m.group(3) != null ? Integer.parseInt(m.group(3)) : 1); c.set(Calendar.HOUR_OF_DAY, m.group(4) != null ? Integer.parseInt(m.group(4)) + hoff: 0); c.set(Calendar.MINUTE, m.group(5) != null ? Integer.parseInt(m.group(5)) + moff: 0); c.set(Calendar.SECOND, m.group(6) != null ? Integer.parseInt(m.group(6)) : 0); c.set(Calendar.MILLISECOND, m.group(7) != null ? Integer.parseInt(m.group(7)) : 0); return c.getTime(); } else { throw new IllegalArgumentException("Invalid Date Format"); } } }