View Javadoc

1   /**
2    * Copyright (c) 2007-2011 Southern Cross IT. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 3 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  package com.scit.sling.test;
15  
16  import java.lang.reflect.Array;
17  import java.math.BigDecimal;
18  import java.util.Calendar;
19  import java.util.Date;
20  import java.util.LinkedHashMap;
21  import java.util.Locale;
22  
23  import org.apache.commons.lang.NotImplementedException;
24  import org.apache.sling.api.resource.ValueMap;
25  import org.joda.time.DateTime;
26  import org.joda.time.format.DateTimeFormat;
27  import org.joda.time.format.DateTimeFormatter;
28  
29  /**
30   * A Mock {@link ValueMap} that has some basic type conversion.
31   * Dates should be stored as {@link DateTime} objects.
32   */
33  public class MockValueMap extends LinkedHashMap<String, Object> implements ValueMap {
34  	private static final long serialVersionUID = 1L;
35  
36  	public <T> T get(String name, Class<T> type) {
37  		return convertType(get(name), type);
38  	}
39  
40  	public <T> T get(String name, T defaultValue) {
41  		@SuppressWarnings("unchecked")
42  		T val = (T) get(name, defaultValue.getClass());
43  		if (val == null) {
44  			return defaultValue;
45  		}
46  		return val;
47  	}
48  	
49  	@SuppressWarnings("unchecked")
50  	private <T> T convertType(Object o, Class<T> type) {
51  		if (o == null) {
52  			return null;
53  		}
54  		if (o.getClass().isArray() && type.isArray()) {
55  			if (type.getComponentType().isAssignableFrom(o.getClass().getComponentType())) {
56  				return (T)o;
57  			} else {
58  				// we need to convert the elements in the array
59  				Object array = Array.newInstance(type.getComponentType(), Array.getLength(o));
60  				for (int i = 0; i < Array.getLength(o); i++) {
61  					Array.set(array, i, convertType(Array.get(o,i), type.getComponentType()));
62  				}
63  				return (T)array;
64  			}
65  		}
66  		if (o.getClass().isAssignableFrom(type)) {
67  			return (T) o;
68  		}
69  		if (String.class.isAssignableFrom(type)) {
70  			// Format dates
71  			if (o instanceof Calendar) {
72  				return (T) formatDate((Calendar)o);
73  			} else if (o instanceof Date) {
74  				return (T) formatDate((Date)o);
75  			} else if (o instanceof DateTime) {
76  				return (T) formatDate((DateTime)o);
77  			}
78  			return (T) String.valueOf(o);
79  		} else if (o instanceof DateTime) {
80  			DateTime dt = (DateTime)o;
81  			if (Calendar.class.isAssignableFrom(type)) {
82  				return (T) dt.toCalendar(Locale.getDefault());
83  			} else if (Date.class.isAssignableFrom(type)) {
84  				return (T) dt.toDate();
85  			} else if (Number.class.isAssignableFrom(type)) {
86  				return convertType(dt.getMillis(), type);
87  			}
88  		} else if (o instanceof Number && Number.class.isAssignableFrom(type)) {
89  			if (Byte.class.isAssignableFrom(type)) {
90  				return (T)(Byte)((Number)o).byteValue();
91  			} else if (Double.class.isAssignableFrom(type)) {
92  				return (T)(Double)((Number)o).doubleValue();
93  			} else if (Float.class.isAssignableFrom(type)) {
94  				return (T)(Float)((Number)o).floatValue();
95  			} else if (Integer.class.isAssignableFrom(type)) {
96  				return (T)(Integer)((Number)o).intValue();
97  			} else if (Long.class.isAssignableFrom(type)) {
98  				return (T)(Long)((Number)o).longValue();
99  			} else if (Short.class.isAssignableFrom(type)) {
100 				return (T)(Short)((Number)o).shortValue();
101 			} else if (BigDecimal.class.isAssignableFrom(type)) {
102 				return (T) new BigDecimal(o.toString());
103 			}
104 		} else if (o instanceof Number && type.isPrimitive()) {
105 			final Number num = (Number)o;
106 			if (type == byte.class) {
107 				return (T) new Byte(num.byteValue());
108 			} else if (type == double.class) {
109 				return (T) new Double(num.doubleValue());
110 			} else if (type == float.class) {
111 				return (T) new Float(num.floatValue());
112 			} else if (type == int.class) {
113 				return (T) new Integer(num.intValue());
114 			} else if (type == long.class) {
115 				return (T) new Long(num.longValue());
116 			} else if (type == short.class) {
117 				return (T) new Short(num.shortValue());
118 			} 
119 		} else if (o instanceof String && Number.class.isAssignableFrom(type)) {
120 			if (Byte.class.isAssignableFrom(type)) {
121 				return (T)new Byte((String)o);
122 			} else if (Double.class.isAssignableFrom(type)) {
123 				return (T)new Double((String)o);
124 			} else if (Float.class.isAssignableFrom(type)) {
125 				return (T)new Float((String)o);
126 			} else if (Integer.class.isAssignableFrom(type)) {
127 				return (T)new Integer((String)o);
128 			} else if (Long.class.isAssignableFrom(type)) {
129 				return (T)new Long((String)o);
130 			} else if (Short.class.isAssignableFrom(type)) {
131 				return (T)new Short((String)o);
132 			} else if (BigDecimal.class.isAssignableFrom(type)) {
133 				return (T) new BigDecimal((String)o);
134 			}
135 		}
136 		throw new NotImplementedException("Can't handle conversion from " + o.getClass().getName() + " to " + type.getName());
137 	}
138 
139 	private String formatDate(DateTime o) {
140 		return DATE_TIME_FORMAT.print(o);
141 	}
142 
143 	private String formatDate(Date o) {
144 		return DATE_TIME_FORMAT.print(new DateTime(o));
145 	}
146 
147 	private String formatDate(Calendar o) {
148 		return DATE_TIME_FORMAT.print(new DateTime(o));
149 	}
150 
151 	public static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormat.forPattern("EEE MMM dd YYYY HH:mm:ss zZ");
152 }