Coverage Report - org.mule.module.sxc.SxcFilteringOutboundRouter
 
Classes in this File Line Coverage Branch Coverage Complexity
SxcFilteringOutboundRouter
0%
0/71
0%
0/24
0
 
 1  
 /*
 2  
  * $Id: SxcFilteringOutboundRouter.java 19661 2010-09-16 12:34:01Z tcarlson $
 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  
 
 11  
 package org.mule.module.sxc;
 12  
 
 13  
 import org.mule.api.DefaultMuleException;
 14  
 import org.mule.api.MuleContext;
 15  
 import org.mule.api.MuleException;
 16  
 import org.mule.api.MuleMessage;
 17  
 import org.mule.api.expression.ExpressionRuntimeException;
 18  
 import org.mule.api.registry.RegistrationException;
 19  
 import org.mule.api.routing.filter.Filter;
 20  
 import org.mule.api.transformer.TransformerException;
 21  
 import org.mule.config.i18n.CoreMessages;
 22  
 import org.mule.module.xml.stax.ReversibleXMLStreamReader;
 23  
 import org.mule.module.xml.transformer.XmlToXMLStreamReader;
 24  
 import org.mule.module.xml.util.NamespaceManager;
 25  
 import org.mule.routing.filters.logic.AndFilter;
 26  
 import org.mule.routing.filters.logic.NotFilter;
 27  
 import org.mule.routing.filters.logic.OrFilter;
 28  
 import org.mule.routing.outbound.FilteringOutboundRouter;
 29  
 
 30  
 import com.envoisolutions.sxc.xpath.XPathBuilder;
 31  
 import com.envoisolutions.sxc.xpath.XPathEvaluator;
 32  
 
 33  
 import java.util.HashMap;
 34  
 import java.util.Iterator;
 35  
 import java.util.Map;
 36  
 
 37  
 /**
 38  
  * <code>FilteringRouter</code> is a router that accepts events based on a filter
 39  
  * set.
 40  
  */
 41  
 
 42  0
 public class SxcFilteringOutboundRouter extends FilteringOutboundRouter
 43  
 {
 44  0
     private final static ThreadLocal<MuleMessage> messages = new ThreadLocal<MuleMessage>();
 45  0
     private final static XmlToXMLStreamReader transformer = new XmlToXMLStreamReader();
 46  
 
 47  
     static
 48  
     {
 49  0
         transformer.setReversible(true);
 50  0
     }
 51  
 
 52  
     private Map<String, String> namespaces;
 53  
     private XPathEvaluator evaluator;
 54  
 
 55  
     private XPathBuilder builder;
 56  
 
 57  
     private NamespaceManager namespaceManager;
 58  
 
 59  
     @Override
 60  
     public void setMuleContext(MuleContext context)
 61  
     {
 62  0
         this.muleContext = context;
 63  
         try
 64  
         {
 65  0
             namespaceManager = muleContext.getRegistry().lookupObject(NamespaceManager.class);
 66  
         }
 67  0
         catch (RegistrationException e)
 68  
         {
 69  0
             throw new ExpressionRuntimeException(CoreMessages.failedToLoad("NamespaceManager"), e);
 70  0
         }
 71  
         
 72  0
         if (namespaceManager != null)
 73  
         {
 74  0
             if (namespaces == null)
 75  
             {
 76  0
                 namespaces = new HashMap(namespaceManager.getNamespaces());
 77  
             }
 78  
             else
 79  
             {
 80  0
                 namespaces.putAll(namespaceManager.getNamespaces());
 81  
             }
 82  
         }
 83  0
     }
 84  
 
 85  
     @Override
 86  
     public void setFilter(Filter filter)
 87  
     {
 88  0
         super.setFilter(filter);
 89  0
     }
 90  
 
 91  
     protected void addEventHandlers(XPathBuilder builder, Filter filter)
 92  
     {
 93  0
         if (filter instanceof SxcFilter)
 94  
         {
 95  0
             SxcFilter sxcFilter = ((SxcFilter) filter);
 96  0
             sxcFilter.addEventHandler(this, builder);
 97  0
         }
 98  0
         else if (filter instanceof AndFilter)
 99  
         {
 100  0
             AndFilter f = (AndFilter) filter;
 101  
 
 102  0
             for (Iterator<?> itr = f.getFilters().iterator(); itr.hasNext();)
 103  
             {
 104  0
                 addEventHandlers(builder, (Filter) itr.next());
 105  
             }
 106  0
         }
 107  0
         else if (filter instanceof OrFilter)
 108  
         {
 109  0
             OrFilter f = (OrFilter) filter;
 110  
 
 111  0
             for (Iterator<?> itr = f.getFilters().iterator(); itr.hasNext();)
 112  
             {
 113  0
                 addEventHandlers(builder, (Filter) itr.next());
 114  
             }
 115  0
         }
 116  0
         else if (filter instanceof NotFilter)
 117  
         {
 118  0
             NotFilter f = (NotFilter) filter;
 119  
 
 120  0
             addEventHandlers(builder, f.getFilter());
 121  0
         }
 122  
         else
 123  
         {
 124  0
             logger.warn("Filter type " + filter.getClass().toString()
 125  
                            + " is not recognized by the SXC router. If it contains child "
 126  
                            + "SXC filters it will not work correctly.");
 127  
         }
 128  0
     }
 129  
 
 130  
     protected void initialize() throws Exception
 131  
     {
 132  0
         if (evaluator == null)
 133  
         {
 134  0
             doInitialize();
 135  
         }
 136  0
     }
 137  
 
 138  
     private synchronized void doInitialize()
 139  
     {
 140  0
         if (evaluator == null)
 141  
         {
 142  0
             builder = new XPathBuilder();
 143  0
             builder.setNamespaceContext(namespaces);
 144  0
             addEventHandlers(builder, getFilter());
 145  
 
 146  0
             evaluator = builder.compile();
 147  
         }
 148  0
     }
 149  
 
 150  
     @Override
 151  
     public boolean isMatch(MuleMessage message) throws MuleException
 152  
     {
 153  0
         ReversibleXMLStreamReader reader = null;
 154  
         try
 155  
         {
 156  0
             initialize();
 157  0
             messages.set(message);
 158  
 
 159  0
             reader = getXMLStreamReader(message);
 160  0
             reader.setTracking(true);
 161  0
             evaluator.evaluate(reader);
 162  
         }
 163  0
         catch (StopProcessingException e)
 164  
         {
 165  
             // stop processing
 166  
         }
 167  0
         catch (Exception e)
 168  
         {
 169  0
             throw new DefaultMuleException(e);
 170  
         }
 171  
         finally
 172  
         {
 173  0
             messages.set(null);
 174  
 
 175  0
             if (reader != null)
 176  
             {
 177  0
                 reader.setTracking(false);
 178  0
                 reader.reset();
 179  
             }
 180  
         }
 181  
 
 182  
         try
 183  
         {
 184  0
             return testMatch(message);
 185  
         }
 186  0
         catch (UndefinedMatchException m)
 187  
         {
 188  0
             return false;
 189  
         }
 190  
     }
 191  
 
 192  
     public boolean testMatch(MuleMessage message) throws MuleException
 193  
     {
 194  0
         return super.isMatch(message);
 195  
     }
 196  
 
 197  
     /**
 198  
      * Gets an XMLStreamReader for this message.
 199  
      * 
 200  
      * @param message
 201  
      * @throws TransformerException
 202  
      */
 203  
     protected ReversibleXMLStreamReader getXMLStreamReader(MuleMessage message) throws TransformerException
 204  
     {
 205  0
          ReversibleXMLStreamReader r = (ReversibleXMLStreamReader) transformer.transform(message);
 206  
          
 207  0
          if (r != message.getPayload())
 208  
          {
 209  0
              message.setPayload(r);
 210  
          }
 211  0
          return r;
 212  
     }
 213  
 
 214  
     public Map<String, String> getNamespaces()
 215  
     {
 216  0
         return namespaces;
 217  
     }
 218  
 
 219  
     public void setNamespaces(Map<String, String> namespaces)
 220  
     {
 221  0
         this.namespaces = namespaces;
 222  0
     }
 223  
 
 224  
     public static MuleMessage getCurrentMessage()
 225  
     {
 226  0
         return messages.get();
 227  
     }
 228  
 }