View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.daemon.impl;
18  
19  
20  //jetspeed stuff
21  import org.apache.jetspeed.daemon.Daemon;
22  import org.apache.jetspeed.daemon.DaemonConfig;
23  import org.apache.jetspeed.daemon.DaemonEntry;
24  import org.apache.jetspeed.daemon.Feed;
25  import org.apache.jetspeed.util.SimpleTransform;
26  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
27  import org.apache.jetspeed.services.logging.JetspeedLogger;
28  import org.apache.jetspeed.services.resources.JetspeedResources;
29  import org.apache.jetspeed.services.registry.FileRegistry;
30  import org.apache.jetspeed.services.registry.RegistryService;
31  
32  //turbine stuff
33  import org.apache.turbine.services.TurbineServices;
34  
35  //java stuff
36  import java.io.Reader;
37  import java.util.Vector;
38  
39  /***
40  <p>
41  A daemon that parses out Jetspeed content sources.  It also handles multiple 
42  updating Feeds within PortletFactory.  When it encounters any RSS feeds that are
43  remote it will pull them locally into the JetspeedDiskCache class via the 
44  bulkdownloader class.
45  </p>
46  
47  <p>
48  The major goals of this Daemon are:
49  
50  <ul>
51      <li>Parse out OCS feeds</li>
52      <li>Put the new Entry into the PortletRegistry</li>
53      <li>Get the URL from the Internet if it hasn't been placed in the cache.</li>    
54      <li>Instantiate the Portlet if it already isn't in the cache.</li>
55  </ul>
56  
57  </p>
58  
59  @author <A HREF="mailto:burton@apache.org">Kevin A. Burton</A>
60  @author <A HREF="mailto:sgala@apache.org">Santiago Gala</A>
61  @version $Id: FeedDaemon.java,v 1.42 2004/02/23 02:48:05 jford Exp $
62  */
63  public class FeedDaemon implements Daemon 
64  {
65      public static final String TEMP_FILE_KEY = "FeedDaemon-debug";
66      
67      public static String TEMP_DIRECTORY = 
68          JetspeedResources.getString( JetspeedResources.TEMP_DIRECTORY_KEY );
69      
70      private static boolean processed = false;
71  
72      private static FeedDaemon instance = null;
73  
74  
75  
76      private int status = Daemon.STATUS_NOT_PROCESSED;
77      private int result = Daemon.RESULT_UNKNOWN;
78      private DaemonConfig config = null;
79      private DaemonEntry entry = null;
80      private boolean initialized = false;
81  
82      /***
83      The total number of entries found by the daemon
84      */
85      private static int count = 0;
86      
87      /***
88       * Static initialization of the logger for this class
89       */
90      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(FeedDaemon.class.getName());
91      
92      /***
93      Get the feed count.
94      */
95      public static int getCount() 
96      {
97          return FeedDaemon.count;
98      }
99  
100     
101     /***
102     Get the feeds that are available to Jetspeed
103     */
104     public static Feed[] getFeeds() 
105     {
106         Vector v = JetspeedResources.getVector( "contentfeeds.feed.name" );
107         Vector found = new Vector();
108         
109         for( int i = 0; i < v.size(); ++i) {
110             String name = (String)v.elementAt(i);
111             
112             String description = JetspeedResources.getString( "contentfeeds.feed." + name + ".description" );
113 
114             String url = JetspeedResources.getString( "contentfeeds.feed." + name + ".url" );
115 
116             found.addElement( new Feed( name, 
117                                         description,
118                                         url ) );
119         }
120 
121         //now that you have the properties file for the feeds transform them
122         //into PML
123         
124         Feed[] feeds = new Feed[found.size()];
125         found.copyInto(feeds);
126         return feeds;
127 
128     }
129     
130     
131     /***
132     */
133     public void run() 
134     {
135         try 
136         {
137             this.setResult( Daemon.RESULT_PROCESSING );
138 
139             logger.info( "Jetspeed:  FeedDaemon  -- BEGIN -- " );
140         
141             FeedDaemon.count = 0;
142             Feed[] feeds = getFeeds();
143 
144             for (int i = 0; i < feeds.length; ++i ) {
145 
146                 String url = feeds[i].getURL();
147 
148                 String name = "feed_"+feeds[i].getName();
149                 
150                 Reader transformed;
151 
152                 try {
153 
154                     logger.info( "BEGIN FEED -> " + url );
155 
156                     //get the list of PortletMarkup entries from OCS
157                     transformed = getEntries( url );
158                     
159                     //the string transformed should now contain PML... tranform it into PortletMarkup
160                     logger.info("Determining portlets...");
161     
162                     FileRegistry registry = (FileRegistry)TurbineServices.getInstance()
163                                                 .getService( RegistryService.SERVICE_NAME );
164 
165                     registry.createFragment( name, transformed , true );
166     
167                     logger.info( "END FEED -> " + url + " -> SUCCESS");    
168 
169                     this.setResult( Daemon.RESULT_SUCCESS );    
170 
171                 } catch ( Exception e ) {
172                     error( e, "FeedDaemon:  Couldn't process URL:  " + url );
173 
174                 } catch ( Throwable t ) {
175                     error( t, "FeedDaemon:  Couldn't process URL:  " + url );
176                 } 
177                 
178             }
179 
180         } finally {
181             logger.info( "Jetspeed:  FeedDaemon  --  END  -- " );
182         }
183 
184     }
185 
186     /***
187     Logs a message to the logging service but also sets the result for this daemon.
188     */
189     private void error( Throwable t, String message ) 
190     {
191         this.setResult( Daemon.RESULT_FAILED );
192         logger.error( message, t  );
193     }
194 
195     /***
196     */
197     private void error( String message ) 
198     {
199         this.error( null, message );
200     }
201     
202     /***
203     Get the PML for the given URL
204     */    
205     public static final Reader getEntries( String url ) throws Exception 
206     {        
207         //this should be the URL to the original document.  Transform
208         //it into PML
209  
210         String stylesheet = JetspeedResources.getString( JetspeedResources.CONTENTFEEDS_STYLESHEET_URL_KEY );
211  
212         logger.info( "FeedDaemon:  transforming url: " + 
213                   url + 
214                   " with stylesheet: " + 
215                   stylesheet );
216 
217          return SimpleTransform.SAXTransform( url, stylesheet, null );
218     }
219 
220 
221     
222     /***
223     String the DOCTYPE from the transformed document.  Castor can't handle this.
224     */
225     private static String strip(String target) 
226     {        
227         if ( target.indexOf("<!DOCTYPE") != -1 ) {
228             
229             int begin = target.indexOf( "\">" ) + 2;
230             
231             target = target.substring( begin, target.length() );
232             
233         }
234         
235         return target;
236     }
237 
238     /* *** Daemon interface *** */
239     
240     /***
241     Init this Daemon from the DaemonFactory
242     */
243     public void init( DaemonConfig config, DaemonEntry entry ) 
244     {
245         this.config = config;
246         this.entry = entry;
247     }
248     
249     /***
250     */
251     public DaemonConfig getDaemonConfig() 
252     {
253         return this.config;
254     }
255 
256     /***
257     */
258     public DaemonEntry getDaemonEntry() 
259     {
260         return this.entry;
261     }
262     
263     /***
264     Return the status for this Daemon
265 
266     @see Daemon#STATUS_NOT_PROCESSED
267     @see Daemon#STATUS_PROCESSED
268     @see Daemon#STATUS_PROCESSING
269     */
270     public int getStatus() 
271     {
272         return this.status;
273     }
274     
275     /***
276     Set the status for this Daemon
277 
278     @see #STATUS_NOT_PROCESSED
279     @see #STATUS_PROCESSED
280     @see #STATUS_PROCESSING
281     */
282     public void setStatus(int status) 
283     {
284         this.status = status;
285     }
286 
287     /***
288     @see Daemon#getResult()
289     */
290     public int getResult() 
291     {
292         return this.result;
293     }
294 
295     /***
296     @see Daemon#setResult(int result)
297     */
298     public void setResult( int result ) 
299     {
300         this.result = result;
301     }
302     
303     /***
304     @see Daemon#getMessage()
305     */
306     public String getMessage() 
307     {
308         return "Total number of content feeds found: " + getCount();
309     }
310     
311 }