View Javadoc
1   /*
2    * Copyright (c) 2002-2015, Mairie de 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.sqlpage.web;
35  
36  import fr.paris.lutece.plugins.sqlpage.business.SQLFragment;
37  import fr.paris.lutece.plugins.sqlpage.business.SQLFragmentHome;
38  import fr.paris.lutece.plugins.sqlpage.business.SQLPage;
39  import fr.paris.lutece.plugins.sqlpage.business.SQLPageHome;
40  import fr.paris.lutece.plugins.sqlpage.business.query.SQLQueryException;
41  import fr.paris.lutece.plugins.sqlpage.service.SQLPageService;
42  import fr.paris.lutece.plugins.sqlpage.service.SQLService;
43  import fr.paris.lutece.portal.business.role.RoleHome;
44  import fr.paris.lutece.portal.service.database.AppConnectionService;
45  import fr.paris.lutece.portal.service.i18n.I18nService;
46  import fr.paris.lutece.portal.service.message.AdminMessage;
47  import fr.paris.lutece.portal.service.message.AdminMessageService;
48  import fr.paris.lutece.portal.util.mvc.admin.annotations.Controller;
49  import fr.paris.lutece.portal.util.mvc.commons.annotations.Action;
50  import fr.paris.lutece.portal.util.mvc.commons.annotations.View;
51  import fr.paris.lutece.util.ReferenceList;
52  import fr.paris.lutece.util.url.UrlItem;
53  
54  import freemarker.template.TemplateException;
55  
56  import java.io.IOException;
57  
58  import java.util.HashMap;
59  import java.util.List;
60  import java.util.Locale;
61  import java.util.Map;
62  
63  import javax.servlet.http.HttpServletRequest;
64  
65  /**
66   * This class provides the user interface to manage SQLFragment features ( manage, create, modify, remove )
67   */
68  @Controller( controllerJsp = "ManageSQLFragments.jsp", controllerPath = "jsp/admin/plugins/sqlpage/", right = "SQLPAGE_MANAGEMENT" )
69  public class SQLFragmentJspBean extends ManageSQLPageJspBean
70  {
71      // //////////////////////////////////////////////////////////////////////////
72      // Constants
73  
74      // templates
75      private static final String TEMPLATE_MANAGE_SQLFRAGMENTS = "/admin/plugins/sqlpage/manage_sqlfragments.html";
76      private static final String TEMPLATE_CREATE_SQLFRAGMENT = "/admin/plugins/sqlpage/create_sqlfragment.html";
77      private static final String TEMPLATE_MODIFY_SQLFRAGMENT = "/admin/plugins/sqlpage/modify_sqlfragment.html";
78  
79      // Parameters
80      private static final String PARAMETER_ID_SQLFRAGMENT = "id";
81      private static final String PARAMETER_ID_SQLPAGE = "id_page";
82  
83      // Properties for page titles
84      private static final String PROPERTY_PAGE_TITLE_MANAGE_SQLFRAGMENTS = "sqlpage.manage_sqlfragments.pageTitle";
85      private static final String PROPERTY_PAGE_TITLE_MODIFY_SQLFRAGMENT = "sqlpage.modify_sqlfragment.pageTitle";
86      private static final String PROPERTY_PAGE_TITLE_CREATE_SQLFRAGMENT = "sqlpage.create_sqlfragment.pageTitle";
87  
88      // Markers
89      private static final String MARK_SQLFRAGMENT_LIST = "sqlfragment_list";
90      private static final String MARK_SQLFRAGMENT = "sqlfragment";
91      private static final String MARK_PAGE = "page";
92      private static final String MARK_ID_PAGE = "id_page";
93      private static final String MARK_POOLS_LIST = "pools_list";
94      private static final String MARK_ROLES_LIST = "roles_list";
95      private static final String JSP_MANAGE_SQLFRAGMENTS = "jsp/admin/plugins/sqlpage/ManageSQLFragments.jsp";
96  
97      // Properties
98      private static final String MESSAGE_CONFIRM_REMOVE_SQLFRAGMENT = "sqlpage.message.confirmRemoveSQLFragment";
99      private static final String MESSAGE_KEY_SQL_ERROR = "sqlpage.message.validation.sqlError";
100     private static final String MESSAGE_KEY_INVALID_SQL_COMMANDS = "sqlpage.message.validation.sqlInvalidCommand";
101     private static final String MESSAGE_KEY_TEMPLATE_ERROR = "sqlpage.message.validation.templateError";
102     private static final String VALIDATION_ATTRIBUTES_PREFIX = "sqlpage.model.entity.sqlfragment.attribute.";
103 
104     // Views
105     private static final String VIEW_MANAGE_SQLFRAGMENTS = "manageSQLFragments";
106     private static final String VIEW_CREATE_SQLFRAGMENT = "createSQLFragment";
107     private static final String VIEW_MODIFY_SQLFRAGMENT = "modifySQLFragment";
108 
109     // Actions
110     private static final String ACTION_CREATE_SQLFRAGMENT = "createSQLFragment";
111     private static final String ACTION_MODIFY_SQLFRAGMENT = "modifySQLFragment";
112     private static final String ACTION_REMOVE_SQLFRAGMENT = "removeSQLFragment";
113     private static final String ACTION_CONFIRM_REMOVE_SQLFRAGMENT = "confirmRemoveSQLFragment";
114     private static final String ACTION_MOVE_UP = "moveUp";
115     private static final String ACTION_MOVE_DOWN = "moveDown";
116 
117     // Infos
118     private static final String INFO_SQLFRAGMENT_CREATED = "sqlpage.info.sqlfragment.created";
119     private static final String INFO_SQLFRAGMENT_UPDATED = "sqlpage.info.sqlfragment.updated";
120     private static final String INFO_SQLFRAGMENT_REMOVED = "sqlpage.info.sqlfragment.removed";
121     private static String [ ] _forbiddenCommands = {
122             "update ", "delete ", "drop ", "truncate"
123     };
124     private static final long serialVersionUID = 1L;
125 
126     // Session variable to store working values
127     private SQLFragment _fragment;
128     private int _nFragmentsCount;
129 
130     /**
131      * Build the Manage View
132      * 
133      * @param request
134      *            The HTTP request
135      * @return The page
136      */
137     @View( value = VIEW_MANAGE_SQLFRAGMENTS, defaultView = true )
138     public String getManageSQLFragments( HttpServletRequest request )
139     {
140         _fragment = null;
141 
142         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
143         int nIdPage = Integer.parseInt( strIdPage );
144 
145         SQLPage page = SQLPageHome.findByPrimaryKey( nIdPage );
146         List<SQLFragment> listSQLFragments = (List<SQLFragment>) SQLFragmentHome.getSQLFragmentsList( nIdPage );
147         _nFragmentsCount = listSQLFragments.size( );
148 
149         Map<String, Object> model = getPaginatedListModel( request, MARK_SQLFRAGMENT_LIST, listSQLFragments, JSP_MANAGE_SQLFRAGMENTS );
150 
151         model.put( MARK_PAGE, page );
152 
153         return getPage( PROPERTY_PAGE_TITLE_MANAGE_SQLFRAGMENTS, TEMPLATE_MANAGE_SQLFRAGMENTS, model );
154     }
155 
156     /**
157      * Returns the form to create a sqlfragment
158      *
159      * @param request
160      *            The Http request
161      * @return the html code of the sqlfragment form
162      */
163     @View( VIEW_CREATE_SQLFRAGMENT )
164     public String getCreateSQLFragment( HttpServletRequest request )
165     {
166         _fragment = ( _fragment != null ) ? _fragment : new SQLFragment( );
167 
168         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
169 
170         Map<String, Object> model = getModel( );
171         model.put( MARK_SQLFRAGMENT, _fragment );
172         model.put( MARK_ID_PAGE, strIdPage );
173         addCommons( model );
174 
175         return getPage( PROPERTY_PAGE_TITLE_CREATE_SQLFRAGMENT, TEMPLATE_CREATE_SQLFRAGMENT, model );
176     }
177 
178     /**
179      * Process the data capture form of a new sqlfragment
180      *
181      * @param request
182      *            The Http Request
183      * @return The Jsp URL of the process result
184      */
185     @Action( ACTION_CREATE_SQLFRAGMENT )
186     public String doCreateSQLFragment( HttpServletRequest request )
187     {
188         _fragment = ( _fragment != null ) ? _fragment : new SQLFragment( );
189         populate( _fragment, request );
190 
191         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
192         Map<String, String> mapParameters = new HashMap<String, String>( );
193         mapParameters.put( PARAMETER_ID_SQLPAGE, strIdPage );
194 
195         // Check constraints
196         if ( !validateBean( _fragment, VALIDATION_ATTRIBUTES_PREFIX ) )
197         {
198             return redirect( request, VIEW_CREATE_SQLFRAGMENT, mapParameters );
199         }
200 
201         _fragment.setSqlQuery( _fragment.getSqlQuery( ).trim( ) );
202 
203         if ( !_fragment.getSqlQuery( ).equals( "" ) )
204         {
205             if ( !validateSQL( _fragment.getSqlQuery( ), _fragment.getPool( ), getLocale( ) ) )
206             {
207                 return redirect( request, VIEW_CREATE_SQLFRAGMENT, mapParameters );
208             }
209         }
210 
211         if ( !validateTemplate( _fragment.getTemplate( ), getLocale( ) ) )
212         {
213             return redirect( request, VIEW_CREATE_SQLFRAGMENT, mapParameters );
214         }
215 
216         _fragment.setIdOrder( _nFragmentsCount );
217 
218         SQLFragmentHome.create( _fragment );
219         addInfo( INFO_SQLFRAGMENT_CREATED, getLocale( ) );
220 
221         return redirect( request, VIEW_MANAGE_SQLFRAGMENTS, mapParameters );
222     }
223 
224     /**
225      * Manages the removal form of a sqlfragment whose identifier is in the http request
226      *
227      * @param request
228      *            The Http request
229      * @return the html code to confirm
230      */
231     @Action( ACTION_CONFIRM_REMOVE_SQLFRAGMENT )
232     public String getConfirmRemoveSQLFragment( HttpServletRequest request )
233     {
234         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SQLFRAGMENT ) );
235         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
236         UrlItem url = new UrlItem( getActionUrl( ACTION_REMOVE_SQLFRAGMENT ) );
237         url.addParameter( PARAMETER_ID_SQLFRAGMENT, nId );
238         url.addParameter( PARAMETER_ID_SQLPAGE, strIdPage );
239 
240         String strMessageUrl = AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE_SQLFRAGMENT, url.getUrl( ), AdminMessage.TYPE_CONFIRMATION );
241 
242         return redirect( request, strMessageUrl );
243     }
244 
245     /**
246      * Handles the removal form of a sqlfragment
247      *
248      * @param request
249      *            The Http request
250      * @return the jsp URL to display the form to manage sqlfragments
251      */
252     @Action( ACTION_REMOVE_SQLFRAGMENT )
253     public String doRemoveSQLFragment( HttpServletRequest request )
254     {
255         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SQLFRAGMENT ) );
256         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
257         SQLFragmentHome.remove( nId );
258         addInfo( INFO_SQLFRAGMENT_REMOVED, getLocale( ) );
259 
260         Map<String, String> mapParameters = new HashMap<String, String>( );
261         mapParameters.put( PARAMETER_ID_SQLPAGE, strIdPage );
262 
263         return redirect( request, VIEW_MANAGE_SQLFRAGMENTS, mapParameters );
264     }
265 
266     /**
267      * Returns the form to update info about a sqlfragment
268      *
269      * @param request
270      *            The Http request
271      * @return The HTML form to update info
272      */
273     @View( VIEW_MODIFY_SQLFRAGMENT )
274     public String getModifySQLFragment( HttpServletRequest request )
275     {
276         int nId = Integer.parseInt( request.getParameter( PARAMETER_ID_SQLFRAGMENT ) );
277         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
278 
279         if ( ( _fragment == null ) || ( _fragment.getId( ) != nId ) )
280         {
281             _fragment = SQLFragmentHome.findByPrimaryKey( nId );
282         }
283 
284         Map<String, Object> model = getModel( );
285         model.put( MARK_SQLFRAGMENT, _fragment );
286         model.put( MARK_ID_PAGE, strIdPage );
287         addCommons( model );
288 
289         return getPage( PROPERTY_PAGE_TITLE_MODIFY_SQLFRAGMENT, TEMPLATE_MODIFY_SQLFRAGMENT, model );
290     }
291 
292     /**
293      * Process the change form of a sqlfragment
294      *
295      * @param request
296      *            The Http request
297      * @return The Jsp URL of the process result
298      */
299     @Action( ACTION_MODIFY_SQLFRAGMENT )
300     public String doModifySQLFragment( HttpServletRequest request )
301     {
302         populate( _fragment, request );
303 
304         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
305         Map<String, String> mapParameters = new HashMap<String, String>( );
306         mapParameters.put( PARAMETER_ID_SQLPAGE, strIdPage );
307         mapParameters.put( PARAMETER_ID_SQLFRAGMENT, String.valueOf( _fragment.getId( ) ) );
308 
309         // Check constraints
310         if ( !validateBean( _fragment, VALIDATION_ATTRIBUTES_PREFIX ) )
311         {
312             return redirect( request, VIEW_MODIFY_SQLFRAGMENT, mapParameters );
313         }
314 
315         _fragment.setSqlQuery( _fragment.getSqlQuery( ).trim( ) );
316 
317         if ( !_fragment.getSqlQuery( ).equals( "" ) )
318         {
319             if ( !validateSQL( _fragment.getSqlQuery( ), _fragment.getPool( ), getLocale( ) ) )
320             {
321                 return redirect( request, VIEW_MODIFY_SQLFRAGMENT, mapParameters );
322             }
323         }
324 
325         if ( !validateTemplate( _fragment.getTemplate( ), getLocale( ) ) )
326         {
327             return redirect( request, VIEW_MODIFY_SQLFRAGMENT, mapParameters );
328         }
329 
330         SQLFragmentHome.update( _fragment );
331         addInfo( INFO_SQLFRAGMENT_UPDATED, getLocale( ) );
332 
333         return redirect( request, VIEW_MANAGE_SQLFRAGMENTS, mapParameters );
334     }
335 
336     /**
337      * Add commons objects to the model
338      * 
339      * @param model
340      *            The model
341      */
342     private void addCommons( Map<String, Object> model )
343     {
344         // Add pools list
345         ReferenceList listPools = new ReferenceList( );
346         AppConnectionService.getPoolList( listPools );
347         model.put( MARK_POOLS_LIST, listPools );
348 
349         // Add roles List
350         ReferenceList roleList = RoleHome.getRolesList( );
351         model.put( MARK_ROLES_LIST, roleList );
352     }
353 
354     /**
355      * Validate The SQL query
356      * 
357      * @param strSqlQuery
358      *            The query
359      * @param strPool
360      *            The connection pool
361      * @param locale
362      *            The locale
363      * @return true if valid else false
364      */
365     private boolean validateSQL( String strSqlQuery, String strPool, Locale locale )
366     {
367         String strCheckedQuery = strSqlQuery.toLowerCase( );
368 
369         for ( String strCommand : _forbiddenCommands )
370         {
371             if ( strCheckedQuery.contains( strCommand ) )
372             {
373                 String strMessage = I18nService.getLocalizedString( MESSAGE_KEY_INVALID_SQL_COMMANDS, locale );
374                 addError( strMessage + strCommand );
375 
376                 return false;
377             }
378         }
379 
380         try
381         {
382             SQLService.validateSQL( strSqlQuery, strPool );
383         }
384         catch( SQLQueryException ex )
385         {
386             String strMessage = I18nService.getLocalizedString( MESSAGE_KEY_SQL_ERROR, locale );
387             addError( strMessage + ex.getCause( ).getMessage( ) );
388 
389             return false;
390         }
391 
392         return true;
393     }
394 
395     /**
396      * Validate a template
397      * 
398      * @param strTemplate
399      *            The template
400      * @param locale
401      *            The locale
402      * @return true if valid otherwise false
403      */
404     private boolean validateTemplate( String strTemplate, Locale locale )
405     {
406         try
407         {
408             SQLPageService.validateTemplate( strTemplate, locale );
409         }
410         catch( TemplateException ex )
411         {
412             String strMessage = I18nService.getLocalizedString( MESSAGE_KEY_TEMPLATE_ERROR, locale );
413             addError( strMessage + ex.getMessage( ) );
414 
415             return false;
416         }
417         catch( IOException ex )
418         {
419             String strMessage = I18nService.getLocalizedString( MESSAGE_KEY_TEMPLATE_ERROR, locale );
420             addError( strMessage + ex.getMessage( ) );
421 
422             return false;
423         }
424 
425         return true;
426     }
427 
428     /**
429      * Process the data capture form of a new sqlfragment
430      *
431      * @param request
432      *            The Http Request
433      * @return The Jsp URL of the process result
434      */
435     @Action( ACTION_MOVE_UP )
436     public String doMoveUp( HttpServletRequest request )
437     {
438         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
439         int nPageId = Integer.parseInt( strIdPage );
440 
441         int nFragmentId = Integer.parseInt( request.getParameter( PARAMETER_ID_SQLFRAGMENT ) );
442 
443         List<SQLFragment> listFragments = SQLFragmentHome.getSQLFragmentsList( nPageId );
444 
445         SQLFragment previous = null;
446 
447         for ( SQLFragment fragment : listFragments )
448         {
449             if ( fragment.getId( ) == nFragmentId )
450             {
451                 if ( previous != null )
452                 {
453                     SQLFragmentHome.swapFragmentsOrder( previous, fragment );
454 
455                     break;
456                 }
457             }
458 
459             previous = fragment;
460         }
461 
462         Map<String, String> mapParameters = new HashMap<String, String>( );
463         mapParameters.put( PARAMETER_ID_SQLPAGE, strIdPage );
464 
465         return redirect( request, VIEW_MANAGE_SQLFRAGMENTS, mapParameters );
466     }
467 
468     /**
469      * Process the data capture form of a new sqlfragment
470      *
471      * @param request
472      *            The Http Request
473      * @return The Jsp URL of the process result
474      */
475     @Action( ACTION_MOVE_DOWN )
476     public String doMoveDown( HttpServletRequest request )
477     {
478         String strIdPage = request.getParameter( PARAMETER_ID_SQLPAGE );
479         int nPageId = Integer.parseInt( strIdPage );
480 
481         int nFragmentId = Integer.parseInt( request.getParameter( PARAMETER_ID_SQLFRAGMENT ) );
482 
483         List<SQLFragment> listFragments = SQLFragmentHome.getSQLFragmentsList( nPageId );
484 
485         SQLFragment previous = null;
486 
487         for ( SQLFragment fragment : listFragments )
488         {
489             if ( previous != null )
490             {
491                 SQLFragmentHome.swapFragmentsOrder( previous, fragment );
492 
493                 break;
494             }
495 
496             if ( fragment.getId( ) == nFragmentId )
497             {
498                 previous = fragment;
499             }
500         }
501 
502         Map<String, String> mapParameters = new HashMap<String, String>( );
503         mapParameters.put( PARAMETER_ID_SQLPAGE, strIdPage );
504 
505         return redirect( request, VIEW_MANAGE_SQLFRAGMENTS, mapParameters );
506     }
507 }