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    }