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.repo;
25
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.util.List;
30 import java.util.concurrent.atomic.AtomicReference;
31
32 import net.sf.jasperreports.engine.JRException;
33 import net.sf.jasperreports.engine.JasperReport;
34 import net.sf.jasperreports.engine.JasperReportsContext;
35 import net.sf.jasperreports.engine.ReportContext;
36
37
38 /**
39  * @author Teodor Danciu (teodord@users.sourceforge.net)
40  */

41 public final class RepositoryUtil
42 {
43     public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR = "repo.byte.data.loading.error";
44     public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_NOT_FOUND = "repo.byte.data.not.found";
45     public static final String EXCEPTION_MESSAGE_KEY_INPUT_STREAM_NOT_FOUND = "repo.input.stream.not.found";
46     public static final String EXCEPTION_MESSAGE_KEY_REPORT_NOT_FOUND = "repo.report.not.found";
47     public static final String EXCEPTION_MESSAGE_KEY_RESOURCET_NOT_FOUND = "repo.resource.not.found";
48     
49     private AtomicReference<List<RepositoryService>> repositoryServices = new AtomicReference<List<RepositoryService>>();
50     
51
52     private RepositoryContext context;
53
54
55     /**
56      *
57      */

58     private RepositoryUtil(RepositoryContext context)//FIXMECONTEXT try to reuse utils as much as you can
59     {
60         this.context = context;
61     }
62     
63     
64     /**
65      *
66      */

67     public static RepositoryUtil getInstance(JasperReportsContext jasperReportsContext)
68     {
69         return getInstance(SimpleRepositoryContext.of(jasperReportsContext));
70     }
71     
72     public static RepositoryUtil getInstance(RepositoryContext repositoryContext)
73     {
74         return new RepositoryUtil(repositoryContext);
75     }
76     
77     
78     /**
79      * 
80      */

81     private List<RepositoryService> getServices()
82     {
83         List<RepositoryService> cachedServices = repositoryServices.get();
84         if (cachedServices != null)
85         {
86             return cachedServices;
87         }
88         
89         List<RepositoryService> services = context.getJasperReportsContext().getExtensions(RepositoryService.class);
90         
91         // set if not already set
92         if (repositoryServices.compareAndSet(null, services))
93         {
94             return services;
95         }
96         
97         // already set in the meantime by another thread
98         return repositoryServices.get();
99     }
100     
101     
102     /**
103      *
104      */

105     public JasperReport getReport(ReportContext reportContext, String location) throws JRException 
106     {
107         JasperReport jasperReport = null;
108         
109         JasperDesignCache cache = JasperDesignCache.getInstance(context.getJasperReportsContext(), reportContext);
110         if (cache != null)
111         {
112             jasperReport = cache.getJasperReport(location);
113         }
114
115         if (jasperReport == null)
116         {
117             ReportResource resource = getResourceFromLocation(location, ReportResource.class);
118             if (resource == null)
119             {
120                 throw 
121                     new JRException(
122                         EXCEPTION_MESSAGE_KEY_REPORT_NOT_FOUND,
123                         new Object[]{location});
124             }
125
126             jasperReport = resource.getReport();
127
128             if (cache != null)
129             {
130                 cache.set(location, jasperReport);
131             }
132         }
133
134         return jasperReport;
135     }
136
137
138     /**
139      * 
140      */

141     public <K extends Resource> K getResourceFromLocation(String location, Class<K> resourceType) throws JRException
142     {
143         K resource = null;
144         List<RepositoryService> services = getServices();
145         if (services != null)
146         {
147             for (RepositoryService service : services)
148             {
149                 resource = service.getResource(context, location, resourceType);
150                 if (resource != null)
151                 {
152                     break;
153                 }
154             }
155         }
156         if (resource == null)
157         {
158             throw 
159             new JRException(
160                 EXCEPTION_MESSAGE_KEY_RESOURCET_NOT_FOUND,
161                 new Object[]{location});    //FIXMEREPO decide whether to return null or throw exception; check everywhere
162         }
163         return resource;
164     }
165
166
167     /**
168      *
169      */

170     public InputStream getInputStreamFromLocation(String location) throws JRException
171     {
172         InputStream is = findInputStream(location);
173         if (is == null)
174         {
175             throw 
176                 new JRException(
177                     EXCEPTION_MESSAGE_KEY_INPUT_STREAM_NOT_FOUND,
178                     new Object[]{location});
179         }
180         return is;
181     }
182
183
184     /**
185      *
186      */

187     private InputStream findInputStream(String location) throws JRException
188     {
189         InputStreamResource inputStreamResource = null;
190         List<RepositoryService> services = getServices();
191         if (services != null)
192         {
193             for (RepositoryService service : services)
194             {
195                 inputStreamResource = service.getResource(context, location, InputStreamResource.class);
196                 if (inputStreamResource != null)
197                 {
198                     break;
199                 }
200             }
201         }
202         return inputStreamResource == null ? null : inputStreamResource.getInputStream();
203     }
204     
205     
206     /**
207      *
208      */

209     public byte[] getBytesFromLocation(String location) throws JRException
210     {
211         InputStream is = findInputStream(location);
212         
213         if (is == null)
214         {
215             throw 
216                 new JRException(
217                     EXCEPTION_MESSAGE_KEY_BYTE_DATA_NOT_FOUND,
218                     new Object[]{location});
219         }
220
221         ByteArrayOutputStream baos = null;
222
223         try
224         {
225             baos = new ByteArrayOutputStream();
226
227             byte[] bytes = new byte[10000];
228             int ln = 0;
229             while ((ln = is.read(bytes)) > 0)
230             {
231                 baos.write(bytes, 0, ln);
232             }
233
234             baos.flush();
235         }
236         catch (IOException e)
237         {
238             throw 
239                 new JRException(
240                     EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR,
241                     new Object[]{location},
242                     e);
243         }
244         finally
245         {
246             if (baos != null)
247             {
248                 try
249                 {
250                     baos.close();
251                 }
252                 catch(IOException e)
253                 {
254                 }
255             }
256
257             if (is != null)
258             {
259                 try
260                 {
261                     is.close();
262                 }
263                 catch(IOException e)
264                 {
265                 }
266             }
267         }
268
269         return baos.toByteArray();
270     }
271     
272     public ResourceInfo getResourceInfo(String location)
273     {
274         ResourceInfo resourceInfo = null;
275         List<RepositoryService> services = getServices();
276         if (services != null)
277         {
278             for (RepositoryService service : services)
279             {
280                 resourceInfo = service.getResourceInfo(context, location);
281                 if (resourceInfo != null)
282                 {
283                     break;
284                 }
285             }
286         }
287         return resourceInfo;
288     }
289     
290     public RepositoryContext getRepositoryContext()
291     {
292         return context;
293     }
294 }
295