1 /*
2  * JasperReports - Free Java Reporting Library.
3  * Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
4  * http://www.jaspersoft.com
5  *
6  * Unless you have purchased a commercial license agreement from Jaspersoft,
7  * the following license terms apply:
8  *
9  * This program is part of JasperReports.
10  *
11  * JasperReports is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * JasperReports is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
23  */

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.JRPropertiesUtil;
37 import net.sf.jasperreports.engine.JRPropertiesUtil.PropertySuffix;
38 import net.sf.jasperreports.engine.JRRuntimeException;
39 import net.sf.jasperreports.engine.JasperReportsContext;
40 import net.sf.jasperreports.engine.type.NamedEnum;
41 import net.sf.jasperreports.engine.util.ClassUtils;
42 import net.sf.jasperreports.engine.util.JRColorUtil;
43 import net.sf.jasperreports.export.annotations.ExporterProperty;
44
45
46 /**
47  * @author Teodor Danciu (teodord@users.sourceforge.net)
48  */

49 public class PropertiesDefaultsConfigurationFactory<C extends CommonExportConfiguration>
50 {
51     /**
52      * 
53      */

54     private final JasperReportsContext jasperReportsContext;
55     
56     /**
57      * 
58      */

59     public PropertiesDefaultsConfigurationFactory(JasperReportsContext jasperReportsContext)
60     {
61         this.jasperReportsContext = jasperReportsContext;
62     }
63
64     
65     /**
66      * 
67      */

68     public C getConfiguration(final Class<C> configurationInterface)
69     {
70         return getProxy(configurationInterface, new PropertiesDefaultsInvocationHandler());
71     }
72
73
74     /**
75      * 
76      */

77     private final C getProxy(Class<?> clazz, InvocationHandler handler)
78     {
79         List<Class<?>> allInterfaces = new ArrayList<Class<?>>();
80
81         if (clazz.isInterface())
82         {
83             allInterfaces.add(clazz);
84         }
85         else
86         {
87             List<Class<?>> lcInterfaces = ClassUtils.getInterfaces(clazz);
88             allInterfaces.addAll(lcInterfaces);
89         }
90
91         @SuppressWarnings("unchecked")
92         C proxy =
93             (C)Proxy.newProxyInstance(
94                 ExporterConfiguration.class.getClassLoader(),
95                 allInterfaces.toArray(new Class<?>[allInterfaces.size()]),
96                 handler
97                 );
98         
99         return proxy;
100     }
101
102
103     /**
104      * 
105      */

106     class PropertiesDefaultsInvocationHandler implements InvocationHandler
107     {
108         /**
109          * 
110          */

111         public PropertiesDefaultsInvocationHandler()
112         {
113         }
114         
115         @Override
116         public Object invoke(
117             Object proxy, 
118             Method method, 
119             Object[] args
120             ) throws Throwable 
121         {
122             return getPropertyValue(method);
123         }
124     }
125     
126     
127     /**
128      * 
129      */

130     protected Object getPropertyValue(Method method)
131     {
132         Object value = null;
133         ExporterProperty exporterProperty = method.getAnnotation(ExporterProperty.class);
134         if (exporterProperty != null)
135         {
136             value = getPropertyValue(jasperReportsContext, exporterProperty, method.getReturnType());
137         }
138         return value;
139     }
140     
141     
142     /**
143      * 
144      */

145     public static Object getPropertyValue(
146         JasperReportsContext jasperReportsContext,
147         ExporterProperty exporterProperty, 
148         Class<?> type 
149         )
150     {
151         Object value = null;
152         
153         String propertyName = exporterProperty.value();
154         
155         JRPropertiesUtil propertiesUtil = JRPropertiesUtil.getInstance(jasperReportsContext);
156
157         if (String[].class.equals(type))
158         {
159             List<PropertySuffix> properties = propertiesUtil.getProperties(propertyName);
160             if (properties != null && !properties.isEmpty())
161             {
162                 String[] values = new String[properties.size()];
163                 for(int i = 0; i < values.length; i++)
164                 {
165                     values[i] = properties.get(i).getValue();
166                 }
167                 
168                 value = values;
169             }
170         }
171         else if (PropertySuffix[].class.equals(type))
172         {
173             List<PropertySuffix> properties = propertiesUtil.getProperties(propertyName);
174             if (properties != null && !properties.isEmpty())
175             {
176                 value = properties.toArray(new PropertySuffix[properties.size()]);
177             }
178         }
179         else if (Map.class.equals(type))
180         {
181             List<PropertySuffix> properties = propertiesUtil.getProperties(propertyName);
182             if (properties != null && !properties.isEmpty())
183             {
184                 Map<String,String> values = new HashMap<String,String>();
185                 for (PropertySuffix propertySuffix : properties)
186                 {
187                     values.put(propertySuffix.getSuffix(), propertySuffix.getValue());
188                 }
189                 value = values;
190             }
191         }
192         else
193         {
194             String strValue = propertiesUtil.getProperty(propertyName);
195             
196             if (String.class.equals(type))
197             {
198                 value = strValue;
199             }
200             else if (Character.class.equals(type))
201             {
202                 value = JRPropertiesUtil.asCharacter(strValue);
203             }
204             else if (Integer.class.equals(type))
205             {
206                 if (strValue == null)
207                 {
208                     if (!exporterProperty.nullDefault())
209                     {
210                         value = exporterProperty.intDefault();
211                     }
212                 }
213                 else
214                 {
215                     value = JRPropertiesUtil.asInteger(strValue);
216                 }
217             }
218             else if (Long.class.equals(type))
219             {
220                 if (strValue == null)
221                 {
222                     if (!exporterProperty.nullDefault())
223                     {
224                         value = exporterProperty.longDefault();
225                     }
226                 }
227                 else
228                 {
229                     value = JRPropertiesUtil.asLong(strValue);
230                 }
231             }
232             else if (Float.class.equals(type))
233             {
234                 if (strValue == null)
235                 {
236                     if (!exporterProperty.nullDefault())
237                     {
238                         value = exporterProperty.floatDefault();
239                     }
240                 }
241                 else
242                 {
243                     value = JRPropertiesUtil.asFloat(strValue);
244                 }
245             }
246             else if (Boolean.class.equals(type))
247             {
248                 if (strValue == null)
249                 {
250                     if (!exporterProperty.nullDefault())
251                     {
252                         value = exporterProperty.booleanDefault();
253                     }
254                 }
255                 else
256                 {
257                     value = JRPropertiesUtil.asBoolean(strValue);
258                 }
259             }
260             else if (Color.class.equals(type))
261             {
262                 if (strValue == null)
263                 {
264                     if (!exporterProperty.nullDefault())
265                     {
266                         strValue = exporterProperty.stringDefault();
267                         if (strValue.trim().length() == 0)
268                         {
269                             throw new JRRuntimeException(
270                                 PropertiesExporterConfigurationFactory.EXCEPTION_MESSAGE_KEY_EXPORT_PROPERTIES_EMPTY_STRING_DEFAULT_NOT_SUPPORTED,
271                                 new Object[]{propertyName}
272                                 );
273                         }
274                     }
275                 }
276
277                 if (strValue != null)
278                 {
279                     value = JRColorUtil.getColor(strValue, null);
280                 }
281             }
282             else if (NamedEnum.class.isAssignableFrom(type))
283             {
284                 if (strValue == null)
285                 {
286                     if (!exporterProperty.nullDefault())
287                     {
288                         strValue = exporterProperty.stringDefault();
289                     }
290                 }
291
292                 if (strValue != null)
293                 {
294                     try
295                     {
296                         Method byNameMethod = type.getMethod("getByName"new Class<?>[]{String.class});
297                         value = byNameMethod.invoke(null, strValue);
298                     }
299                     catch (NoSuchMethodException e)
300                     {
301                         throw new JRRuntimeException(e);
302                     }
303                     catch (InvocationTargetException e)
304                     {
305                         throw new JRRuntimeException(e);
306                     }
307                     catch (IllegalAccessException e)
308                     {
309                         throw new JRRuntimeException(e);
310                     }
311                 }
312             }
313             else
314             {
315                 throw 
316                     new JRRuntimeException(
317                         PropertiesExporterConfigurationFactory.EXCEPTION_MESSAGE_KEY_EXPORT_PROPERTIES_TYPE_NOT_SUPPORTED, 
318                         new Object[]{type});
319             }
320         }
321         
322         return value;
323     }
324     
325 }
326