001 /* 002 Copyright (c) 2009 Olivier Chafik, All Rights Reserved 003 004 This file is part of JNAerator (http://jnaerator.googlecode.com/). 005 006 JNAerator is free software: you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation, either version 3 of the License, or 009 (at your option) any later version. 010 011 JNAerator is distributed in the hope that it will be useful, 012 but WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 GNU General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with JNAerator. If not, see <http://www.gnu.org/licenses/>. 018 */ 019 package com.ochafik.lang; 020 021 import java.io.File; 022 import java.lang.reflect.Constructor; 023 import java.lang.reflect.Method; 024 import java.lang.reflect.Modifier; 025 import java.net.MalformedURLException; 026 import java.net.URI; 027 import java.net.URL; 028 import java.text.DateFormat; 029 import java.text.ParseException; 030 import java.util.Collections; 031 import java.util.Date; 032 import java.util.HashMap; 033 import java.util.Iterator; 034 import java.util.LinkedHashMap; 035 import java.util.Map; 036 import java.util.NoSuchElementException; 037 038 import org.w3c.dom.Node; 039 import org.w3c.dom.NodeList; 040 041 042 public class SyntaxUtils { 043 public static <T> T[] array(T... elements) { 044 return elements; 045 } 046 047 public static <T> boolean equal(T a, T b) { 048 if (a == null) 049 return b == null; 050 if (b == null) 051 return false; 052 return a.equals(b); 053 } 054 055 public static <T> T as(Object value, Class<T> c) { 056 if (value == null) 057 return null; 058 if (c.isAssignableFrom(value.getClass())) 059 return c.cast(value); 060 return null; 061 } 062 063 interface Converter<T> { 064 public T convert(Object value) throws Exception; 065 } 066 067 public static <T> void registerConverter(Class<T> c, Converter<T> converter) { 068 converters.put(c, converter); 069 } 070 071 static Map<Class<?>, Converter<?>> converters = new HashMap<Class<?>, Converter<?>>(); 072 static { 073 registerConverter(Date.class, new Converter<Date>() { 074 public Date convert(Object value) throws ParseException { 075 String s = value.toString(); 076 Date date = DateFormat.getDateTimeInstance().parse(s); 077 if (date == null) 078 date = DateFormat.getDateInstance().parse(s); 079 return date; 080 } 081 }); 082 083 registerConverter(Double.class, new Converter<Double>() { 084 public Double convert(Object value) throws ParseException { 085 if (value instanceof Number) 086 return ((Number)value).doubleValue(); 087 String s = value.toString(); 088 if (s.length() == 0) 089 return 0.0; 090 091 return Double.parseDouble(s); 092 } 093 }); 094 registerConverter(Float.class, new Converter<Float>() { 095 public Float convert(Object value) throws ParseException { 096 if (value instanceof Number) 097 return ((Number)value).floatValue(); 098 String s = value.toString(); 099 if (s.length() == 0) 100 return 0f; 101 102 return Float.parseFloat(s); 103 } 104 }); 105 registerConverter(Long.class, new Converter<Long>() { 106 public Long convert(Object value) throws ParseException { 107 if (value instanceof Number) 108 return ((Number)value).longValue(); 109 String s = value.toString(); 110 if (s.length() == 0) 111 return 0l; 112 113 return Long.parseLong(s); 114 } 115 }); 116 registerConverter(Integer.class, new Converter<Integer>() { 117 public Integer convert(Object value) throws ParseException { 118 if (value instanceof Number) 119 return ((Number)value).intValue(); 120 String s = value.toString(); 121 if (s.length() == 0) 122 return 0; 123 124 return Integer.parseInt(s); 125 } 126 }); 127 registerConverter(Short.class, new Converter<Short>() { 128 public Short convert(Object value) throws ParseException { 129 if (value instanceof Number) 130 return ((Number)value).shortValue(); 131 String s = value.toString(); 132 if (s.length() == 0) 133 return 0; 134 135 return Short.parseShort(s); 136 } 137 }); 138 registerConverter(String.class, new Converter<String>() { 139 public String convert(Object value) throws ParseException { 140 if (value instanceof Date) 141 return DateFormat.getDateInstance().format((Date)value); 142 return value.toString(); 143 } 144 }); 145 registerConverter(File.class, new Converter<File>() { 146 public File convert(Object value) throws ParseException { 147 if (value instanceof URI) 148 try { 149 value = ((URI)value).toURL(); 150 } catch (MalformedURLException e1) {} 151 152 if (value instanceof String) { 153 try { 154 value = new URL((String)value); 155 } catch (MalformedURLException e) {} 156 } 157 if (value instanceof URL) 158 return new File(((URL)value).getFile()); 159 160 String s = value.toString(); 161 if (s.length() == 0) 162 return null; 163 164 return new File(s); 165 } 166 }); 167 registerConverter(URL.class, new Converter<URL>() { 168 public URL convert(Object value) { 169 if (value instanceof URI) 170 try { 171 return ((URI)value).toURL(); 172 } catch (MalformedURLException e1) {} 173 174 if (value instanceof File) 175 try { 176 return ((File)value).toURI().toURL(); 177 } catch (MalformedURLException e1) {} 178 179 String s = value.toString(); 180 if (s.length() == 0) 181 return null; 182 183 try { 184 return new URL(s); 185 } catch (MalformedURLException e) {} 186 187 try { 188 return new File(s).toURI().toURL(); 189 } catch (MalformedURLException e) {} 190 191 return null; 192 } 193 }); 194 } 195 196 @SuppressWarnings("unchecked") 197 public static <T> T convert(Object value, Class<T> c) { 198 if (value == null) 199 return null; 200 201 Class<?> type = value.getClass(); 202 if (c.isAssignableFrom(type)) 203 return c.cast(value); 204 205 Converter<T> converter = (Converter<T>)converters.get(c); 206 if (converter != null) 207 try { 208 return converter.convert(value); 209 } catch (Exception e) { 210 e.printStackTrace(); 211 } 212 213 for (Constructor<?> cons : c.getConstructors()) { 214 Class<?>[] parameterTypes = cons.getParameterTypes(); 215 if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(type)) { 216 try { 217 return (T)cons.newInstance(value); 218 } catch (Exception e) { 219 e.printStackTrace(); 220 } 221 } 222 } 223 224 for (Method meth : c.getMethods()) { 225 String name = meth.getName(); 226 if ((meth.getModifiers() & Modifier.STATIC) == 0) 227 continue; 228 229 if (!" parse createInstance newInstance ".contains(" " + name + " ")) 230 continue; 231 232 Class<?>[] parameterTypes = meth.getParameterTypes(); 233 if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(type)) { 234 try { 235 return (T)meth.invoke(null, value); 236 } catch (Exception e) { 237 e.printStackTrace(); 238 } 239 } 240 } 241 return null; 242 } 243 244 public static class EasyMap<K, V> extends LinkedHashMap<K, V> { 245 private static final long serialVersionUID = -3087972422440202407L; 246 247 public EasyMap<K, V> add(K key, V value) { 248 put(key, value); 249 return this; 250 } 251 } 252 public static <K, V> EasyMap<K, V> map(K key, V value) { 253 return new EasyMap<K, V>().add(key, value); 254 } 255 256 @SuppressWarnings("unchecked") 257 public static Iterable<Node> iterable(final NodeList list) { 258 if (list == null) 259 return Collections.EMPTY_LIST; 260 261 return new Iterable<Node>() { 262 int nextPos = 0; 263 public Iterator<Node> iterator() { 264 return new Iterator<Node>() { 265 public Node next() { 266 if (nextPos >= list.getLength()) 267 throw new NoSuchElementException(); 268 return list.item(nextPos++); 269 } 270 public boolean hasNext() { 271 return nextPos < list.getLength(); 272 } 273 public void remove() { 274 throw new UnsupportedOperationException(); 275 } 276 }; 277 } 278 }; 279 } 280 }