View Javadoc
1   /*
2    * Copyright (c) 2002-2014, 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.rss.service;
35  
36  import fr.paris.lutece.plugins.document.business.Document;
37  import fr.paris.lutece.plugins.rss.business.RssGeneratedFile;
38  import fr.paris.lutece.plugins.rss.business.RssGeneratedFileHome;
39  import fr.paris.lutece.plugins.rss.web.FeedUtil;
40  import fr.paris.lutece.portal.business.rss.FeedResource;
41  import fr.paris.lutece.portal.business.rss.FeedResourceImage;
42  import fr.paris.lutece.portal.business.rss.FeedResourceItem;
43  import fr.paris.lutece.portal.business.rss.IFeedResource;
44  import fr.paris.lutece.portal.business.rss.IFeedResourceImage;
45  import fr.paris.lutece.portal.business.rss.IFeedResourceItem;
46  import fr.paris.lutece.portal.service.portal.PortalService;
47  import fr.paris.lutece.portal.service.template.AppTemplateService;
48  import fr.paris.lutece.portal.service.util.AppLogService;
49  import fr.paris.lutece.portal.service.util.AppPathService;
50  import fr.paris.lutece.portal.service.util.AppPropertiesService;
51  import fr.paris.lutece.util.html.HtmlTemplate;
52  import java.io.File;
53  import java.io.FileWriter;
54  import java.io.IOException;
55  import java.util.ArrayList;
56  import java.util.HashMap;
57  import java.util.List;
58  import java.util.Locale;
59  import java.util.Map;
60  import javax.servlet.http.HttpServletRequest;
61  import org.apache.commons.lang3.StringUtils;
62  
63  
64  /**
65   * This class provides utilities to create RSS documents.
66   */
67  public final class RssGeneratorService
68  {
69      /* Constants */
70  
71      /**
72       * The path which points the rss files are stored
73       */
74      public static final String PROPERTY_RSS_STORAGE_FOLDER_PATH = "rss.storage.folder.path";
75      public static final String PROPERTY_STORAGE_DIRECTORY_NAME = "rss.storage.directory.name";
76      private static final String TEMPLATE_PUSH_RSS_XML = "admin/plugins/rss/rss_xml.html";
77      private static final String TEMPLATE_FEED_LINK = "admin/plugins/rss/feed_link.html";
78      private static final String MARK_ITEM_LIST = "itemList";
79      private static final String MARK_RSS_SITE_NAME = "site_name";
80      private static final String MARK_RSS_FILE_LANGUAGE = "file_language";
81      private static final String MARK_RSS_SITE_URL = "site_url";
82      private static final String MARK_DOCUMENT_ID = "document_id";
83      private static final String MARK_RSS_SITE_DESCRIPTION = "site_description";
84      private static final String MARK_ID_PORTLET = "id_portlet";
85      private static final String PROPERTY_SITE_LANGUAGE = "rss.language";
86      private static final String PROPERTY_WEBAPP_PROD_URL = "lutece.prod.url";
87      private static final String PROPERTY_BASE_URL = "lutece.base.url";
88      private static final String CONSTANT_IMAGE_RSS = "/images/local/skin/plugins/rss/rss-image.png";
89  
90      /**
91       * Private constructor
92       */
93      private RssGeneratorService(  )
94      {
95      }
96  
97      ///////////////////////////////////////////////////////////////////////////
98      // Create RSS document
99  
100     /**
101      * Creates the push RSS document corresponding to the given portlet
102      *
103      * @param nIdPortlet the portlet id for wich the file is created
104      * @param strRssFileDescription the Description
105      * @param strEncoding encoding
106      * @param strFeedType feed type
107      * @param nMaxItems max items
108      * @return String the XML content of the RSS document
109      */
110     public static String createRssDocument( int nIdPortlet, String strRssFileDescription, String strEncoding,
111         String strFeedType, int nMaxItems )
112     {
113         return createRssDocument( nIdPortlet, strRssFileDescription, strEncoding, strFeedType, nMaxItems, null );
114     }
115 
116     /**
117      * Creates the push RSS document corresponding to the given portlet
118      *
119      * @param nIdPortlet the portlet id for wich the file is created
120      * @param strRssFileDescription the Description
121      * @param strEncoding encoding
122      * @param strFeedType feed type
123      * @param nMaxItems max items
124      * @param request The HTTP request
125      * @return String the XML content of the RSS document
126      */
127     public static String createRssDocument( int nIdPortlet, String strRssFileDescription, String strEncoding,
128         String strFeedType, int nMaxItems, HttpServletRequest request )
129     {
130         String strRssFileSiteName = PortalService.getSiteName();
131         String strRssFileLanguage = AppPropertiesService.getProperty( PROPERTY_SITE_LANGUAGE );
132         String strIdPortlet = Integer.toString( nIdPortlet );
133         String strWebAppUrl = AppPropertiesService.getProperty( PROPERTY_WEBAPP_PROD_URL );
134         String strSiteUrl;
135 
136         if ( StringUtils.isNotBlank( strWebAppUrl ) )
137         {
138             strSiteUrl = strWebAppUrl;
139         }
140         else
141         {
142             if ( request == null )
143             {
144                 strSiteUrl = AppPropertiesService.getProperty( PROPERTY_BASE_URL );
145             }
146             else
147             {
148                 strSiteUrl = AppPathService.getBaseUrl( request );
149             }
150         }
151 
152         IFeedResource resource = new FeedResource(  );
153         resource.setTitle( strRssFileSiteName );
154         resource.setLanguage( strRssFileLanguage );
155         resource.setLink( strSiteUrl );
156         resource.setDescription( strRssFileDescription );
157 
158         IFeedResourceImage image = new FeedResourceImage(  );
159         image.setLink( strSiteUrl );
160         image.setTitle( strRssFileDescription );
161         image.setUrl( strSiteUrl + CONSTANT_IMAGE_RSS );
162         resource.setImage( image );
163 
164         Locale locale = new Locale( strRssFileLanguage );
165 
166         List<Document> listDocuments = RssGeneratedFileHome.findDocumentsByPortlet( nIdPortlet );
167 
168         List<IFeedResourceItem> listItems = new ArrayList<IFeedResourceItem>(  );
169 
170         for ( Document document : listDocuments )
171         {
172             IFeedResourceItem item = new FeedResourceItem(  );
173             item.setTitle( document.getTitle(  ) );
174             item.setDescription( document.getSummary(  ) );
175             item.setDate( document.getDateModification(  ) );
176 
177             // link creation
178             Map<String, Object> model = new HashMap<String, Object>(  );
179             model.put( MARK_ID_PORTLET, strIdPortlet );
180             model.put( MARK_DOCUMENT_ID, document.getId(  ) );
181             model.put( MARK_RSS_SITE_URL, strSiteUrl );
182 
183             HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_FEED_LINK, locale, model );
184             String strLink = template.getHtml(  );
185             item.setGUID( strLink );
186             item.setLink( strLink );
187 
188             listItems.add( item );
189         }
190 
191         resource.setItems( listItems );
192 
193         return FeedUtil.getFeed( resource, strFeedType, strEncoding, nMaxItems );
194     }
195 
196     /**
197      * Creates the push RSS document corresponding to the given portlet
198      *
199      * @param listRssItem The RSS List
200      * @param strRssFileDescription the Description
201      * @return String the XML content of the RSS document
202      */
203     public static String createRssDocument( List listRssItem, String strRssFileDescription )
204     {
205         HashMap model = new HashMap(  );
206 
207         // Update the head of the document
208         String strRssFileSiteName = PortalService.getSiteName();
209         String strRssFileLanguage = AppPropertiesService.getProperty( PROPERTY_SITE_LANGUAGE );
210 
211         String strWebAppUrl = AppPropertiesService.getProperty( PROPERTY_WEBAPP_PROD_URL );
212         String strSiteUrl = strWebAppUrl;
213         model.put( MARK_RSS_SITE_NAME, strRssFileSiteName );
214         model.put( MARK_RSS_FILE_LANGUAGE, strRssFileLanguage );
215         model.put( MARK_RSS_SITE_URL, strSiteUrl );
216         model.put( MARK_RSS_SITE_DESCRIPTION, strRssFileDescription );
217 
218         // Find documents by portlet
219         //List listDocuments = RssGeneratedFileHome.findDocumentsByPortlet( nIdPortlet );
220         //The date must respect RFC-822 date-time
221         model.put( MARK_ITEM_LIST, listRssItem );
222 
223         Locale locale = new Locale( strRssFileLanguage );
224 
225         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_PUSH_RSS_XML, locale, model );
226 
227         return template.getHtml(  );
228     }
229 
230     /**
231      * Creates the pushrss file in the directory
232      *
233      * @param strRssFileName The file's name that must be deleted
234      * @param strRssDocument The content of the new RSS file
235      */
236     public static void createFileRss( String strRssFileName, String strRssDocument )
237     {
238         FileWriter fileRssWriter;
239 
240         try
241         {
242             // fetches the pushRss directory path
243             String strFolderPath = AppPathService.getPath( RssGeneratorService.PROPERTY_RSS_STORAGE_FOLDER_PATH, "" );
244 
245             // Test if the pushRss directory exist and create it if it doesn't exist
246             if ( !new File( strFolderPath ).exists(  ) )
247             {
248                 File fileFolder = new File( strFolderPath );
249                 fileFolder.mkdir(  );
250             }
251 
252             // Creates a temporary RSS file
253             String strFileRss = AppPathService.getPath( RssGeneratorService.PROPERTY_RSS_STORAGE_FOLDER_PATH, "" ) +
254                 strRssFileName;
255             String strFileDirectory = AppPathService.getPath( RssGeneratorService.PROPERTY_RSS_STORAGE_FOLDER_PATH, "" );
256             File fileRss = new File( strFileRss );
257             File fileRssDirectory = new File( strFileDirectory );
258             File fileRssTemp = File.createTempFile( "tmp", null, fileRssDirectory );
259             fileRssWriter = new FileWriter( fileRssTemp );
260             fileRssWriter.write( strRssDocument );
261             fileRssWriter.flush(  );
262             fileRssWriter.close(  );
263 
264             // Deletes the file if the file exists and renames the temporary file into the file
265             if ( new File( strFileRss ).exists(  ) )
266             {
267                 File file = new File( strFileRss );
268                 file.delete(  );
269             }
270 
271             fileRssTemp.renameTo( fileRss );
272         }
273         catch ( IOException e )
274         {
275             AppLogService.error( e.getMessage(  ), e );
276         }
277         catch ( NullPointerException e )
278         {
279             AppLogService.error( e.getMessage(  ), e );
280         }
281     }
282 
283     /**
284      * Deletes the pushrss file in the directory
285      *
286      * @param strRssFileName The name of the RSS file
287      * @param strPluginName The plugin's name
288      */
289     public static void deleteFileRss( String strRssFileName, String strPluginName )
290     {
291         try
292         {
293             // Define pushRss directory
294             String strFileRss = AppPathService.getPath( RssGeneratorService.PROPERTY_RSS_STORAGE_FOLDER_PATH, "" ) +
295                 strRssFileName;
296 
297             // Delete the file if file exists
298             if ( new File( strFileRss ).exists(  ) )
299             {
300                 File file = new File( strFileRss );
301                 file.delete(  );
302             }
303         }
304         catch ( NullPointerException e )
305         {
306             AppLogService.error( e.getMessage(  ), e );
307         }
308     }
309 
310     /**
311      * Regenerate all Rss files in the file system
312      * @return Execution logs
313      */
314     public static String generateAllRss(  )
315     {
316         StringBuilder sb = new StringBuilder( "Regenerate all RSS files from the database to the filesystem.\n" );
317         List<RssGeneratedFile> list = RssGeneratedFileHome.getRssFileList(  );
318 
319         for ( RssGeneratedFile file : list )
320         {
321             createRssDocument( file.getPortletId(  ), file.getDescription(  ), file.getEncoding(  ),
322                 file.getFeedType(  ), file.getMaxItems(  ) );
323             sb.append( "\nFile  " ).append( file.getName(  ) ).append( " regenerated.\n" );
324         }
325 
326         AppLogService.info( sb.toString(  ) );
327 
328         return sb.toString(  );
329     }
330 }