001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * bstefanescu 016 */ 017package org.nuxeo.ecm.webengine.forms.validation; 018 019import java.lang.reflect.Array; 020import java.util.Calendar; 021import java.util.Date; 022import java.util.TimeZone; 023import java.util.regex.Matcher; 024import java.util.regex.Pattern; 025 026import org.nuxeo.ecm.webengine.WebEngine; 027import org.nuxeo.runtime.api.Framework; 028 029/** 030 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 031 */ 032public abstract class TypeConvertor<T> { 033 034 public abstract Class<?> getType(); 035 036 public abstract T convert(String value) throws ValidationException; 037 038 public Object[] newArray(int length) { 039 return (Object[]) Array.newInstance(getType(), length); 040 } 041 042 @SuppressWarnings("unchecked") 043 public static <T> TypeConvertor<T> getConvertor(Class<T> type) { 044 if (type == String.class) { 045 return null; 046 } 047 TypeConvertor<?> result = null; 048 if (type == Boolean.class) { 049 result = BOOLEAN; 050 } else if (type == Date.class) { 051 result = DATE; 052 } else if (type == Integer.class) { 053 result = INTEGER; 054 } else if (type == Float.class) { 055 result = FLOAT; 056 } else if (type == Long.class) { 057 result = LONG; 058 } else if (type == Double.class) { 059 result = DOUBLE; 060 } else if (type == Class.class) { 061 result = CLASS; 062 } else { 063 throw new IllegalArgumentException("Unsupported type: " + type); 064 } 065 return (TypeConvertor<T>) result; 066 } 067 068 public static final TypeConvertor<Boolean> BOOLEAN = new TypeConvertor<Boolean>() { 069 @Override 070 public Class<?> getType() { 071 return Boolean.class; 072 } 073 074 @Override 075 public Boolean convert(String value) throws ValidationException { 076 if ("true".equals(value)) { 077 return Boolean.TRUE; 078 } else if ("false".equals(value)) { 079 return Boolean.FALSE; 080 } else { 081 throw new ValidationException(); 082 } 083 } 084 }; 085 086 public static final TypeConvertor<Integer> INTEGER = new TypeConvertor<Integer>() { 087 @Override 088 public Class<?> getType() { 089 return Integer.class; 090 } 091 092 @Override 093 public Integer convert(String value) throws ValidationException { 094 try { 095 return Integer.valueOf(value); 096 } catch (NumberFormatException e) { 097 throw new ValidationException(); 098 } 099 } 100 }; 101 102 public static final TypeConvertor<Long> LONG = new TypeConvertor<Long>() { 103 @Override 104 public Class<?> getType() { 105 return Long.class; 106 } 107 108 @Override 109 public Long convert(String value) throws ValidationException { 110 try { 111 return Long.valueOf(value); 112 } catch (NumberFormatException e) { 113 throw new ValidationException(); 114 } 115 } 116 }; 117 118 public static final TypeConvertor<Float> FLOAT = new TypeConvertor<Float>() { 119 @Override 120 public Class<?> getType() { 121 return Float.class; 122 } 123 124 @Override 125 public Float convert(String value) throws ValidationException { 126 try { 127 return Float.valueOf(value); 128 } catch (NumberFormatException e) { 129 throw new ValidationException(); 130 } 131 } 132 }; 133 134 public static final TypeConvertor<Double> DOUBLE = new TypeConvertor<Double>() { 135 @Override 136 public Class<?> getType() { 137 return Double.class; 138 } 139 140 @Override 141 public Double convert(String value) throws ValidationException { 142 try { 143 return Double.valueOf(value); 144 } catch (NumberFormatException e) { 145 throw new ValidationException(); 146 } 147 } 148 }; 149 150 public static final TypeConvertor<Date> DATE = new TypeConvertor<Date>() { 151 @Override 152 public Class<?> getType() { 153 return Date.class; 154 } 155 156 @Override 157 public Date convert(String value) throws ValidationException { 158 try { 159 return parseDate(value); 160 } catch (IllegalArgumentException e) { 161 throw new ValidationException(); 162 } 163 } 164 }; 165 166 public static final TypeConvertor<Class<?>> CLASS = new TypeConvertor<Class<?>>() { 167 @Override 168 public Class<?> getType() { 169 return Class.class; 170 } 171 172 @Override 173 public Class<?> convert(String value) throws ValidationException { 174 try { 175 return loadClass(value); 176 } catch (ReflectiveOperationException e) { 177 throw new ValidationException(); 178 } 179 } 180 }; 181 182 public static Class<?> loadClass(String name) throws ReflectiveOperationException { 183 return Framework.getLocalService(WebEngine.class).loadClass(name); 184 } 185 186 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}))?"); 187 188 /** 189 * Parse the serialized string form into a java.util.Date 190 * 191 * @param date The serialized string form of the date 192 * @return The created java.util.Date 193 */ 194 public static Date parseDate(String date) { 195 Matcher m = PATTERN.matcher(date); 196 if (m.find()) { 197 Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 198 int hoff = 0, moff = 0, doff = -1; 199 if (m.group(9) != null) { 200 doff = m.group(9).equals("-") ? 1 : -1; 201 hoff = doff * (m.group(10) != null ? Integer.parseInt(m.group(10)) : 0); 202 moff = doff * (m.group(11) != null ? Integer.parseInt(m.group(11)) : 0); 203 } 204 c.set(Calendar.YEAR, Integer.parseInt(m.group(1))); 205 c.set(Calendar.MONTH, m.group(2) != null ? Integer.parseInt(m.group(2)) - 1 : 0); 206 c.set(Calendar.DATE, m.group(3) != null ? Integer.parseInt(m.group(3)) : 1); 207 c.set(Calendar.HOUR_OF_DAY, m.group(4) != null ? Integer.parseInt(m.group(4)) + hoff : 0); 208 c.set(Calendar.MINUTE, m.group(5) != null ? Integer.parseInt(m.group(5)) + moff : 0); 209 c.set(Calendar.SECOND, m.group(6) != null ? Integer.parseInt(m.group(6)) : 0); 210 c.set(Calendar.MILLISECOND, m.group(7) != null ? Integer.parseInt(m.group(7)) : 0); 211 return c.getTime(); 212 } else { 213 throw new IllegalArgumentException("Invalid Date Format"); 214 } 215 } 216 217}