View Javadoc
1   /*
2    * Copyright (c) 2002-2020, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.jasper.service.export;
35  
36  import java.io.File;
37  import java.sql.Connection;
38  import java.sql.SQLException;
39  import java.text.MessageFormat;
40  import java.util.HashMap;
41  import java.util.List;
42  import java.util.Map;
43  
44  import javax.servlet.http.HttpServletRequest;
45  import javax.servlet.http.HttpSession;
46  
47  import fr.paris.lutece.plugins.jasper.business.JasperReportHome;
48  import fr.paris.lutece.plugins.jasper.service.CompiledJasperTemplateCacheService;
49  import fr.paris.lutece.plugins.jasper.service.ILinkJasperReport;
50  import fr.paris.lutece.plugins.jasper.service.JasperConnectionService;
51  import fr.paris.lutece.plugins.jasper.service.JasperFileLinkService;
52  import fr.paris.lutece.portal.service.plugin.Plugin;
53  import fr.paris.lutece.portal.service.plugin.PluginService;
54  import fr.paris.lutece.portal.service.util.AppLogService;
55  import fr.paris.lutece.portal.service.util.AppPathService;
56  import fr.paris.lutece.portal.service.util.AppPropertiesService;
57  import net.sf.jasperreports.engine.JRDataSource;
58  import net.sf.jasperreports.engine.JRException;
59  import net.sf.jasperreports.engine.JasperFillManager;
60  import net.sf.jasperreports.engine.JasperPrint;
61  import net.sf.jasperreports.engine.JasperReport;
62  import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
63  import net.sf.jasperreports.engine.util.JRLoader;
64  
65  /**
66   * Abstract class used to generate a Jasper report
67   *
68   */
69  public abstract class AbstractDefaultJasperRender implements ILinkJasperReport, Cloneable
70  {
71      protected static final String PLUGIN_NAME = "jasper";
72      protected static final String PROPERTY_FILES_PATH = "jasper.files.path";
73      protected static final String PROPERTY_IMAGES_FILES_PATH = "jasper.images.path";
74      protected static final String PROPERTY_EXPORT_CHARACTER_ENCODING = "jasper.export.characterEncoding";
75      protected static final String PARAMETER_JASPER_VALUE = "value";
76      protected static final String PARAMETER_JASPER_IMAGE_DIRECTORY = "imageDirectory";
77      protected static final String PARAMETER_JASPER_SUB_REPORT_DIRECTORY = "SUBREPORT_DIR";
78  
79      protected static final String REGEX_ID = "^[\\d]+$";
80      protected static final String PATH_SEPARATOR = "/";
81      private static final String SESSION_DATA_SOURCE = "dataSource";
82      private static final String URL_PATTERN = "jsp/site/plugins/jasper/DownloadFile.jsp?report_type={0}&report_id={1}";
83      private static final String FILE_EXTENSION_DELIMITER = ".";
84      private static final String JRXML_EXTENSION = ".jrxml";
85  
86      /**
87       * {@inheritDoc }
88       */
89      @Override
90      public String getLink( String strReportId )
91      {
92          return MessageFormat.format( URL_PATTERN, getFileType( ), strReportId );
93      }
94  
95      /**
96       * {@inheritDoc }
97       */
98      @Override
99      public String getFileName( String strReportCode )
100     {
101         return strReportCode + FILE_EXTENSION_DELIMITER + getFileType( );
102     }
103 
104     /**
105      * {@inheritDoc }
106      */
107     @Override
108     public byte [ ] getBuffer( String strCode, HttpServletRequest request )
109     {
110         Plugin plugin = PluginService.getPlugin( PLUGIN_NAME );
111         JRDataSource dataSource = null;
112         fr.paris.lutece.plugins.jasper.business.JasperReport report = null;
113         HttpSession session = request.getSession( false );
114 
115         if ( session != null )
116         {
117             dataSource = (JRDataSource) session.getAttribute( SESSION_DATA_SOURCE );
118         }
119         report = JasperReportHome.findByCode( strCode, plugin );
120         List<String> listValues = JasperFileLinkService.INSTANCE.getValues( request );
121         Map<String, Object> parameters = new HashMap<String, Object>( );
122 
123         for ( int i = 0; i < listValues.size( ); i++ )
124         {
125             parameters.put( PARAMETER_JASPER_VALUE + ( i + 1 ),
126                     listValues.get( i ).matches( REGEX_ID ) ? Integer.parseInt( listValues.get( i ) ) : listValues.get( i ) );
127         }
128 
129         return getBuffer( report, dataSource, parameters, request );
130     }
131 
132     /**
133      * {@inheritDoc }
134      */
135     @Override
136     public byte [ ] getBuffer( String strCode, JRBeanCollectionDataSource dataSource, Map<String, Object> parameters, HttpServletRequest request )
137     {
138         // We override the methods instead of replacing them to ensure binary compatibility
139         return getBuffer( strCode, (JRDataSource) dataSource, parameters, request );
140     }
141 
142     /**
143      * {@inheritDoc }
144      */
145     @Override
146     public byte [ ] getBuffer( String strCode, JRDataSource dataSource, Map<String, Object> parameters, HttpServletRequest request )
147     {
148         Plugin plugin = PluginService.getPlugin( PLUGIN_NAME );
149         fr.paris.lutece.plugins.jasper.business.JasperReport report = JasperReportHome.findByCode( strCode, plugin );
150         return getBuffer( report, dataSource, parameters, request );
151     }
152 
153     /**
154      * {@inheritDoc }
155      */
156     @Override
157     public byte [ ] getBuffer( fr.paris.lutece.plugins.jasper.business.JasperReport report, JRBeanCollectionDataSource dataSource,
158             Map<String, Object> parameters, HttpServletRequest request )
159     {
160         // We override the methods instead of replacing them to ensure binary compatibility
161         return getBuffer( report, (JRDataSource) dataSource, parameters, request );
162     }
163 
164     /**
165      * {@inheritDoc }
166      */
167     @Override
168     public byte [ ] getBuffer( fr.paris.lutece.plugins.jasper.business.JasperReport report, JRDataSource dataSource, Map<String, Object> parameters,
169             HttpServletRequest request )
170     {
171         byte [ ] byteArray = new byte [ 1024];
172         Connection connection = null;
173         try
174         {
175 
176             String strPageDesc = report.getUrl( );
177             String strDirectoryPath = AppPropertiesService.getProperty( PROPERTY_FILES_PATH );
178             String strAbsolutePath = AppPathService.getWebAppPath( ) + strDirectoryPath + strPageDesc;
179 
180             String strSubReportPath = AppPathService.getWebAppPath( ) + strDirectoryPath + report.getCode( ) + "/";
181 
182             File reportFile = new File( strAbsolutePath );
183 
184             JasperReport jasperReport = null;
185 
186             if ( strAbsolutePath.endsWith( JRXML_EXTENSION ) )
187             {
188                 jasperReport = CompiledJasperTemplateCacheService.getInstance( ).getCompiledJasperTemplate( report.getCode( ), reportFile );
189             } else
190             {
191                 jasperReport = ( JasperReport ) JRLoader.loadObject( reportFile );
192             }
193 
194             String strImageDirectoryPath = AppPropertiesService.getProperty( PROPERTY_IMAGES_FILES_PATH );
195             String strImageDirectoryAbsolutePath = new StringBuffer( AppPathService.getWebAppPath( ) ).append( strImageDirectoryPath )
196                     .append( report.getCode( ) ).append( PATH_SEPARATOR ).toString( );
197             parameters.put( PARAMETER_JASPER_IMAGE_DIRECTORY, strImageDirectoryAbsolutePath );
198             parameters.put( PARAMETER_JASPER_SUB_REPORT_DIRECTORY, strSubReportPath );
199 
200             JasperPrint jasperPrint = null;
201             if ( dataSource == null )
202             {
203                 connection = JasperConnectionService.getConnectionService( report.getPool( ) ).getConnection( );
204                 jasperPrint = JasperFillManager.fillReport( jasperReport, parameters, connection );
205             }
206             else
207             {
208                 jasperPrint = JasperFillManager.fillReport( jasperReport, parameters, dataSource );
209             }
210 
211             byteArray = getData( request, report, jasperPrint );
212 
213         }
214         catch( Exception e )
215         {
216             AppLogService.error( e.getMessage( ), e );
217         }
218         finally
219         {
220             if ( connection != null )
221             {
222                 if ( report != null )
223                 {
224                     try
225                     {
226                         JasperConnectionService.getConnectionService( report.getPool( ) ).freeConnection( connection );
227                     }
228                     catch( Exception e )
229                     {
230                         AppLogService.error( e.getMessage( ), e );
231                         try
232                         {
233                             connection.close( );
234                         }
235                         catch( SQLException s )
236                         {
237                             AppLogService.error( s.getMessage( ), s );
238                         }
239                     }
240                 }
241                 try
242                 {
243                     connection.close( );
244                 }
245                 catch( SQLException s )
246                 {
247                     AppLogService.error( s.getMessage( ), s );
248                 }
249             }
250         }
251 
252         return byteArray;
253     }
254 
255     /**
256      * Gives data generated by Jasper
257      * 
258      * @param request
259      *            the request
260      * @param report
261      *            the Jasper report
262      * @param jasperPrint
263      *            the JasperPrint
264      * @return the data as array of bytes
265      * @throws JRException
266      *             if there is an exception during the treatment
267      */
268     protected abstract byte [ ] getData( HttpServletRequest request, fr.paris.lutece.plugins.jasper.business.JasperReport report, JasperPrint jasperPrint )
269             throws JRException;
270 }