1
24 package net.sf.jasperreports.export;
25
26 import java.awt.Color;
27 import java.lang.reflect.InvocationHandler;
28 import java.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30 import java.lang.reflect.Proxy;
31 import java.util.ArrayList;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import net.sf.jasperreports.engine.JRPropertiesHolder;
37 import net.sf.jasperreports.engine.JRPropertiesMap;
38 import net.sf.jasperreports.engine.JRPropertiesUtil;
39 import net.sf.jasperreports.engine.JRPropertiesUtil.PropertySuffix;
40 import net.sf.jasperreports.engine.JRRuntimeException;
41 import net.sf.jasperreports.engine.JasperReportsContext;
42 import net.sf.jasperreports.engine.type.NamedEnum;
43 import net.sf.jasperreports.engine.util.ClassUtils;
44 import net.sf.jasperreports.engine.util.JRColorUtil;
45 import net.sf.jasperreports.export.annotations.ExporterProperty;
46
47
48
51 public class PropertiesNoDefaultsConfigurationFactory<C extends CommonExportConfiguration>
52 {
53
56 private final JasperReportsContext jasperReportsContext;
57
58
61 public PropertiesNoDefaultsConfigurationFactory(JasperReportsContext jasperReportsContext)
62 {
63 this.jasperReportsContext = jasperReportsContext;
64 }
65
66
67
70 public C getConfiguration(final Class<C> configurationInterface, final JRPropertiesHolder propertiesHolder)
71 {
72 return getProxy(configurationInterface, new PropertiesInvocationHandler(propertiesHolder));
73 }
74
75
76
79 private final C getProxy(Class<?> clazz, InvocationHandler handler)
80 {
81 List<Class<?>> allInterfaces = new ArrayList<Class<?>>();
82
83 if (clazz.isInterface())
84 {
85 allInterfaces.add(clazz);
86 }
87 else
88 {
89 List<Class<?>> lcInterfaces = ClassUtils.getInterfaces(clazz);
90 allInterfaces.addAll(lcInterfaces);
91 }
92
93 @SuppressWarnings("unchecked")
94 C proxy =
95 (C)Proxy.newProxyInstance(
96 ExporterConfiguration.class.getClassLoader(),
97 allInterfaces.toArray(new Class<?>[allInterfaces.size()]),
98 handler
99 );
100
101 return proxy;
102 }
103
104
105
108 class PropertiesInvocationHandler implements InvocationHandler
109 {
110 private final JRPropertiesHolder propertiesHolder;
111
112
115 public PropertiesInvocationHandler(final JRPropertiesHolder propertiesHolder)
116 {
117 this.propertiesHolder = propertiesHolder;
118 }
119
120 @Override
121 public Object invoke(
122 Object proxy,
123 Method method,
124 Object[] args
125 ) throws Throwable
126 {
127 return getPropertyValue(method, propertiesHolder);
128 }
129 }
130
131
132
135 protected Object getPropertyValue(Method method, JRPropertiesHolder propertiesHolder)
136 {
137 Object value = null;
138 ExporterProperty exporterProperty = method.getAnnotation(ExporterProperty.class);
139 if (exporterProperty != null)
140 {
141 value = getPropertyValue(jasperReportsContext, propertiesHolder, exporterProperty, method.getReturnType());
142 }
143 return value;
144 }
145
146
147
150 public static Object getPropertyValue(
151 JasperReportsContext jasperReportsContext,
152 JRPropertiesHolder propertiesHolder,
153 ExporterProperty exporterProperty,
154 Class<?> type
155 )
156 {
157 Object value = null;
158
159 String propertyName = exporterProperty.value();
160
161 if (String[].class.equals(type))
162 {
163 List<PropertySuffix> properties = JRPropertiesUtil.getProperties(propertiesHolder, propertyName);
164 if (properties != null && !properties.isEmpty())
165 {
166 String[] values = new String[properties.size()];
167 for(int i = 0; i < values.length; i++)
168 {
169 values[i] = properties.get(i).getValue();
170 }
171
172 value = values;
173 }
174 }
175 else if (PropertySuffix[].class.equals(type))
176 {
177 List<PropertySuffix> properties = JRPropertiesUtil.getProperties(propertiesHolder, propertyName);
178 if (properties != null && !properties.isEmpty())
179 {
180 value = properties.toArray(new PropertySuffix[properties.size()]);
181 }
182 }
183 else if (Map.class.equals(type))
184 {
185 List<PropertySuffix> properties = JRPropertiesUtil.getProperties(propertiesHolder, propertyName);
186 if (properties != null && !properties.isEmpty())
187 {
188 Map<String,String> values = new HashMap<String,String>();
189 for (PropertySuffix propertySuffix : properties)
190 {
191 values.put(propertySuffix.getSuffix(), propertySuffix.getValue());
192 }
193 value = values;
194 }
195 }
196 else
197 {
198 String strValue = null;
199
200 JRPropertiesMap propertiesMap = propertiesHolder.getPropertiesMap();
201 if (propertiesMap != null && propertiesMap.containsProperty(propertyName))
202 {
203 strValue = propertiesMap.getProperty(propertyName);
204 }
205
206 if (strValue != null)
207 {
208 if (String.class.equals(type))
209 {
210 value = strValue;
211 }
212 else if (Character.class.equals(type))
213 {
214 value = JRPropertiesUtil.asCharacter(strValue);
215 }
216 else if (Integer.class.equals(type))
217 {
218 value = JRPropertiesUtil.asInteger(strValue);
219 }
220 else if (Long.class.equals(type))
221 {
222 value = JRPropertiesUtil.asLong(strValue);
223 }
224 else if (Float.class.equals(type))
225 {
226 value = JRPropertiesUtil.asFloat(strValue);
227 }
228 else if (Boolean.class.equals(type))
229 {
230 value = JRPropertiesUtil.asBoolean(strValue);
231 }
232 else if (Color.class.equals(type))
233 {
234 value = strValue == null ? null : JRColorUtil.getColor(strValue, null);
235 }
236 else if (NamedEnum.class.isAssignableFrom(type))
237 {
238 try
239 {
240 Method byNameMethod = type.getMethod("getByName", new Class<?>[]{String.class});
241 value = byNameMethod.invoke(null, strValue);
242 }
243 catch (NoSuchMethodException e)
244 {
245 throw new JRRuntimeException(e);
246 }
247 catch (InvocationTargetException e)
248 {
249 throw new JRRuntimeException(e);
250 }
251 catch (IllegalAccessException e)
252 {
253 throw new JRRuntimeException(e);
254 }
255 }
256 else
257 {
258 throw
259 new JRRuntimeException(
260 PropertiesExporterConfigurationFactory.EXCEPTION_MESSAGE_KEY_EXPORT_PROPERTIES_TYPE_NOT_SUPPORTED,
261 new Object[]{type});
262 }
263 }
264 }
265
266 return value;
267 }
268 }
269