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.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 /**
49  * @author Teodor Danciu (teodord@users.sourceforge.net)
50  */

51 public class PropertiesNoDefaultsConfigurationFactory<C extends CommonExportConfiguration>
52 {
53     /**
54      * 
55      */

56     private final JasperReportsContext jasperReportsContext;
57     
58     /**
59      * 
60      */

61     public PropertiesNoDefaultsConfigurationFactory(JasperReportsContext jasperReportsContext)
62     {
63         this.jasperReportsContext = jasperReportsContext;
64     }
65
66     
67     /**
68      * 
69      */

70     public C getConfiguration(final Class<C> configurationInterface, final JRPropertiesHolder propertiesHolder)
71     {
72         return getProxy(configurationInterface, new PropertiesInvocationHandler(propertiesHolder));
73     }
74
75
76     /**
77      * 
78      */

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     /**
106      * 
107      */

108     class PropertiesInvocationHandler implements InvocationHandler
109     {
110         private final JRPropertiesHolder propertiesHolder;
111         
112         /**
113          * 
114          */

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     /**
133      * 
134      */

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     /**
148      * 
149      */

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