View Javadoc
1   /*
2    * Copyright (c) 2002-2021, 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.importexport.web;
35  
36  import fr.paris.lutece.plugins.importexport.business.importdata.ImportResult;
37  import fr.paris.lutece.plugins.importexport.service.ImportExportPlugin;
38  import fr.paris.lutece.plugins.importexport.service.importdata.IImportSource;
39  import fr.paris.lutece.plugins.importexport.service.importdata.ImportManager;
40  import fr.paris.lutece.portal.business.user.AdminUser;
41  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
42  import fr.paris.lutece.portal.service.admin.AdminUserService;
43  import fr.paris.lutece.portal.service.message.AdminMessage;
44  import fr.paris.lutece.portal.service.message.AdminMessageService;
45  import fr.paris.lutece.portal.service.plugin.Plugin;
46  import fr.paris.lutece.portal.service.plugin.PluginService;
47  import fr.paris.lutece.portal.service.template.AppTemplateService;
48  import fr.paris.lutece.portal.service.util.AppPathService;
49  import fr.paris.lutece.portal.service.util.AppPropertiesService;
50  import fr.paris.lutece.portal.web.admin.AdminFeaturesPageJspBean;
51  import fr.paris.lutece.portal.web.upload.MultipartHttpServletRequest;
52  import fr.paris.lutece.util.ReferenceItem;
53  import fr.paris.lutece.util.ReferenceList;
54  import fr.paris.lutece.util.html.HtmlTemplate;
55  
56  import java.util.Collection;
57  import java.util.HashMap;
58  import java.util.Locale;
59  import java.util.Map;
60  
61  import javax.servlet.http.HttpServletRequest;
62  
63  import org.apache.commons.fileupload.FileItem;
64  import org.apache.commons.lang3.StringUtils;
65  
66  /**
67   * This class provides the user interface to import data into the database
68   */
69  public class ImportDataJspBean extends AdminFeaturesPageJspBean
70  {
71      public static final String RIGHT_IMPORT_DATA = "IMPORTEXPORT_MANAGEMENT";
72  
73      /**
74       * Generated serial version UID
75       */
76      private static final long serialVersionUID = 8260626003003487223L;
77  
78      // Properties
79      private static final String PROPERTY_DATABASE_TABLES = "importexport.database.importableTableNames";
80      private static final String PROPERTY_MESSAGE_IMPORT_DATA_PAGE_TITLE = "importexport.import_data.pageTitle";
81      private static final String PROPERTY_ASYNCHRONOUS_IMPORT_FILE_SIZE = "importexport.importdata.asynchronousImportFileSize";
82  
83      // Messages
84      private static final String MESSAGE_FILE_NOT_VALIDE = "importexport.import_data.labelErrorFileFormatNotSupported";
85      private static final String MESSAGE_MANDATORY_FIELDS = "portal.util.message.mandatoryFields";
86  
87      // Marks
88      private static final String MARK_DATABASE_TABLES = "databaseTables";
89      private static final String MARK_LIST_PLUGIN = "listPlugin";
90      private static final String MARK_SESSION_IMPORT_RESULT = "importexport.session_import_result";
91      private static final String MARK_RESULT = "result";
92  
93      // Parameters
94      private static final String PARAMETER_FILE = "file";
95      private static final String PARAMETER_TABLE_NAME = "databaseTable";
96      private static final String PARAMETER_PLUGIN_NAME = "plugin";
97      private static final String PARAMETER_UPDATE_EXISTING_ROWS = "update";
98      private static final String PARAMETER_STOP_ON_ERRORS = "stopOnErrors";
99      private static final String PARAMETER_EMPTY_TABLE = "emptyTable";
100 
101     // Templates
102     private static final String TEMPLATE_IMPORT_DATA = "admin/plugins/importexport/import_data.html";
103     private static final String TEMPLATE_IMPORT_WAITING = "admin/plugins/importexport/import_waiting.html";
104     private static final String TEMPLATE_IMPORT_RESULT = "admin/plugins/importexport/import_result.html";
105 
106     private static final String JSP_URL_MANAGE_IMPORT = "jsp/admin/plugins/importexport/ManageImportData.jsp";
107     private static final String JSP_URL_IMPORT_PROCESSING = "jsp/admin/plugins/importexport/GetImportProcessing.jsp";
108     private static final String JSP_URL_IMPORT_RESULT = "jsp/admin/plugins/importexport/GetImportResult.jsp";
109 
110     private static final String CONSTANT_SEMICOLON = ";";
111 
112     /**
113      * Creates a new ImportDataJspBean object.
114      */
115     public ImportDataJspBean( )
116     {
117     }
118 
119     /**
120      * Get the import data page
121      * 
122      * @param request
123      *            The request
124      * @return The HTML content to display
125      */
126     public String getImportData( HttpServletRequest request )
127     {
128         // We remove any previous import result generated synchronously or asynchronously
129         request.getSession( ).removeAttribute( MARK_SESSION_IMPORT_RESULT );
130         // We remove the data table manager from the session
131         request.getSession( ).removeAttribute( ExportDataJspBean.PROPERTY_SESSION_AUTOMATIC_EXPORT_TABLE_MANAGER );
132         ImportManager.getAsynchronousImportResult( AdminUserService.getAdminUser( request ).getUserId( ) );
133 
134         String strDatabaseTables = AppPropertiesService.getProperty( PROPERTY_DATABASE_TABLES );
135         ReferenceList refList = new ReferenceList( );
136         if ( StringUtils.isNotBlank( strDatabaseTables ) )
137         {
138             for ( String strDatabaseTable : strDatabaseTables.split( CONSTANT_SEMICOLON ) )
139             {
140                 ReferenceItem refItem = new ReferenceItem( );
141                 refItem.setCode( strDatabaseTable );
142                 refItem.setName( strDatabaseTable );
143                 refList.add( refItem );
144             }
145         }
146         Map<String, Object> model = new HashMap<String, Object>( );
147 
148         model.put( MARK_DATABASE_TABLES, refList );
149         Collection<Plugin> listPlugins = PluginService.getPluginList( );
150         ReferenceList refListPlugins = new ReferenceList( );
151         ReferenceItem refItemPlugin = new ReferenceItem( );
152         Plugin core = PluginService.getCore( );
153         refItemPlugin.setName( core.getName( ) );
154         refItemPlugin.setCode( core.getName( ) );
155         refListPlugins.add( refItemPlugin );
156         for ( Plugin plugin : listPlugins )
157         {
158             if ( plugin.isDbPoolRequired( ) )
159             {
160                 refItemPlugin = new ReferenceItem( );
161                 refItemPlugin.setName( plugin.getName( ) );
162                 refItemPlugin.setCode( plugin.getName( ) );
163                 refListPlugins.add( refItemPlugin );
164             }
165         }
166         model.put( MARK_LIST_PLUGIN, refListPlugins );
167 
168         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_IMPORT_DATA, AdminUserService.getLocale( request ), model );
169 
170         setPageTitleProperty( PROPERTY_MESSAGE_IMPORT_DATA_PAGE_TITLE );
171 
172         return getAdminPage( template.getHtml( ) );
173     }
174 
175     /**
176      * Do import data into the database
177      * 
178      * @param request
179      *            The request
180      * @return The next URL to redirect to
181      * @throws AccessDeniedException
182      *             If the table to import data in has not been declared as an importable table
183      */
184     public String doImportData( HttpServletRequest request ) throws AccessDeniedException
185     {
186         AdminUser admin = AdminUserService.getAdminUser( request );
187         if ( ImportManager.hasImportInProcess( admin.getUserId( ) ) )
188         {
189             return AppPathService.getBaseUrl( request ) + JSP_URL_IMPORT_PROCESSING;
190         }
191 
192         if ( request instanceof MultipartHttpServletRequest )
193         {
194             FileItem fileItem = ( (MultipartHttpServletRequest) request ).getFile( PARAMETER_FILE );
195             String strTableName = request.getParameter( PARAMETER_TABLE_NAME );
196             String strPluginName = request.getParameter( PARAMETER_PLUGIN_NAME );
197             Plugin plugin = PluginService.getPlugin( strPluginName );
198             boolean bUpdateExistingRows = Boolean.parseBoolean( request.getParameter( PARAMETER_UPDATE_EXISTING_ROWS ) );
199             boolean bStopOnErrors = Boolean.parseBoolean( request.getParameter( PARAMETER_STOP_ON_ERRORS ) );
200             boolean bEmptyTable = Boolean.parseBoolean( request.getParameter( PARAMETER_EMPTY_TABLE ) );
201             if ( fileItem == null || StringUtils.isEmpty( strTableName ) )
202             {
203                 return AdminMessageService.getMessageUrl( request, MESSAGE_MANDATORY_FIELDS, AdminMessage.TYPE_ERROR );
204             }
205             boolean bAuthorizedTable = false;
206             String strDatabaseTables = AppPropertiesService.getProperty( PROPERTY_DATABASE_TABLES );
207             for ( String strDatabaseTable : strDatabaseTables.split( CONSTANT_SEMICOLON ) )
208             {
209                 if ( StringUtils.equals( strDatabaseTable, strTableName ) )
210                 {
211                     bAuthorizedTable = true;
212                     break;
213                 }
214             }
215 
216             if ( !bAuthorizedTable )
217             {
218                 throw new AccessDeniedException( "The database table '" + strTableName + "' has NOT been decalred as an importable table" );
219             }
220 
221             IImportSource importSource = ImportManager.getImportSource( fileItem );
222             if ( importSource != null )
223             {
224                 long lThresholdSize = AppPropertiesService.getPropertyLong( PROPERTY_ASYNCHRONOUS_IMPORT_FILE_SIZE, 1048576l );
225                 Locale locale = AdminUserService.getLocale( request );
226                 if ( fileItem.getSize( ) < lThresholdSize )
227                 {
228                     ImportResult result = ImportManager.doProcessImport( importSource, strTableName, bUpdateExistingRows, bStopOnErrors, bEmptyTable, plugin,
229                             locale );
230                     request.getSession( ).setAttribute( MARK_SESSION_IMPORT_RESULT, result );
231                     return AppPathService.getBaseUrl( request ) + JSP_URL_IMPORT_RESULT;
232                 }
233                 ImportManager.doProcessAsynchronousImport( importSource, strTableName, plugin, locale, bUpdateExistingRows, bStopOnErrors, bEmptyTable, admin );
234                 return AppPathService.getBaseUrl( request ) + JSP_URL_IMPORT_PROCESSING;
235 
236             }
237             return AdminMessageService.getMessageUrl( request, MESSAGE_FILE_NOT_VALIDE, AdminMessage.TYPE_ERROR );
238         }
239         return AppPathService.getBaseUrl( request ) + JSP_URL_MANAGE_IMPORT;
240     }
241 
242     /**
243      * Get the waiting page if an import has been started by the user and has not terminated yet. If there is no running import, then the import result page is
244      * displayed
245      * 
246      * @param request
247      *            The request
248      * @return The HTML content to display
249      */
250     public String getImportProcessing( HttpServletRequest request )
251     {
252         AdminUser admin = AdminUserService.getAdminUser( request );
253         if ( ImportManager.hasImportInProcess( admin.getUserId( ) ) )
254         {
255             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_IMPORT_WAITING, AdminUserService.getLocale( request ) );
256             return getAdminPage( template.getHtml( ) );
257         }
258         return getImportResult( request );
259     }
260 
261     /**
262      * Get the import result page. If the user has already displayed results of imports, or if he has not started any import then page to create import is
263      * displayed instead
264      * 
265      * @param request
266      *            The request
267      * @return The HTML content to display
268      */
269     public String getImportResult( HttpServletRequest request )
270     {
271         AdminUser admin = AdminUserService.getAdminUser( request );
272         ImportResult../../../../fr/paris/lutece/plugins/importexport/business/importdata/ImportResult.html#ImportResult">ImportResult result = (ImportResult) request.getSession( ).getAttribute( MARK_SESSION_IMPORT_RESULT );
273         if ( result == null )
274         {
275             result = ImportManager.getAsynchronousImportResult( admin.getUserId( ) );
276             if ( result == null )
277             {
278                 return getImportData( request );
279             }
280         }
281         else
282         {
283             request.getSession( ).removeAttribute( MARK_SESSION_IMPORT_RESULT );
284         }
285 
286         Map<String, Object> model = new HashMap<String, Object>( );
287         model.put( MARK_RESULT, result );
288         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_IMPORT_RESULT, AdminUserService.getLocale( request ), model );
289 
290         return getAdminPage( template.getHtml( ) );
291     }
292 
293     /**
294      * Return the plugin
295      * 
296      * @return Plugin
297      */
298     public Plugin getPlugin( )
299     {
300         return PluginService.getPlugin( ImportExportPlugin.PLUGIN_NAME );
301     }
302 }