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.engine;
25
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.Enumeration;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Properties;
32 import java.util.concurrent.ConcurrentHashMap;
33
34 import net.sf.jasperreports.annotations.properties.Property;
35 import net.sf.jasperreports.annotations.properties.PropertyScope;
36 import net.sf.jasperreports.engine.design.JRCompiler;
37 import net.sf.jasperreports.engine.xml.JRReportSaxParserFactory;
38 import net.sf.jasperreports.engine.xml.PrintSaxParserFactory;
39 import net.sf.jasperreports.extensions.ExtensionsEnvironment;
40 import net.sf.jasperreports.properties.PropertyConstants;
41
42
43 /**
44  * @author Teodor Danciu (teodord@users.sourceforge.net)
45  */

46 public class DefaultJasperReportsContext implements JasperReportsContext
47 {
48     
49     /**
50      * The default properties file.
51      */

52     public static final String DEFAULT_PROPERTIES_FILE = "jasperreports.properties";
53     
54     /**
55      * The name of the system property that specifies the properties file name.
56      */

57     @Property(
58             category = PropertyConstants.CATEGORY_OTHER,
59             defaultValue = "jasperreports.properties",
60             scopes = {PropertyScope.SYSTEM},
61             sinceVersion = PropertyConstants.VERSION_1_0_0
62             )
63     public static final String PROPERTIES_FILE = JRPropertiesUtil.PROPERTY_PREFIX + "properties";
64
65     /**
66      *
67      */

68     private static final DefaultJasperReportsContext INSTANCE = new DefaultJasperReportsContext();
69     
70     public static final String EXCEPTION_MESSAGE_KEY_LOAD_DEFAULT_PROPERTIES_FAILURE = "engine.context.load.default.properties.failure";
71     public static final String EXCEPTION_MESSAGE_KEY_LOAD_PROPERTIES_FAILURE = "engine.context.load.properties.failure";
72     public static final String EXCEPTION_MESSAGE_KEY_LOAD_PROPERTIES_FILE_FAILURE = "engine.context.load.properties.file.failure";
73     public static final String EXCEPTION_MESSAGE_KEY_DEFAULT_PROPERTIES_FILE_NOT_FOUND = "engine.context.default.properties.file.not.found";
74     
75     private Map<String, Object> values = new ConcurrentHashMap<String, Object>(16, .75f, 1);// assume low update concurrency
76
77     // FIXME remove volatile after we get rid of restoreProperties()
78     protected volatile ConcurrentHashMap<String, String> properties;
79     
80     /**
81      *
82      */

83     private DefaultJasperReportsContext()
84     {
85         initProperties();
86     }
87
88     /**
89      *
90      */

91     public static DefaultJasperReportsContext getInstance()//FIXMECONTEXT check this use of this
92     {
93         return INSTANCE;
94     }
95
96     /**
97      * Loads the properties. 
98      */

99     protected void initProperties()
100     {
101         try
102         {
103             Properties defaults = getDefaultProperties();
104             String propFile = getSystemProperty(PROPERTIES_FILE);
105             Properties loadedProps;
106             if (propFile == null)
107             {
108                 loadedProps = JRPropertiesUtil.loadProperties(DEFAULT_PROPERTIES_FILE, defaults);
109                 if (loadedProps == null)
110                 {
111                     loadedProps = new Properties(defaults);
112                 }
113             }
114             else
115             {
116                 loadedProps = JRPropertiesUtil.loadProperties(propFile, defaults);
117                 if (loadedProps == null)
118                 {
119                     throw 
120                         new JRRuntimeException(
121                             EXCEPTION_MESSAGE_KEY_LOAD_PROPERTIES_FILE_FAILURE,
122                             new Object[]{propFile});
123                 }
124             }
125
126             //FIXME configurable concurrency level?
127             properties = new ConcurrentHashMap<String, String>();
128             for (Enumeration<?> names = loadedProps.propertyNames(); names.hasMoreElements();)
129             {
130                 String name = (String) names.nextElement();
131                 String value = loadedProps.getProperty(name);
132                 properties.put(name, value);
133             }
134             
135             loadSystemProperties();
136         }
137         catch (JRException e)
138         {
139             throw 
140                 new JRRuntimeException(
141                     EXCEPTION_MESSAGE_KEY_LOAD_PROPERTIES_FAILURE,
142                     (Object[])null,
143                     e);
144         }
145     }
146     
147     /**
148      * 
149      */

150     @SuppressWarnings("deprecation")
151     protected void loadSystemProperties()
152     {
153         loadSystemProperty("jasper.reports.compiler.class", JRCompiler.COMPILER_CLASS);
154         loadSystemProperty("jasper.reports.compile.xml.validation", JRReportSaxParserFactory.COMPILER_XML_VALIDATION);
155         loadSystemProperty("jasper.reports.export.xml.validation", PrintSaxParserFactory.EXPORT_XML_VALIDATION);
156         loadSystemProperty("jasper.reports.compile.keep.java.file", JRCompiler.COMPILER_KEEP_JAVA_FILE);
157         loadSystemProperty("jasper.reports.compile.temp", JRCompiler.COMPILER_TEMP_DIR);
158         loadSystemProperty("jasper.reports.compile.class.path", JRCompiler.COMPILER_CLASSPATH);    
159     }
160
161     /**
162      * Sets the default properties.
163      * 
164      * @return the default properties
165      */

166     protected static Properties getDefaultProperties() throws JRException
167     {
168         Properties defaults = new Properties();
169         
170         InputStream is = JRPropertiesUtil.class.getResourceAsStream("/default.jasperreports.properties");
171         
172         if (is == null)
173         {
174             throw 
175                 new JRException(
176                     EXCEPTION_MESSAGE_KEY_DEFAULT_PROPERTIES_FILE_NOT_FOUND,
177                     (Object[])null);
178         }
179
180         try
181         {
182             defaults.load(is);
183         }
184         catch (IOException e)
185         {
186             throw 
187                 new JRException(
188                     EXCEPTION_MESSAGE_KEY_LOAD_DEFAULT_PROPERTIES_FAILURE, 
189                     null
190                     e);
191         }
192         finally
193         {
194             try
195             {
196                 is.close();
197             }
198             catch (IOException e)
199             {
200             }
201         }
202         
203         String userDir = getSystemProperty("user.dir");
204         if (userDir != null)
205         {
206             defaults.setProperty(JRCompiler.COMPILER_TEMP_DIR, userDir);
207         }
208         
209         String classPath = getSystemProperty("java.class.path");
210         if (classPath != null)
211         {
212             defaults.setProperty(JRCompiler.COMPILER_CLASSPATH, classPath);
213         }
214
215         return defaults;
216     }
217
218     /**
219      * 
220      */

221     protected static String getSystemProperty(String propertyName)
222     {
223         try
224         {
225             return System.getProperty(propertyName);
226         }
227         catch (SecurityException e)
228         {
229             // This could fail if we are in the applet viewer or some other 
230             // restrictive environment, but it should be safe to simply return null.
231             // We cannot log this properly using a logging API, 
232             // as we want to keep applet JAR dependencies to a minimum.
233             return null;
234         }
235     }
236
237     /**
238      * 
239      */

240     protected void loadSystemProperty(String sysKey, String propKey)
241     {
242         String val = getSystemProperty(sysKey);
243         if (val != null)
244         {
245             properties.put(propKey, val);
246         }
247     }
248
249     @Override
250     public Object getValue(String key)
251     {
252         return values.get(key);
253     }
254
255     @Override
256     public Object getOwnValue(String key)
257     {
258         return values.get(key);
259     }
260
261     @Override
262     public void setValue(String key, Object value)
263     {
264         values.put(key, value);
265     }
266     
267     /**
268      * Returns a list of extension objects for a specific extension type.
269      * 
270      * @param extensionType the extension type
271      * @param <T> generic extension type
272      * @return a list of extension objects
273      */

274     @Override
275     public <T> List<T> getExtensions(Class<T> extensionType)
276     {
277         return ExtensionsEnvironment.getExtensionsRegistry().getExtensions(extensionType);
278     }
279     
280     /**
281      * Returns the value of the property.
282      * 
283      * @param key the key
284      * @return the property value
285      */

286     @Override
287     public String getProperty(String key)
288     {
289         return properties.get(key);
290     }
291     
292     @Override
293     public String getOwnProperty(String key)
294     {
295         return properties.get(key);
296     }
297     
298     @Override
299     public void setProperty(String key, String value)
300     {
301         properties.put(key, value);
302     }
303     
304     @Override
305     public void removeProperty(String key)
306     {
307         properties.remove(key);
308     }
309     
310     @Override
311     public Map<String, String> getProperties()
312     {
313         return properties;
314     }
315 }
316