View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.rss.routing;
8   
9   import org.mule.DefaultMuleMessage;
10  import org.mule.api.MessagingException;
11  import org.mule.api.MuleEvent;
12  import org.mule.api.MuleException;
13  import org.mule.api.MuleMessage;
14  import org.mule.api.routing.filter.Filter;
15  import org.mule.api.transformer.TransformerException;
16  import org.mule.module.rss.transformers.ObjectToRssFeed;
17  import org.mule.routing.AbstractSplitter;
18  
19  import com.sun.syndication.feed.synd.SyndEntry;
20  import com.sun.syndication.feed.synd.SyndFeed;
21  
22  import java.util.ArrayList;
23  import java.util.Comparator;
24  import java.util.List;
25  import java.util.Set;
26  import java.util.TreeSet;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  /**
32   * Will split the feed into entries. This message processor also filters out any entries that
33   * are older than the last one read. The filter can be configured with a date from
34   * which to accept feed entries
35   */
36  public class FeedSplitter extends AbstractSplitter
37  {
38      public static final String FEED_PROPERTY = "feed.object";
39  
40      /**
41       * logger used by this class
42       */
43      protected transient final Log logger = LogFactory.getLog(FeedSplitter.class);
44  
45      private Filter entryFilter;
46      private ObjectToRssFeed objectToFeed = new ObjectToRssFeed();
47  
48      public FeedSplitter()
49      {
50          // By default set the filter so that entries are only read once
51          entryFilter = new EntryLastUpdatedFilter(null);
52      }
53  
54      @Override
55      protected List<MuleMessage> splitMessage(MuleEvent event) throws MuleException
56      {
57          List<MuleMessage> messages = new ArrayList<MuleMessage>();
58  
59          if (event.getMessage().getInboundProperty("Content-Length", -1) == 0)
60          {
61              logger.info("Feed has no content, ignoring");
62              return messages;
63          }
64  
65          try
66          {
67              SyndFeed feed = transformToFeed(event);
68  
69              Set<SyndEntry> entries = new TreeSet<SyndEntry>(new EntryComparator());
70              entries.addAll(feed.getEntries());
71  
72              for (SyndEntry entry : entries)
73              {
74                  MuleMessage entryMessage = new DefaultMuleMessage(entry, event.getMuleContext());
75                  if ((entryFilter != null) && !entryFilter.accept(entryMessage))
76                  {
77                      continue;
78                  }
79  
80                  entryMessage.setInvocationProperty(FEED_PROPERTY, feed);
81                  messages.add(entryMessage);
82              }
83              return messages;
84          }
85          catch (MuleException e)
86          {
87              throw new MessagingException(e.getI18nMessage(), event, e);
88          }
89      }
90  
91      protected SyndFeed transformToFeed(MuleEvent event) throws TransformerException
92      {
93          Object payload = event.getMessage().getPayload();
94          if (payload instanceof SyndFeed)
95          {
96              return (SyndFeed) payload;
97          }
98          else
99          {
100             return (SyndFeed) objectToFeed.transform(payload);
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     static 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 }