View Javadoc

1   /*
2    * $Id: FeedSplitter.java 19359 2010-09-03 20:03:08Z rossmason $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  package org.mule.module.rss.routing;
11  
12  import org.mule.DefaultMuleMessage;
13  import org.mule.api.MessagingException;
14  import org.mule.api.MuleEvent;
15  import org.mule.api.MuleException;
16  import org.mule.api.MuleMessage;
17  import org.mule.api.routing.filter.Filter;
18  import org.mule.api.transport.PropertyScope;
19  import org.mule.module.rss.transformers.ObjectToRssFeed;
20  import org.mule.routing.AbstractSplitter;
21  
22  import com.sun.syndication.feed.synd.SyndEntry;
23  import com.sun.syndication.feed.synd.SyndFeed;
24  
25  import java.util.ArrayList;
26  import java.util.Comparator;
27  import java.util.List;
28  import java.util.Set;
29  import java.util.TreeSet;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  
34  /**
35   * Will split the feed into entries.  This router also filters out any entries that are older than the last one read
36   * The filter can be configured with a date from which to accept feed entries
37   */
38  public class FeedSplitter extends AbstractSplitter
39  {
40      /**
41       * logger used by this class
42       */
43      protected transient final Log logger = LogFactory.getLog(FeedSplitter.class);
44  
45      public static final String FEED_PROPERTY = "feed.object";
46      private Filter entryFilter;
47      private ObjectToRssFeed objectToFeed = new ObjectToRssFeed();
48  
49      public FeedSplitter()
50      {
51          //By default set the filter so that entries are only read once
52          entryFilter = new EntryLastUpdatedFilter(null);
53      }
54  
55      @Override
56      protected List<MuleMessage> splitMessage(MuleEvent event) throws MuleException
57      {
58          //TODO MULE-5048, should not need to set this manually
59          setMuleContext(event.getMuleContext());
60  
61          List<MuleMessage> messages = new ArrayList<MuleMessage>();
62          if(event.getMessage().getInboundProperty("Content-Length", -1) == 0)
63          {
64              logger.info("Feed has no content, ignoring");
65              return messages;
66          }
67  
68          try
69          {
70              Object payload = event.getMessage().getPayload();
71              
72              SyndFeed feed;
73              if (payload instanceof SyndFeed)
74              {
75                  feed = (SyndFeed) payload;
76              }
77              else
78              {
79                  feed = (SyndFeed) objectToFeed.transform(event.getMessage().getPayload());
80              }
81              
82              Set<SyndEntry> entries = new TreeSet<SyndEntry>(new EntryComparator());
83              entries.addAll(feed.getEntries());
84  
85              for (SyndEntry entry : entries)
86              {
87                  MuleMessage m = new DefaultMuleMessage(entry, event.getMuleContext());
88                  if (entryFilter != null && !entryFilter.accept(m))
89                  {
90                      continue;
91                  }
92                  m.setProperty(FEED_PROPERTY, feed, PropertyScope.INVOCATION);
93                  messages.add(m);
94              }
95              return messages;
96  
97          }
98          catch (MuleException e)
99          {
100             throw new MessagingException(e.getI18nMessage(), event, e);
101         }
102     }
103 
104     public Filter getEntryFilter()
105     {
106         return entryFilter;
107     }
108 
109     public void setEntryFilter(Filter entryFilter)
110     {
111         this.entryFilter = entryFilter;
112     }
113     
114     class EntryComparator implements Comparator<SyndEntry>
115     {
116         public int compare(SyndEntry e1, SyndEntry e2)
117         {
118             if (e1.getPublishedDate().before(e2.getPublishedDate()))
119             {
120                 return -1;
121             }
122             else if (e1.equals(e2))
123             {
124                 return 0;
125             }
126             else
127             {
128                 return 1;
129             }
130         }
131     }
132 }