[abdera-transport-dev] [68] trunk: Added inbound support for filtering and splitting feeds

View: New views
1 Messages — Rating Filter:   Alert me  

[abdera-transport-dev] [68] trunk: Added inbound support for filtering and splitting feeds

by ross-32 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
[68] trunk: Added inbound support for filtering and splitting feeds

Diff

Modified: trunk/pom.xml (67 => 68)

--- trunk/pom.xml	2009-08-04 19:14:24 UTC (rev 67)
+++ trunk/pom.xml	2009-11-05 17:53:42 UTC (rev 68)
@@ -4,7 +4,7 @@
     <artifactId>mule-transport-abdera</artifactId>
     <packaging>jar</packaging>
     <name>Mule Abdera Service Component</name>
-    <version>1.3-M2-SNAPSHOT</version>
+    <version>1.3-SNAPSHOT</version>
     <description>Abdera Service Component for Mule</description>
 
     <properties>
@@ -253,4 +253,4 @@
         <developerConnection>scm:svn:https://svn.muleforge.org/abdera-transport/trunk</developerConnection>
         <url>http://svn.abdera-transport.muleforge.org/</url>
     </scm>
-</project>
\ No newline at end of file
+</project>

Modified: trunk/src/main/java/org/mule/transport/abdera/AbderaNamespaceHandler.java (67 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/AbderaNamespaceHandler.java	2009-08-04 19:14:24 UTC (rev 67)
+++ trunk/src/main/java/org/mule/transport/abdera/AbderaNamespaceHandler.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -14,6 +14,7 @@
 import org.mule.config.spring.parsers.specific.ComponentDefinitionParser;
 import org.mule.config.spring.parsers.specific.TransformerDefinitionParser;
 import org.mule.transport.abdera.transformers.AtomEntryBuilder;
+import org.mule.transport.abdera.filters.URIRouteFilter;
 import org.mule.expression.transformers.ExpressionArgument;
 
 import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

Added: trunk/src/main/java/org/mule/transport/abdera/InboundFeedSplitter.java (0 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/InboundFeedSplitter.java	                        (rev 0)
+++ trunk/src/main/java/org/mule/transport/abdera/InboundFeedSplitter.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -0,0 +1,142 @@
+/*
+ * $Id$
+ * --------------------------------------------------------------------------------------
+ * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
+ *
+ * The software in this package is published under the terms of the CPAL v1.0
+ * license, a copy of which has been included with this distribution in the
+ * LICENSE.txt file.
+ */
+package org.mule.transport.abdera;
+
+import org.mule.DefaultMuleEvent;
+import org.mule.DefaultMuleMessage;
+import org.mule.api.MessagingException;
+import org.mule.api.MuleEvent;
+import org.mule.api.MuleMessage;
+import org.mule.api.routing.InboundRouter;
+import org.mule.api.routing.filter.Filter;
+import org.mule.api.transformer.TransformerException;
+import org.mule.api.transport.PropertyScope;
+import org.mule.routing.AbstractRouter;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
+
+/**
+ * An inbound router that will split a Feed into entries. A filter can be applied to the entires to omit
+ * certain entires, the most common use of this would be to filter out entries that have already been read
+ * by using the {@link org.mule.transport.abdera.filters.EntryLastUpdatedFilter} filter.
+ */
+public class InboundFeedSplitter extends AbstractRouter implements InboundRouter
+{
+    /**
+     * logger used by this class
+     */
+    protected transient final Log logger = LogFactory.getLog(InboundFeedSplitter.class);
+
+    public static final String ATOM_FEED_PROPERTY = "AtomFeed";
+    private Filter entryFilter;
+    private List<String> acceptedContentTypes;
+    private ObjectToFeed objectToFeed = new ObjectToFeed();
+
+    public InboundFeedSplitter()
+    {
+        acceptedContentTypes = new ArrayList<String>();
+        acceptedContentTypes.add("application/atom+xml");
+    }
+
+    public MuleEvent[] process(MuleEvent muleEvent) throws MessagingException
+    {
+        try
+        {
+            Feed feed = (Feed)objectToFeed.transform(muleEvent.getMessage().getPayload());
+            
+            List<MuleEvent> events = new ArrayList<MuleEvent>();
+            //MuleEvent[] events = new MuleEvent[feed.getEntries().size()];
+            Set<Entry> entries = new TreeSet<Entry>(new EntryComparator());
+            entries.addAll(feed.getEntries());
+            for (Entry entry : entries)
+            {
+                MuleMessage m = new DefaultMuleMessage(entry, getMuleContext());
+                if(entryFilter!=null && !entryFilter.accept(m))
+                {
+                    continue;
+                }
+                m.setProperty(ATOM_FEED_PROPERTY, feed, PropertyScope.INVOCATION);
+                MuleEvent e =  new DefaultMuleEvent(m, muleEvent.getEndpoint(), muleEvent.getService(), muleEvent);
+                events.add(e);
+            }
+            return events.toArray(new MuleEvent[]{});
+        }
+        catch (TransformerException e)
+        {
+            throw new MessagingException(e.getI18nMessage() ,muleEvent.getMessage(), e);
+        }
+    }
+
+    public boolean isMatch(MuleEvent muleEvent) throws MessagingException
+    {
+        String contentType = muleEvent.getMessage().getStringProperty("Content-Type", null);
+        if (contentType!=null) 
+        {
+            int i = contentType.indexOf(";");
+            contentType = (i > -1 ? contentType.substring(0, i) : contentType);
+            return acceptedContentTypes.contains(contentType);
+        }
+        else
+        {
+            logger.warn("Content-Type header not set, not accepting the message");
+            return false;
+        }
+    }
+
+    public Filter getEntryFilter()
+    {
+        return entryFilter;
+    }
+
+    public void setEntryFilter(Filter entryFilter)
+    {
+        this.entryFilter = entryFilter;
+    }
+
+    public List<String> getAcceptedContentTypes()
+    {
+        return acceptedContentTypes;
+    }
+
+    public void setAcceptedContentTypes(List<String> acceptedContentTypes)
+    {
+        this.acceptedContentTypes = acceptedContentTypes;
+    }
+
+    class EntryComparator implements Comparator
+    {
+        public int compare(Object o1, Object o2)
+        {
+            Entry e1 = (Entry)o1;
+            Entry e2 = (Entry)o2;
+            if(e1.getPublished().before(e2.getPublished()))
+            {
+                return -1;
+            }
+            else if(e1.equals(e2))
+            {
+                return 0;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+    }
+}
Property changes on: trunk/src/main/java/org/mule/transport/abdera/InboundFeedSplitter.java
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Modified: trunk/src/main/java/org/mule/transport/abdera/ObjectToFeed.java (67 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/ObjectToFeed.java	2009-08-04 19:14:24 UTC (rev 67)
+++ trunk/src/main/java/org/mule/transport/abdera/ObjectToFeed.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -25,7 +25,7 @@
 /**
  * <code>ObjectToInputStream</code> converts serilaizable object to a input stream but
  * treats <code>java.lang.String</code> differently by converting to bytes using
- * the <code>String.getBytrs()</code> method.
+ * the <code>String.getBytes()</code> method.
  */
 public class ObjectToFeed extends AbstractDiscoverableTransformer
 {
@@ -34,25 +34,17 @@
     {
         this.registerSourceType(byte[].class);
         this.registerSourceType(InputStream.class);
-        this.registerSourceType(Object.class);
+        this.registerSourceType(String.class);
         setReturnClass(Feed.class);
     }
 
-    // @Override
+    @Override
     public Object doTransform(Object src, String encoding) throws TransformerException
     {
         try
         {
-//            UMOMessage msg = (UMOMessage) src;
-//            
-//            
-//            InputStream is = (InputStream) msg.getPayload(InputStream.class);
-//            
-//            Document<Element> parse = Abdera.getInstance().getParser().parse(is, encoding);
-//            return parse.getRoot();
-            
             Parser parser = Abdera.getInstance().getParser();
-            Document<Element> doc = null;
+            Document<Element> doc;
             if (src instanceof InputStream)
             {
                 doc = parser.parse((InputStream) src, encoding);
@@ -61,16 +53,12 @@
             {
                 doc = parser.parse(new ByteArrayInputStream((byte[]) src), encoding);
             }
-            else if (src instanceof String)
+            else
             {
                 doc = parser.parse(new StringReader((String) src));
             }
-            else 
-            {
-                // TODO
-                throw new RuntimeException();
-            }
-            
+            //we only need to check for the registered source types
+
             return doc.getRoot();
         }
         catch (Exception e)

Deleted: trunk/src/main/java/org/mule/transport/abdera/URIRouteFilter.java (67 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/URIRouteFilter.java	2009-08-04 19:14:24 UTC (rev 67)
+++ trunk/src/main/java/org/mule/transport/abdera/URIRouteFilter.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -1,49 +0,0 @@
-package org.mule.transport.abdera;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.abdera.i18n.templates.Route;
-import org.mule.api.MuleMessage;
-import org.mule.api.routing.filter.Filter;
-import org.mule.transport.http.HttpConnector;
-
-public class URIRouteFilter implements Filter {
-
-    private Set<String> verbs;
-    private Route route;
-    
-    public URIRouteFilter() {
-        super();
-    }
-
-    public void setRoute(String routePattern) {
-        route = new Route("", routePattern);
-    }
-    
-    public void setVerbs(String verbString) {
-        if (verbString.equals("*")) return;
-        
-        String[] split = verbString.split(" ");
-        verbs = new HashSet<String>();
-        for (String s : split) {
-            verbs.add(s.toUpperCase());
-        }
-    }
-    
-    public void setVerbs(Set<String> verbs) {
-        this.verbs = verbs;
-    }
-
-    public boolean accept(MuleMessage message) {
-        String method = message.getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY, "");
-        if (verbs != null && !verbs.contains(method)) {
-            return false;
-        }
-        
-        String path = message.getStringProperty(HttpConnector.HTTP_REQUEST_PROPERTY, "");
-        
-        return route.match(path);
-    }
-
-}

Added: trunk/src/main/java/org/mule/transport/abdera/filters/EntryLastUpdatedFilter.java (0 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/filters/EntryLastUpdatedFilter.java	                        (rev 0)
+++ trunk/src/main/java/org/mule/transport/abdera/filters/EntryLastUpdatedFilter.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -0,0 +1,105 @@
+/*
+ * $Id$
+ * --------------------------------------------------------------------------------------
+ * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
+ *
+ * The software in this package is published under the terms of the CPAL v1.0
+ * license, a copy of which has been included with this distribution in the
+ * LICENSE.txt file.
+ */
+package org.mule.transport.abdera.filters;
+
+import org.mule.api.MuleMessage;
+import org.mule.api.routing.filter.Filter;
+
+import java.util.Date;
+
+import org.apache.abdera.model.Entry;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Will filter entries in an atom feed based on the lasted Edited date, falling back to the
+ * published date if the edit date was not set
+ */
+public class EntryLastUpdatedFilter implements Filter
+{
+    /**
+     * logger used by this class
+     */
+    private final transient Log logger = LogFactory.getLog(EntryLastUpdatedFilter.class);
+    private Date lastUpdate;
+
+    private boolean acceptWithoutUpdateDate = false;
+
+    public EntryLastUpdatedFilter()
+    {
+    }
+
+    public EntryLastUpdatedFilter(Date lastUpdate)
+    {
+        this.lastUpdate = lastUpdate;
+    }
+
+    public boolean accept(MuleMessage message)
+    {
+        Entry entry = (Entry) message.getPayload();
+        Date updated = entry.getEdited();
+        if (updated == null)
+        {
+            updated = entry.getPublished();
+            if (updated == null)
+            {
+                if (isAcceptWithoutUpdateDate())
+                {
+                    if (logger.isDebugEnabled())
+                    {
+                        logger.debug("Feed does not have a last updated or published date set, assuming the feed should be processed");
+                    }
+                    return true;
+                }
+                else
+                {
+                    if (logger.isWarnEnabled())
+                    {
+                        logger.warn("Feed does not have a last updated or published date set, not consuming the feed because 'acceptWithoutUpdateDate' is false");
+                    }
+                    return false;
+                }
+            }
+        }
+        if (lastUpdate != null)
+        {
+            if (lastUpdate.after(updated) || lastUpdate.equals(updated))
+            {
+                if (logger.isDebugEnabled())
+                {
+                    logger.debug("Feed update is not newer than the last update, not processing");
+                }
+                return false;
+            }
+        }
+        lastUpdate = updated;
+        return true;
+    }
+
+    public boolean isAcceptWithoutUpdateDate()
+    {
+        return acceptWithoutUpdateDate;
+    }
+
+    public void setAcceptWithoutUpdateDate(boolean acceptWithoutUpdateDate)
+    {
+        this.acceptWithoutUpdateDate = acceptWithoutUpdateDate;
+    }
+
+    public Date getLastUpdate()
+    {
+        return lastUpdate;
+    }
+
+    public void setLastUpdate(Date lastUpdate)
+    {
+        this.lastUpdate = lastUpdate;
+    }
+}
Property changes on: trunk/src/main/java/org/mule/transport/abdera/filters/EntryLastUpdatedFilter.java
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Added: trunk/src/main/java/org/mule/transport/abdera/filters/FeedLastUpdatedFilter.java (0 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/filters/FeedLastUpdatedFilter.java	                        (rev 0)
+++ trunk/src/main/java/org/mule/transport/abdera/filters/FeedLastUpdatedFilter.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ * --------------------------------------------------------------------------------------
+ * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
+ *
+ * The software in this package is published under the terms of the CPAL v1.0
+ * license, a copy of which has been included with this distribution in the
+ * LICENSE.txt file.
+ */
+package org.mule.transport.abdera.filters;
+
+import org.mule.api.MuleMessage;
+import org.mule.api.routing.filter.Filter;
+
+import java.util.Date;
+
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Will filter a feed who's update date has changed since the last time it was read.  Some feeds to no update
+ * this value so {@link #setAcceptWithoutUpdateDate(boolean)} can be set to always consume the feed 
+ */
+public class FeedLastUpdatedFilter implements Filter
+{
+    /**
+     * logger used by this class
+     */
+    private final transient Log logger = LogFactory.getLog(FeedLastUpdatedFilter.class);
+    private Date lastUpdate;
+
+    private boolean acceptWithoutUpdateDate = true;
+
+    public FeedLastUpdatedFilter()
+    {
+        //For Spring Xml
+    }
+
+    public FeedLastUpdatedFilter(Date lastUpdate)
+    {
+        this.lastUpdate = lastUpdate;
+    }
+
+    public boolean accept(MuleMessage message)
+    {
+        Feed feed = (Feed) message.getPayload();
+        Date updated = feed.getUpdated();
+        if (updated == null)
+        {
+            if(isAcceptWithoutUpdateDate())
+            {
+                if (logger.isDebugEnabled())
+                {
+                    logger.debug("Feed does not have a last updated or published date set, assuming the feed should be processed");
+                }
+                return true;
+            }
+            else
+            {
+                if (logger.isWarnEnabled())
+                {
+                    logger.warn("Feed does not have a last updated or published date set, not consuming the feed because 'acceptWithoutUpdateDate' is false");
+                }
+                return false;
+            }
+        }
+
+        if (lastUpdate != null)
+        {
+            if (lastUpdate.after(updated) || lastUpdate.equals(updated))
+            {
+                if (logger.isDebugEnabled())
+                {
+                    logger.debug("Feed update is not newer than the last update, not processing");
+                }
+                return false;
+            }
+        }
+        lastUpdate = updated;
+        return true;
+    }
+
+    public boolean isAcceptWithoutUpdateDate()
+    {
+        return acceptWithoutUpdateDate;
+    }
+
+    public void setAcceptWithoutUpdateDate(boolean acceptWithoutUpdateDate)
+    {
+        this.acceptWithoutUpdateDate = acceptWithoutUpdateDate;
+    }
+
+    public Date getLastUpdate()
+    {
+        return lastUpdate;
+    }
+
+    public void setLastUpdate(Date lastUpdate)
+    {
+        this.lastUpdate = lastUpdate;
+    }
+}
\ No newline at end of file
Property changes on: trunk/src/main/java/org/mule/transport/abdera/filters/FeedLastUpdatedFilter.java
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:eol-style
   + native

Copied: trunk/src/main/java/org/mule/transport/abdera/filters/URIRouteFilter.java (from rev 57, trunk/src/main/java/org/mule/transport/abdera/URIRouteFilter.java) (0 => 68)

--- trunk/src/main/java/org/mule/transport/abdera/filters/URIRouteFilter.java	                        (rev 0)
+++ trunk/src/main/java/org/mule/transport/abdera/filters/URIRouteFilter.java	2009-11-05 17:53:42 UTC (rev 68)
@@ -0,0 +1,49 @@
+package org.mule.transport.abdera.filters;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.abdera.i18n.templates.Route;
+import org.mule.api.MuleMessage;
+import org.mule.api.routing.filter.Filter;
+import org.mule.transport.http.HttpConnector;
+
+public class URIRouteFilter implements Filter {
+
+    private Set<String> verbs;
+    private Route route;
+    
+    public URIRouteFilter() {
+        super();
+    }
+
+    public void setRoute(String routePattern) {
+        route = new Route("", routePattern);
+    }
+    
+    public void setVerbs(String verbString) {
+        if (verbString.equals("*")) return;
+        
+        String[] split = verbString.split(" ");
+        verbs = new HashSet<String>();
+        for (String s : split) {
+            verbs.add(s.toUpperCase());
+        }
+    }
+    
+    public void setVerbs(Set<String> verbs) {
+        this.verbs = verbs;
+    }
+
+    public boolean accept(MuleMessage message) {
+        String method = message.getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY, "");
+        if (verbs != null && !verbs.contains(method)) {
+            return false;
+        }
+        
+        String path = message.getStringProperty(HttpConnector.HTTP_REQUEST_PROPERTY, "");
+        
+        return route.match(path);
+    }
+
+}

Property changes: trunk/src/main/java/org/mule/transport/abdera/filters/URIRouteFilter.java

Name: svn:executable
   + *
Name: svn:keywords
   + Rev Date
Name: svn:eol-style
   + native


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "MuleForge Dev" group.
To post to this group, send email to muleforgedev@...
To unsubscribe from this group, send email to muleforgedev+unsubscribe@...
For more options, visit this group at http://groups.google.com/group/muleforgedev?hl=en
-~----------~----~----~----~------~----~------~--~---
--------------------------------------------------------------------- To unsubscribe from this list, please visit: http://admin.muleforge.org/manage_email