View Javadoc
1   /*
2    * Copyright (c) 2002-2017, 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.jsr168.business.portlet;
35  
36  import fr.paris.lutece.plugins.jsr168.pluto.Button;
37  import fr.paris.lutece.plugins.jsr168.pluto.Buttons;
38  import fr.paris.lutece.plugins.jsr168.pluto.LuteceToPlutoConnector;
39  import fr.paris.lutece.portal.business.portlet.Portlet;
40  import fr.paris.lutece.util.xml.XmlUtil;
41  
42  import java.util.Iterator;
43  import java.util.StringTokenizer;
44  
45  import javax.servlet.http.HttpServletRequest;
46  
47  
48  /**
49   * This class represents business objects HtmlPortlet
50   */
51  public class Jsr168Portlet extends Portlet
52  {
53      private static final String TAG_HTML_PORTLET = "html-portlet";
54      private static final String TAG_HTML_PORTLET_CONTENT = "html-portlet-content";
55      private static final String XML_ELEMENT_PORTLET_BUTTONS = "portlet-buttons";
56      private static final String XML_ELEMENT_PORTLET_BUTTONS_MODES = "modes";
57      private static final String XML_ELEMENT_PORTLET_BUTTONS_STATES = "states";
58  
59      /////////////////////////////////////////////////////////////////////////////////
60      // Constants
61      private String _strJsr168Name;
62  
63      /**
64       * Sets the identifier of the portlet type to value specified
65       */
66      public Jsr168Portlet(  )
67      {
68          setPortletTypeId( Jsr168PortletHome.getInstance(  ).getPortletTypeId(  ) );
69      }
70  
71      /**
72       * Sets the name of the jsr 168 portlet
73       *
74       * @param strJsr168Name the name of the jsr 168 portlet
75       */
76      public void setJsr168Name( String strJsr168Name )
77      {
78          _strJsr168Name = strJsr168Name;
79      }
80  
81      /**
82       * Returns the name of the jsr 168 name
83       *
84       * @return the name of the Jsr 168 portlet
85       */
86      public String getJsr168Name(  )
87      {
88          return _strJsr168Name;
89      }
90  
91      /**
92       * Add the common tags to all the portlets to the XML document
93       *
94       * @param sbPortlet The string buffer which contains the XML content of this portlet
95       * @return The XML content of this portlet encapsulated by the common tags
96       */
97      protected String addPortletTags( StringBuffer sbPortlet )
98      {
99          StringBuffer sbXml = new StringBuffer(  );
100         XmlUtil.beginElement( sbXml, TAG_PORTLET );
101         XmlUtil.addElementHtml( sbXml, TAG_PORTLET_NAME, getName(  ) );
102         XmlUtil.addElement( sbXml, TAG_PORTLET_ID, getId(  ) );
103         XmlUtil.addElement( sbXml, TAG_PAGE_ID, getPageId(  ) );
104         addPortletButtons( sbXml );
105         sbXml.append( sbPortlet );
106         XmlUtil.endElement( sbXml, TAG_PORTLET );
107 
108         return sbXml.toString(  );
109     }
110 
111     /**
112      * Removes the current instance of the HtmlPortlet object
113      */
114     public void remove(  )
115     {
116         Jsr168PortletHome.getInstance(  ).remove( this );
117     }
118 
119     /*
120             Method to add when portlets can follow the server life-cycle.
121             This method must be called when the server shutdown.
122             It calls "destroy" method of JSR168 portlets. JSR 168 Portlets
123             can release ressources: database connexions, transactions, open files...
124     
125             public void destroy()
126             {
127                     try
128                     {
129                             PortletContainerFactory.
130                                     getPortletContainer().
131                                             shutdown();
132     
133                             // destroy all services
134     
135                             ServiceManager.destroy (getServletConfig ());
136     
137                             System.gc ();
138                     }
139                     catch (Throwable t)
140                     {
141                             log ("Destruction failed!", t);
142                     }
143             }
144     */
145 
146     /**
147      * Returns the Xml code of the HTML portlet without Xml header
148      *
149      * @param request Current user HTTP Request
150      * @return the Xml code of the HTML portlet content
151      */
152     public String getXml( HttpServletRequest request )
153     {
154         StringBuffer sbXml = new StringBuffer(  );
155         XmlUtil.beginElement( sbXml, TAG_HTML_PORTLET );
156         XmlUtil.addElementHtml( sbXml, TAG_HTML_PORTLET_CONTENT,
157             LuteceToPlutoConnector.render( getId(  ), getJsr168Name(  ) ) );
158         XmlUtil.endElement( sbXml, TAG_HTML_PORTLET );
159 
160         return addPortletTags( sbXml );
161     }
162 
163     /**
164      * Returns the Xml code of the HTML portlet with Xml header
165      *
166      * @param request Current user HTTP Request
167      * @return the Xml code of the HTML portlet
168      */
169     public String getXmlDocument( HttpServletRequest request )
170     {
171         return XmlUtil.getXmlHeader(  ) + getXml( request );
172     }
173 
174     /**
175      * Updates the current instance of the HtmlPortlet object
176      */
177     public void update(  )
178     {
179         Jsr168PortletHome.getInstance(  ).update( this );
180     }
181 
182     /**
183      * Add buttons associate with this portlet.<br>
184      *
185      * Side-effect: for perfomance, this method append text in the buffer
186      * argument <code>bufXml</code>
187      *
188      * @param sbXml Buffer of current portlet xml fragment (side-effect on parameter:
189      *     append text in the buffer)
190      */
191     private void addPortletButtons( StringBuffer sbXml )
192     {
193         // Get defined buttons for this portlet
194         Buttons buttons = LuteceToPlutoConnector.getButtons( getId(  ), getJsr168Name(  ) );
195 
196         XmlUtil.beginElement( sbXml, XML_ELEMENT_PORTLET_BUTTONS );
197 
198         // Add "modes" buttons
199         XmlUtil.beginElement( sbXml, XML_ELEMENT_PORTLET_BUTTONS_MODES );
200 
201         for ( Iterator it = buttons.modes(  ); it.hasNext(  ); )
202         {
203             Button button = (Button) it.next(  );
204             sbXml.append( "<button link=\"" ).append( protectAmp( button.getUrlRender(  ) ) ).append( "\" image=\"" )
205                  .append( button.getImagePath(  ) ).append( "\"/>" );
206         }
207 
208         XmlUtil.endElement( sbXml, XML_ELEMENT_PORTLET_BUTTONS_MODES );
209 
210         // Add "states" buttons
211         XmlUtil.beginElement( sbXml, XML_ELEMENT_PORTLET_BUTTONS_STATES );
212 
213         for ( Iterator it = buttons.states(  ); it.hasNext(  ); )
214         {
215             Button button = (Button) it.next(  );
216             sbXml.append( "<button link=\"" ).append( protectAmp( button.getUrlRender(  ) ) ).append( "\" image=\"" )
217                  .append( button.getImagePath(  ) ).append( "\"/>" );
218         }
219 
220         XmlUtil.endElement( sbXml, XML_ELEMENT_PORTLET_BUTTONS_STATES );
221 
222         XmlUtil.endElement( sbXml, XML_ELEMENT_PORTLET_BUTTONS );
223     }
224 
225     /**
226      * Optimized function for protecting the character &quot;&amp;&quot;
227      * by replacing it with an &quot;&amp;amp;&quot;.
228      *
229      * @param strSrc The string to analyse
230      * @return The string with character replaced
231      */
232     private String protectAmp( String strSrc )
233     {
234         StringBuffer buf = new StringBuffer( strSrc.length(  ) );
235 
236         for ( StringTokenizer tokenizer = new StringTokenizer( strSrc, "&" ); tokenizer.hasMoreElements(  ); )
237         {
238             String token = tokenizer.nextToken(  );
239             buf.append( token );
240 
241             if ( tokenizer.hasMoreElements(  ) )
242             {
243                 buf.append( "&amp;" );
244             }
245         }
246 
247         return buf.toString(  );
248     }
249 }