View Javadoc
1   /*
2    * Copyright (c) 2002-2025, 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.portal.web.portlet;
35  
36  import java.util.HashMap;
37  import java.util.Locale;
38  import java.util.Map;
39  
40  import javax.servlet.http.HttpServletRequest;
41  
42  import fr.paris.lutece.portal.business.page.PageHome;
43  import fr.paris.lutece.portal.business.portlet.Portlet;
44  import fr.paris.lutece.portal.business.portlet.PortletHome;
45  import fr.paris.lutece.portal.business.portlet.PortletType;
46  import fr.paris.lutece.portal.business.portlet.PortletTypeHome;
47  import fr.paris.lutece.portal.business.role.RoleHome;
48  import fr.paris.lutece.portal.service.message.AdminMessage;
49  import fr.paris.lutece.portal.service.message.AdminMessageService;
50  import fr.paris.lutece.portal.service.template.AppTemplateService;
51  import fr.paris.lutece.portal.service.util.AppLogService;
52  import fr.paris.lutece.portal.service.util.AppPropertiesService;
53  import fr.paris.lutece.portal.web.admin.AdminFeaturesPageJspBean;
54  import fr.paris.lutece.portal.web.constants.Messages;
55  import fr.paris.lutece.portal.web.constants.Parameters;
56  import fr.paris.lutece.util.ReferenceList;
57  import fr.paris.lutece.util.html.HtmlTemplate;
58  import fr.paris.lutece.util.string.StringUtil;
59  
60  /**
61   * This class represents user interface Portlet. It is the base class of all user interface portlets. It is abstract and the implementation of the interface
62   * PortletJspBeanInterface is compulsary.
63   */
64  public abstract class PortletJspBean extends AdminFeaturesPageJspBean
65  {
66      // //////////////////////////////////////////////////////////////////////////
67      // Constants
68      public static final String RIGHT_MANAGE_ADMIN_SITE = "CORE_ADMIN_SITE";
69  
70      // Parameters
71      protected static final String PARAMETER_PAGE_ID = "page_id";
72      protected static final String PARAMETER_PORTLET_ID = "portlet_id";
73      protected static final String PARAMETER_PORTLET_TYPE_ID = "portlet_type_id";
74      private static final long serialVersionUID = -3546292252642160812L;
75  
76      // Markers
77      private static final String MARK_PORTLET = "portlet";
78      private static final String MARK_PORTLET_TYPE = "portletType";
79      private static final String MARK_PORTLET_PAGE_ID = "portlet_page_id";
80      private static final String MARK_PORTLET_ORDER_COMBO = "portlet_order_combo";
81      private static final String MARK_PORTLET_COLUMNS_COMBO = "portlet_columns_combo";
82      private static final String MARK_PORTLET_STYLES_COMBO = "portlet_style_combo";
83      private static final String MARK_PORTLET_ROLES_COMBO = "portlet_role_combo";
84      private static final String MARK_SMALL_CHECKED = "small_checked";
85      private static final String MARK_NORMAL_CHECKED = "normal_checked";
86      private static final String MARK_LARGE_CHECKED = "large_checked";
87      private static final String MARK_XLARGE_CHECKED = "xlarge_checked";
88      private static final String VALUE_CHECKED = "checked=\"checked\"";
89      private static final String VALUE_UNCHECKED = "";
90  
91      // Templates
92      private static final String TEMPLATE_CREATE_PORTLET = "admin/portlet/create_portlet.html";
93      private static final String TEMPLATE_MODIFY_PORTLET = "admin/portlet/modify_portlet.html";
94  
95      // Properties
96      private static final String PROPERTY_LIST_ORDER_MAX = "list.order.max";
97      private static final String PROPERTY_COLUMN_NUM_MAX = "nb.columns";
98  
99      // Messages
100     private static final String MESSAGE_INVALID_PAGE_ID = "portal.site.message.pageIdInvalid";
101 
102     // Jsp
103     private static final String JSP_ADMIN_SITE = "../../site/AdminSite.jsp";
104     private static final String JSP_ADMIN_SITE_WITH_PATH = "jsp/admin/site/AdminSite.jsp";
105 
106     /**
107      * Displays the portlet's creation form
108      *
109      * @param request
110      *            The http request
111      * @return The html code for displaying the creation form
112      */
113     public abstract String getCreate( HttpServletRequest request );
114 
115     /**
116      * Processes portlet's creation
117      *
118      * @param request
119      *            The http request
120      * @return The Management jsp url
121      */
122     public abstract String doCreate( HttpServletRequest request );
123 
124     /**
125      * Displays the portlet's modification form
126      *
127      * @param request
128      *            The http request
129      * @return The html code for displaying the modification form
130      */
131     public abstract String getModify( HttpServletRequest request );
132 
133     /**
134      * Processes portlet's modification
135      *
136      * @param request
137      *            The http request
138      * @return The Management jsp url
139      */
140     public abstract String doModify( HttpServletRequest request );
141 
142     // //////////////////////////////////////////////////////////////////////////
143     // Management of the combos common to all portlets
144     // Order combo
145 
146     /**
147      * Returns a list of orders
148      *
149      * @return the list of orders in form of ReferenceList
150      */
151     private ReferenceList getOrdersList( )
152     {
153         ReferenceListnceList.html#ReferenceList">ReferenceList list = new ReferenceList( );
154         int nOrderMax = AppPropertiesService.getPropertyInt( PROPERTY_LIST_ORDER_MAX, 15 );
155 
156         for ( int i = 1; i <= nOrderMax; i++ )
157         {
158             list.addItem( i, String.valueOf( i ) );
159         }
160 
161         return list;
162     }
163 
164     /**
165      * Returns the list of the columns of the page where the portlet can be positioned
166      *
167      * @return the list of the page columns in form of ReferenceList
168      */
169     private ReferenceList getColumnsList( )
170     {
171         ReferenceListnceList.html#ReferenceList">ReferenceList list = new ReferenceList( );
172         int nColumnNumMax = AppPropertiesService.getPropertyInt( PROPERTY_COLUMN_NUM_MAX, 1 );
173 
174         for ( int i = 1; i <= nColumnNumMax; i++ )
175         {
176             list.addItem( i, String.valueOf( i ) );
177         }
178 
179         return list;
180     }
181 
182     /**
183      * Recovers the common attributes of the portlet
184      *
185      * @param request
186      *            the http request
187      * @param portlet
188      *            The instance of the portlet
189      * @return An error Key if error, otherwise null.
190      */
191     protected String setPortletCommonData( HttpServletRequest request, Portlet portlet )
192     {
193         String strErrorKey = null;
194 
195         // get portlet attributes
196         String strName = request.getParameter( Parameters.PORTLET_NAME );
197         String strStyleId = request.getParameter( Parameters.STYLE );
198         String strColumn = request.getParameter( Parameters.COLUMN );
199         String strOrder = request.getParameter( Parameters.ORDER );
200         String strAcceptAlias = request.getParameter( Parameters.ACCEPT_ALIAS );
201         String strAcceptPortletTitle = request.getParameter( Parameters.DISPLAY_PORTLET_TITLE );
202         String strPortletTypeId = request.getParameter( Parameters.PORTLET_TYPE_ID );
203         String strRole = request.getParameter( Parameters.ROLE );
204         String strDisplaySmall = request.getParameter( Parameters.DISPLAY_ON_SMALL_DEVICE );
205         String strDisplayNormal = request.getParameter( Parameters.DISPLAY_ON_NORMAL_DEVICE );
206         String strDisplayLarge = request.getParameter( Parameters.DISPLAY_ON_LARGE_DEVICE );
207         String strDisplayXLarge = request.getParameter( Parameters.DISPLAY_ON_XLARGE_DEVICE );
208 
209         strName = strName.replaceAll( "\"", "" );
210 
211         // Check Mandatory fields
212         if ( StringUtil.isAnyEmpty( strName, strOrder, strColumn, strAcceptAlias, strAcceptPortletTitle ) )
213         {
214             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, JSP_ADMIN_SITE_WITH_PATH, AdminMessage.TYPE_STOP );
215         }
216 
217         // style id is not mandatory if the content is not generated from XML and XSL
218         if ( portlet.isContentGeneratedByXmlAndXsl( ) && ( strStyleId == null || strStyleId.trim( ).equals( "" ) ) )
219         {
220             return AdminMessageService.getMessageUrl( request, Messages.MANDATORY_FIELDS, JSP_ADMIN_SITE_WITH_PATH, AdminMessage.TYPE_STOP );
221         }
222 
223         String strPageId = request.getParameter( PARAMETER_PAGE_ID );
224         int nPageId;
225 
226         // Test format of the id and the existence of the page
227         try
228         {
229             nPageId = Integer.parseInt( strPageId );
230 
231             if ( !PageHome.checkPageExist( nPageId ) )
232             {
233                 return AdminMessageService.getMessageUrl( request, MESSAGE_INVALID_PAGE_ID, JSP_ADMIN_SITE_WITH_PATH, AdminMessage.TYPE_STOP );
234             }
235         }
236         catch( NumberFormatException e )
237         {
238             AppLogService.error( e.getMessage( ), e );
239 
240             return AdminMessageService.getMessageUrl( request, MESSAGE_INVALID_PAGE_ID, JSP_ADMIN_SITE_WITH_PATH, AdminMessage.TYPE_STOP );
241         }
242 
243         int nOrder = Integer.parseInt( strOrder );
244         int nColumn = Integer.parseInt( strColumn );
245         int nAcceptAlias = Integer.parseInt( strAcceptAlias );
246         int nAcceptPortletTitle = Integer.parseInt( strAcceptPortletTitle );
247 
248         int nStyleId = portlet.isContentGeneratedByXmlAndXsl( ) ? Integer.parseInt( strStyleId ) : 0;
249 
250         int nDeviceDisplayFlags = 0;
251 
252         if ( strDisplaySmall != null )
253         {
254             nDeviceDisplayFlags |= Portlet.FLAG_DISPLAY_ON_SMALL_DEVICE;
255         }
256 
257         if ( strDisplayNormal != null )
258         {
259             nDeviceDisplayFlags |= Portlet.FLAG_DISPLAY_ON_NORMAL_DEVICE;
260         }
261 
262         if ( strDisplayLarge != null )
263         {
264             nDeviceDisplayFlags |= Portlet.FLAG_DISPLAY_ON_LARGE_DEVICE;
265         }
266 
267         if ( strDisplayXLarge != null )
268         {
269             nDeviceDisplayFlags |= Portlet.FLAG_DISPLAY_ON_XLARGE_DEVICE;
270         }
271 
272         portlet.setName( strName );
273         portlet.setOrder( nOrder );
274         portlet.setColumn( nColumn );
275         portlet.setStyleId( nStyleId );
276         portlet.setPageId( nPageId );
277         portlet.setAcceptAlias( nAcceptAlias );
278         portlet.setDisplayPortletTitle( nAcceptPortletTitle );
279         portlet.setPortletTypeId( strPortletTypeId );
280         portlet.setRole( strRole );
281         portlet.setDeviceDisplayFlags( nDeviceDisplayFlags );
282 
283         return strErrorKey;
284     }
285 
286     /**
287      * Fills templates with common values shared by portlet creation form
288      *
289      * @param strPageId
290      *            the page identifier
291      * @param strPortletTypeId
292      *            the Portlet type identifier
293      * @return the template filled
294      */
295     protected HtmlTemplate getCreateTemplate( String strPageId, String strPortletTypeId )
296     {
297         return getCreateTemplate( strPageId, strPortletTypeId, new HashMap<>( ) );
298     }
299 
300     /**
301      * Fills templates with common values shared by portlet creation form
302      *
303      * @param strPageId
304      *            the page identifier
305      * @param strPortletTypeId
306      *            the Portlet type identifier
307      * @param model
308      *            Specific data stored in a hashtable
309      * @return the template filled
310      */
311     protected HtmlTemplate getCreateTemplate( String strPageId, String strPortletTypeId, Map<String, Object> model )
312     {
313         PortletType portletType = PortletTypeHome.findByPrimaryKey( strPortletTypeId );
314         Locale locale = getLocale( );
315         portletType.setLocale( locale );
316 
317         model.put( MARK_PORTLET_TYPE, portletType );
318         model.put( MARK_PORTLET_PAGE_ID, strPageId );
319         model.put( MARK_PORTLET_ORDER_COMBO, getOrdersList( ) );
320         model.put( MARK_PORTLET_COLUMNS_COMBO, getColumnsList( ) );
321         model.put( MARK_PORTLET_STYLES_COMBO, PortletHome.getStylesList( strPortletTypeId ) );
322         model.put( MARK_PORTLET_ROLES_COMBO, RoleHome.getRolesList( getUser( ) ) );
323 
324         return AppTemplateService.getTemplate( TEMPLATE_CREATE_PORTLET, locale, model );
325     }
326 
327     /**
328      * Fills update template with portlet values
329      *
330      * @param portlet
331      *            the object to update
332      * @return the update template filled
333      */
334     protected HtmlTemplate getModifyTemplate( Portlet portlet )
335     {
336         return getModifyTemplate( portlet, new HashMap<>( ) );
337     }
338 
339     /**
340      * Fills update template with portlet values
341      *
342      * @param portlet
343      *            the object to update
344      * @param model
345      *            The Data model
346      * @return the update template filled
347      */
348     protected HtmlTemplate getModifyTemplate( Portlet portlet, Map<String, Object> model )
349     {
350         PortletType portletType = PortletTypeHome.findByPrimaryKey( portlet.getPortletTypeId( ) );
351         portletType.setLocale( getLocale( ) );
352         model.put( MARK_PORTLET_TYPE, portletType );
353         model.put( MARK_PORTLET, portlet );
354         model.put( MARK_PORTLET_ORDER_COMBO, getOrdersList( ) );
355         model.put( MARK_PORTLET_COLUMNS_COMBO, getColumnsList( ) );
356         model.put( MARK_PORTLET_STYLES_COMBO, PortletHome.getStylesList( portlet.getPortletTypeId( ) ) );
357         model.put( MARK_PORTLET_ROLES_COMBO, RoleHome.getRolesList( getUser( ) ) );
358         putCheckBox( model, MARK_SMALL_CHECKED, portlet.hasDeviceDisplayFlag( Portlet.FLAG_DISPLAY_ON_SMALL_DEVICE ) );
359         putCheckBox( model, MARK_NORMAL_CHECKED, portlet.hasDeviceDisplayFlag( Portlet.FLAG_DISPLAY_ON_NORMAL_DEVICE ) );
360         putCheckBox( model, MARK_LARGE_CHECKED, portlet.hasDeviceDisplayFlag( Portlet.FLAG_DISPLAY_ON_LARGE_DEVICE ) );
361         putCheckBox( model, MARK_XLARGE_CHECKED, portlet.hasDeviceDisplayFlag( Portlet.FLAG_DISPLAY_ON_XLARGE_DEVICE ) );
362 
363         return AppTemplateService.getTemplate( TEMPLATE_MODIFY_PORTLET, getLocale( ), model );
364     }
365 
366     /**
367      * Put check box.
368      *
369      * @param model
370      *            the model
371      * @param strMarkerChecked
372      *            the str marker checked
373      * @param bChecked
374      *            the b checked
375      */
376     protected void putCheckBox( Map<String, Object> model, String strMarkerChecked, boolean bChecked )
377     {
378         String strChecked = ( bChecked ) ? VALUE_CHECKED : VALUE_UNCHECKED;
379         model.put( strMarkerChecked, strChecked );
380     }
381 
382     /**
383      * Gets the page URL
384      * 
385      * @param nIdPage
386      *            Page ID
387      * @return The page URL
388      */
389     protected String getPageUrl( int nIdPage )
390     {
391         return JSP_ADMIN_SITE + "?" + PARAMETER_PAGE_ID + "=" + nIdPage;
392     }
393 }