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.business.portlet;
35
36 import fr.paris.lutece.portal.business.XmlContent;
37 import fr.paris.lutece.portal.business.page.Page;
38 import fr.paris.lutece.portal.business.stylesheet.StyleSheet;
39 import fr.paris.lutece.portal.web.l10n.LocaleService;
40 import fr.paris.lutece.util.xml.XmlUtil;
41
42 import java.sql.Timestamp;
43 import java.util.Locale;
44 import java.util.Map;
45
46 import javax.servlet.http.HttpServletRequest;
47
48 /**
49 * This class represents business objects Portlet. It is the base class of all portlets. It is abstract and the implementation of the interface XmlContent is
50 * compulsory.
51 */
52 public abstract class Portlet implements XmlContent
53 {
54 // //////////////////////////////////////////////////////////////////////////
55 // Publics variables common to all the portlets
56 public static final int STATUS_PUBLISHED = 0;
57 public static final int STATUS_UNPUBLISHED = 1;
58 public static final int FLAG_DISPLAY_ON_SMALL_DEVICE = 0x00000001;
59 public static final int FLAG_DISPLAY_ON_NORMAL_DEVICE = 0x00000010;
60 public static final int FLAG_DISPLAY_ON_LARGE_DEVICE = 0x00000100;
61 public static final int FLAG_DISPLAY_ON_XLARGE_DEVICE = 0x00001000;
62 private static final String VALUE_TRUE = "1";
63 private static final String VALUE_FALSE = "0";
64
65 // //////////////////////////////////////////////////////////////////////////
66 // Privates variables common to all the portlets
67 private static final int MODE_NORMAL = 0;
68 private static final int MODE_ADMIN = 1;
69 private int _nId;
70 private int _nPageId;
71 private int _nStyleId;
72 private int _nColumn;
73 private int _nOrder;
74 private int _nStatus;
75 private int _nAcceptAlias;
76 private int _nDisplayPortletTitle;
77 private String _strName;
78 private String _strPortletTypeId;
79 private String _strPortletTypeName;
80 private String _strUrlCreation;
81 private String _strUrlUpdate;
82 private String _strPluginName;
83 private String _strHomeClassName;
84 private String _strRole;
85 private Timestamp _dateUpdate;
86 private int _nDeviceFlags;
87
88 // //////////////////////////////////////////////////////////////////////////
89 // Accessors
90
91 /**
92 * Returns the identifier of this portlet.
93 *
94 * @return the portlet identifier
95 */
96 public int getId( )
97 {
98 return _nId;
99 }
100
101 /**
102 * Sets the identifier of the portlet to the specified int.
103 *
104 * @param nId
105 * the new identifier
106 */
107 public void setId( int nId )
108 {
109 _nId = nId;
110 }
111
112 /**
113 * Returns the style identifier of this portlet
114 *
115 * @return the style identifier
116 */
117 public int getStyleId( )
118 {
119 return _nStyleId;
120 }
121
122 /**
123 * Sets the identifier of the portlet style with the specified int.
124 *
125 * @param nStyleId
126 * the new style identifier
127 */
128 public void setStyleId( int nStyleId )
129 {
130 _nStyleId = nStyleId;
131 }
132
133 /**
134 * Returns the page identifier associated to this portlet
135 *
136 * @return the page identifier
137 */
138 public int getPageId( )
139 {
140 return _nPageId;
141 }
142
143 /**
144 * Sets the identifier of the portlet style with the specified int.
145 *
146 * @param nPageId
147 * The identifier of the page
148 */
149 public void setPageId( int nPageId )
150 {
151 _nPageId = nPageId;
152 }
153
154 /**
155 * Returns the identifier of this portlet.
156 *
157 * @return the portlet identifier
158 */
159 public int getStatus( )
160 {
161 return _nStatus;
162 }
163
164 /**
165 * Sets the identifier of the portlet to the specified int.
166 *
167 * @param nStatus
168 * the new status
169 */
170 public void setStatus( int nStatus )
171 {
172 _nStatus = nStatus;
173 }
174
175 /**
176 * Returns the name of this portlet
177 *
178 * @return the portlet name
179 */
180 public String getName( )
181 {
182 return _strName;
183 }
184
185 /**
186 * Sets the name of this portlet to the specified string.
187 *
188 * @param strName
189 * the new name
190 */
191 public void setName( String strName )
192 {
193 _strName = strName;
194 }
195
196 /**
197 * Returns the identifier of the portlet type of this portlet which caracterizes the portlet.
198 *
199 * @return the portlet type identifier
200 */
201 public String getPortletTypeId( )
202 {
203 return _strPortletTypeId;
204 }
205
206 /**
207 * Sets the identifier of the portlet type to the specified int.
208 *
209 * @param strPortletTypeId
210 * the portlet type identifier
211 */
212 public void setPortletTypeId( String strPortletTypeId )
213 {
214 _strPortletTypeId = strPortletTypeId;
215 }
216
217 /**
218 * Returns the portlet type name of this portlet
219 *
220 * @return the portlet type name
221 */
222 public String getPortletTypeName( )
223 {
224 return _strPortletTypeName;
225 }
226
227 /**
228 * Sets the name of this portlet type with the specified string.
229 *
230 * @param strPortletTypeName
231 * the new portlet type name
232 */
233 public void setPortletTypeName( String strPortletTypeName )
234 {
235 _strPortletTypeName = strPortletTypeName;
236 }
237
238 /**
239 * Returns the url of the program which manages the creation of a portlet
240 *
241 * @return the url of the creation
242 */
243 public String getUrlCreation( )
244 {
245 return _strUrlCreation;
246 }
247
248 /**
249 * Sets the url of the program which creates this portlet
250 *
251 * @param strUrlCreation
252 * The url of creation
253 */
254 public void setUrlCreation( String strUrlCreation )
255 {
256 _strUrlCreation = strUrlCreation;
257 }
258
259 /**
260 * Returns the url of the program which manages the update of a portlet
261 *
262 * @return the url of the program as a String
263 */
264 public String getUrlUpdate( )
265 {
266 return _strUrlUpdate;
267 }
268
269 /**
270 * Sets the url of the program which updates this portlet
271 *
272 * @param strUrlUpdate
273 * The url of update
274 */
275 public void setUrlUpdate( String strUrlUpdate )
276 {
277 _strUrlUpdate = strUrlUpdate;
278 }
279
280 /**
281 * Returns the date of update of this portlet
282 *
283 * @return the update date
284 */
285 public Timestamp getDateUpdate( )
286 {
287 return _dateUpdate;
288 }
289
290 /**
291 * Sets the date of update of this portlet with the specified date.
292 *
293 * @param dateUpdate
294 * the new date
295 */
296 public void setDateUpdate( Timestamp dateUpdate )
297 {
298 _dateUpdate = dateUpdate;
299 }
300
301 /**
302 * Return the number of the column of this portlet in the page
303 *
304 * @return the number of the column
305 */
306 public int getColumn( )
307 {
308 return _nColumn;
309 }
310
311 /**
312 * Sets the number of the column of this portlet in its page with the specified int.
313 *
314 * @param nColumn
315 * the new number of column
316 */
317 public void setColumn( int nColumn )
318 {
319 _nColumn = nColumn;
320 }
321
322 /**
323 * Returns the order of this portlet in the page which contains it.
324 *
325 * @return the order
326 */
327 public int getOrder( )
328 {
329 return _nOrder;
330 }
331
332 /**
333 * Sets the order of this portlet in its page with the specified int.
334 *
335 * @param nType
336 * the new order
337 */
338 public void setOrder( int nType )
339 {
340 _nOrder = nType;
341 }
342
343 /**
344 * Gets device display flags
345 *
346 * @return Flags
347 */
348 public int getDeviceDisplayFlags( )
349 {
350 return _nDeviceFlags;
351 }
352
353 /**
354 * Check if a flag is setted
355 *
356 * @param nFlag
357 * The flag to check
358 * @return true if the flag is set, otherwise false
359 */
360 public boolean hasDeviceDisplayFlag( int nFlag )
361 {
362 return ( _nDeviceFlags & nFlag ) != 0;
363 }
364
365 /**
366 * Set device display flags
367 *
368 * @param nFlags
369 * Flags
370 */
371 public void setDeviceDisplayFlags( int nFlags )
372 {
373 _nDeviceFlags = nFlags;
374 }
375
376 /**
377 * Returns the name of the java class which manages this type of portlet.
378 *
379 * @return the java class name
380 */
381 public String getHomeClassName( )
382 {
383 return _strHomeClassName;
384 }
385
386 /**
387 * Sets the name of the java class which manages this type of portlet with the specified string.
388 *
389 * @param strHomeClassName
390 * The Home Class name
391 */
392 public void setHomeClassName( String strHomeClassName )
393 {
394 _strHomeClassName = strHomeClassName;
395 }
396
397 /**
398 * Indicates if this portlet can be modified after its creation or not.
399 *
400 * @return 1 if the portlet can be updated, 0 if not
401 */
402 public int getAcceptAlias( )
403 {
404 return _nAcceptAlias;
405 }
406
407 /**
408 * Sets the flag which indicates that this portlet can be have a title or not.
409 *
410 * @param nDisplayPortletTitle
411 * The flag
412 */
413 public void setDisplayPortletTitle( int nDisplayPortletTitle )
414 {
415 _nDisplayPortletTitle = nDisplayPortletTitle;
416 }
417
418 /**
419 * Indicates if this portlet can be modified have a title or not.
420 *
421 * @return 1 if the portlet can be have a title, 0 if not
422 */
423 public int getDisplayPortletTitle( )
424 {
425 return _nDisplayPortletTitle;
426 }
427
428 /**
429 * Sets the flag which indicates that this portlet can be updated or not.
430 *
431 * @param nAcceptAlias
432 * The flag
433 */
434 public void setAcceptAlias( int nAcceptAlias )
435 {
436 _nAcceptAlias = nAcceptAlias;
437 }
438
439 /**
440 * Get the plugin Name
441 *
442 * @return The pluginName
443 */
444 public String getPluginName( )
445 {
446 return _strPluginName;
447 }
448
449 /**
450 * Sets the flag which indicates that this portlet can be updated or not.
451 *
452 * @param strPluginName
453 * The flag
454 */
455 public void setPluginName( String strPluginName )
456 {
457 _strPluginName = strPluginName;
458 }
459
460 /**
461 * Gets the portlet's role
462 *
463 * @return page's role as a String
464 * @since v2.5
465 */
466 public String getRole( )
467 {
468 _strRole = ( _strRole == null ) ? Page.ROLE_NONE : _strRole;
469
470 return _strRole;
471 }
472
473 /**
474 * Sets the portlet's role
475 *
476 * @param strRole
477 * The role
478 * @since v2.5
479 */
480 public void setRole( String strRole )
481 {
482 _strRole = ( ( strRole == null ) || ( strRole.equals( "" ) ) ) ? Page.ROLE_NONE : strRole;
483 }
484
485 // //////////////////////////////////////////////////////////////////////////
486 // Operations
487
488 /**
489 * This method copies the fields of the portlet specified in this portlet.
490 *
491 * @param portlet
492 * the portlet to copy
493 */
494 public void copy( Portlet portlet )
495 {
496 setId( portlet.getId( ) );
497 setPortletTypeId( portlet.getPortletTypeId( ) );
498 setPageId( portlet.getPageId( ) );
499 setStyleId( portlet.getStyleId( ) );
500 setName( portlet.getName( ) );
501 setPortletTypeName( portlet.getPortletTypeName( ) );
502 setUrlCreation( portlet.getUrlCreation( ) );
503 setUrlUpdate( portlet.getUrlUpdate( ) );
504 setDateUpdate( portlet.getDateUpdate( ) );
505 setColumn( portlet.getColumn( ) );
506 setOrder( portlet.getOrder( ) );
507 setAcceptAlias( portlet.getAcceptAlias( ) );
508 setPluginName( portlet.getPluginName( ) );
509 setDisplayPortletTitle( portlet.getDisplayPortletTitle( ) );
510 setDeviceDisplayFlags( portlet.getDeviceDisplayFlags( ) );
511 setStatus( portlet.getStatus( ) );
512 setRole( portlet.getRole( ) );
513 }
514
515 /**
516 * Add the common tags to all the portlets to the XML document
517 *
518 * @param strPortlet
519 * The string buffer which contains the XML content of this portlet
520 * @return The XML content of this portlet encapsulated by the common tags
521 */
522 protected String addPortletTags( StringBuffer strPortlet )
523 {
524 StringBuffer strXml = new StringBuffer( );
525 XmlUtil.beginElement( strXml, TAG_PORTLET );
526 XmlUtil.addElementHtml( strXml, TAG_PORTLET_NAME, getName( ) );
527 XmlUtil.addElement( strXml, TAG_PORTLET_ID, getId( ) );
528 XmlUtil.addElement( strXml, TAG_PAGE_ID, getPageId( ) );
529 XmlUtil.addElement( strXml, TAG_PLUGIN_NAME, getPluginName( ) );
530 XmlUtil.addElement( strXml, TAG_DISPLAY_PORTLET_TITLE, getDisplayPortletTitle( ) );
531
532 String strDisplayOnSmallDevice = ( ( getDeviceDisplayFlags( ) & FLAG_DISPLAY_ON_SMALL_DEVICE ) != 0 ) ? VALUE_TRUE : VALUE_FALSE;
533 XmlUtil.addElement( strXml, TAG_DISPLAY_ON_SMALL_DEVICE, strDisplayOnSmallDevice );
534
535 String strDisplayOnNormalDevice = ( ( getDeviceDisplayFlags( ) & FLAG_DISPLAY_ON_NORMAL_DEVICE ) != 0 ) ? VALUE_TRUE : VALUE_FALSE;
536 XmlUtil.addElement( strXml, TAG_DISPLAY_ON_NORMAL_DEVICE, strDisplayOnNormalDevice );
537
538 String strDisplayOnLargeDevice = ( ( getDeviceDisplayFlags( ) & FLAG_DISPLAY_ON_LARGE_DEVICE ) != 0 ) ? VALUE_TRUE : VALUE_FALSE;
539 XmlUtil.addElement( strXml, TAG_DISPLAY_ON_LARGE_DEVICE, strDisplayOnLargeDevice );
540
541 String strDisplayOnXLargeDevice = ( ( getDeviceDisplayFlags( ) & FLAG_DISPLAY_ON_XLARGE_DEVICE ) != 0 ) ? VALUE_TRUE : VALUE_FALSE;
542 XmlUtil.addElement( strXml, TAG_DISPLAY_ON_XLARGE_DEVICE, strDisplayOnXLargeDevice );
543
544 strXml.append( strPortlet.toString( ) );
545 XmlUtil.endElement( strXml, TAG_PORTLET );
546
547 return strXml.toString( );
548 }
549
550 /**
551 * Recovers the stylesheet of the portlet according to the mode
552 *
553 * @param nMode
554 * the selected mode.
555 * @return the name of the stylesheet file
556 */
557 public String getXslFile( int nMode )
558 {
559 StyleSheet xsl;
560
561 // Added in v1.3
562 // Use the same stylesheet for normal or admin mode
563 switch( nMode )
564 {
565 case MODE_NORMAL:
566 case MODE_ADMIN:
567 xsl = PortletHome.getXsl( getId( ), MODE_NORMAL );
568
569 break;
570
571 default:
572 xsl = PortletHome.getXsl( getId( ), nMode );
573
574 break;
575 }
576
577 return xsl.getFile( );
578 }
579
580 /**
581 * Recovers the stylesheet of the portlet according to the mode
582 *
583 * @param nMode
584 * the selected mode.
585 * @return the content of the stylesheet file
586 */
587 public byte [ ] getXslSource( int nMode )
588 {
589 StyleSheet xsl;
590
591 // Added in v1.3
592 // Use the same stylesheet for normal or admin mode
593 switch( nMode )
594 {
595 case MODE_NORMAL:
596 case MODE_ADMIN:
597 xsl = PortletHome.getXsl( getId( ), MODE_NORMAL );
598
599 break;
600
601 default:
602 xsl = PortletHome.getXsl( getId( ), nMode );
603
604 break;
605 }
606
607 return xsl.getSource( );
608 }
609
610 /**
611 * Recovers the parameters to use with the stylesheet at the time of the transformation.<br>
612 * By default, portlets do not return any parameter
613 *
614 * @return a collection of the type Dictionary (Use the Hashtable implementation)
615 */
616 public Map<String, String> getXslParams( )
617 {
618 return null;
619 }
620
621 /**
622 * Remove the portlet. This method MUST be overloaded on the level of the implementation of each portlet
623 */
624 public abstract void remove( );
625
626 /**
627 * Check if the content of this portlet is generated by xml and xsl, or if it manage its own content generation
628 *
629 * @return True if the content must be generated from XML and XSL, false if it must be generated by the {@link #getHtmlContent(HttpServletRequest request)}
630 * method
631 */
632 public boolean isContentGeneratedByXmlAndXsl( )
633 {
634 return true;
635 }
636
637 /**
638 * Get the HTML content of the portlet. If the content must be generated from XML and XSL, then this method should return null. This method should only be
639 * overrided if the method {@link #isContentGeneratedByXmlAndXsl()} returns true
640 *
641 * @param request
642 * The request
643 * @return The HTML content of the portlet, or null if the content is generated from XML and XSL
644 */
645 public String getHtmlContent( HttpServletRequest request )
646 {
647 return null;
648 }
649
650 /**
651 * Default getLocale() implementation. Could be overriden
652 *
653 * @param request
654 * The HTTP request
655 * @return The Locale
656 */
657 protected Locale getLocale( HttpServletRequest request )
658 {
659 return LocaleService.getContextUserLocale( request );
660 }
661
662 /**
663 * Check if the content of the portlet can be put in cache if the current user is not authenticated. If a cache is disabled for a portlet, then every page
664 * that contains a portlet of this type will NOT use the page cache, and portlet contents of this portlet type will not be saved into portlet cache.<br>
665 * WARNING : Overrides this method with extreme care : disabling page cache can cause severe performance issues !
666 *
667 * @return True if the content of the portlet can be put in cache if the user is not authenticated, false otherwise.<br>
668 * The default value is true.
669 * @see #canBeCachedForConnectedUsers() {@link #canBeCachedForConnectedUsers()} for cache for authenticated users
670 */
671 public boolean canBeCachedForAnonymousUsers( )
672 {
673 return true;
674 }
675
676 /**
677 * Check if the content of the portlet can be put in cache if the current user is authenticated. If a cache is disabled for a portlet, then every page that
678 * contains a portlet of this type will NOT use the page cache, and portlet contents of this portlet type will not be saved into portlet cache.<br>
679 * WARNING : Overrides this method with extreme care : disabling page cache can cause severe performance issues !
680 *
681 * @return True if the content of the portlet can be put in cache if the user is authenticated, false otherwise.<br>
682 * The default value is true.
683 * @see #canBeCachedForAnonymousUsers() {@link #canBeCachedForAnonymousUsers()} for cache for anonymous users
684 */
685 public boolean canBeCachedForConnectedUsers( )
686 {
687 return true;
688 }
689 }