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