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.rss.business.RssFeed;
37  import fr.paris.lutece.plugins.rss.business.RssFeedHome;
38  import fr.paris.lutece.portal.service.resource.Resource;
39  import fr.paris.lutece.portal.service.resource.ResourceLoader;
40  import fr.paris.lutece.portal.service.util.AppLogService;
41  import fr.paris.lutece.portal.service.util.AppPathService;
42  import fr.paris.lutece.util.httpaccess.HttpAccess;
43  import fr.paris.lutece.util.httpaccess.HttpAccessException;
44  
45  import java.io.BufferedReader;
46  import java.io.File;
47  import java.io.FileNotFoundException;
48  import java.io.FileOutputStream;
49  import java.io.FileReader;
50  import java.io.IOException;
51  
52  import java.sql.Timestamp;
53  
54  import java.util.ArrayList;
55  import java.util.Collection;
56  import java.util.Date;
57  import java.util.Iterator;
58  
59  
60  /**
61   *
62   * This class delivers RSS contents loaded from Internet Feeds
63   */
64  public class RssContentLoader implements ResourceLoader
65  {
66      private static final String PROPERTY_CACHE_DIRECTORY = "rss.content.service.cache.directory";
67      private static final String FILE_EXT = ".xml";
68      private static final int FETCH_OK = 0;
69      private static final int FETCH_ERROR = 1;
70  
71      /**
72       * Implementation of the ResourceLoader interface
73       * @return A collection of resources
74       */
75      public Collection getResources(  )
76      {
77          ArrayList listRssContents = new ArrayList(  );
78          Collection colRssFeeds = RssFeedHome.getRssFeeds(  );
79          Iterator i = colRssFeeds.iterator(  );
80  
81          while ( i.hasNext(  ) )
82          {
83              RssFeed="../../../../../../fr/paris/lutece/plugins/rss/business/RssFeed.html#RssFeed">RssFeed rss = (RssFeed) i.next(  );
84              Resource resource = getResource( "" + rss.getId(  ) );
85              listRssContents.add( resource );
86          }
87  
88          return listRssContents;
89      }
90  
91      /**
92       * Implementation of the ResourceLoader interface
93       * @param strId The resource Id
94       * @return The Resource
95       */
96      public Resource getResource( String strId )
97      {
98          RssContentrvice/RssContent.html#RssContent">RssContent rssContent = new RssContent(  );
99          String strContent = getFromCacheFile( strId );
100 
101         if ( strContent == null )
102         {
103             int nId = Integer.parseInt( strId );
104 
105             try
106             {
107                 strContent = fetchRssFeed( nId );
108             }
109             catch ( RssParsingException ex )
110             {
111                 AppLogService.error( ex.getMessage(  ), ex );
112             }
113         }
114 
115         rssContent.setContent( strContent );
116 
117         return rssContent;
118     }
119 
120     /**
121      * Fetch an active RSS feed
122      * @param nId The RSS feed Id
123      * @return The content of the RSS feed
124      * @throws RssParsingException If a parsing exception occurs
125      */
126     public static String fetchRssFeed( int nId ) throws RssParsingException
127     {
128         String strContent = null;
129         RssFeed rss = RssFeedHome.findByPrimaryKey( nId, true );
130         HttpAccess httpAccess = new HttpAccess(  );
131 
132         try
133         {
134             strContent = httpAccess.doGet( rss.getUrl(  ) );
135             rss.setLastFetchStatus( FETCH_OK );
136             rss.setLastFetchError( "" );
137             saveInCacheFile( rss.getId(  ), strContent );
138         }
139         catch ( HttpAccessException e )
140         {
141             rss.setLastFetchStatus( FETCH_ERROR );
142             rss.setLastFetchError( e.getMessage(  ) );
143         }
144 
145         rss.setLastFetchDate( new Timestamp( new Date(  ).getTime(  ) ) );
146         RssFeedHome.updateLastFetchInfos( rss );
147 
148         return strContent;
149     }
150 
151     /**
152      * Gets the content of the RSS feed from a cache file
153      * @param strId The RS feed Id
154      * @return The content of the RSS feed
155      */
156     private static String getFromCacheFile( String strId )
157     {
158         String strContent = null;
159         String strFilePath = AppPathService.getPath( PROPERTY_CACHE_DIRECTORY, strId + FILE_EXT );
160         File file = new File( strFilePath );
161         BufferedReader input = null;
162 
163         StringBuffer sbContent = new StringBuffer(  );
164 
165         try
166         {
167             //use buffering
168             //this implementation reads one line at a time
169             //FileReader always assumes default encoding is OK!
170             input = new BufferedReader( new FileReader( file ) );
171 
172             String strLine = null;
173 
174             while ( ( strLine = input.readLine(  ) ) != null )
175             {
176                 sbContent.append( strLine );
177             }
178 
179             strContent = sbContent.toString(  );
180         }
181         catch ( FileNotFoundException e )
182         {
183             AppLogService.error( e.getMessage(  ), e );
184         }
185         catch ( IOException e )
186         {
187             AppLogService.error( e.getMessage(  ), e );
188         }
189         finally
190         {
191             try
192             {
193                 if ( input != null )
194                 {
195                     //flush and close both "input" and its underlying FileReader
196                     input.close(  );
197                 }
198             }
199             catch ( IOException e )
200             {
201                 AppLogService.error( e.getMessage(  ), e );
202             }
203         }
204 
205         return strContent;
206     }
207 
208     /**
209      * Save the content of the RSS feed in a cache file
210      * @param nId The RSS feed ID
211      * @param strContent The content of the RSS feed to store
212      */
213     private static void saveInCacheFile( int nId, String strContent )
214     {
215         String strFilePath = AppPathService.getPath( PROPERTY_CACHE_DIRECTORY, "" + nId + FILE_EXT );
216 
217         try
218         {
219             File file = new File( strFilePath );
220 
221             if ( file.exists(  ) )
222             {
223                 file.delete(  );
224             }
225 
226             FileOutputStream fos = new FileOutputStream( file );
227             fos.flush(  );
228             fos.write( strContent.getBytes(  ) );
229             fos.close(  );
230         }
231         catch ( IOException io )
232         {
233             AppLogService.error( io.getMessage(  ), io );
234         }
235     }
236 
237     /**
238      * Fetch all feeds
239      * @return the log message
240      */
241     public static String fetchAllRssFeeds(  )
242     {
243         StringBuffer sbProcessingLog = new StringBuffer(  );
244         Collection colRssFeeds = RssFeedHome.getRssFeeds(  );
245         Iterator i = colRssFeeds.iterator(  );
246 
247         while ( i.hasNext(  ) )
248         {
249             RssFeed="../../../../../../fr/paris/lutece/plugins/rss/business/RssFeed.html#RssFeed">RssFeed rss = (RssFeed) i.next(  );
250 
251             try
252             {
253                 fetchRssFeed( rss.getId(  ) );
254             }
255             catch ( RssParsingException ex )
256             {
257                 AppLogService.error( ex.getMessage(  ), ex );
258             }
259 
260             sbProcessingLog.append( "\nFetching " + rss.toString(  ) );
261         }
262 
263         return sbProcessingLog.toString(  );
264     }
265 }