Coverage Report - org.mule.source.StartableCompositeMessageSource
 
Classes in this File Line Coverage Branch Coverage Complexity
StartableCompositeMessageSource
0%
0/73
0%
0/40
0
StartableCompositeMessageSource$InternalMessageProcessor
0%
0/7
0%
0/4
0
 
 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.source;
 8  
 
 9  
 import org.mule.api.MuleEvent;
 10  
 import org.mule.api.MuleException;
 11  
 import org.mule.api.construct.FlowConstruct;
 12  
 import org.mule.api.construct.FlowConstructAware;
 13  
 import org.mule.api.lifecycle.Disposable;
 14  
 import org.mule.api.lifecycle.Initialisable;
 15  
 import org.mule.api.lifecycle.InitialisationException;
 16  
 import org.mule.api.lifecycle.Lifecycle;
 17  
 import org.mule.api.lifecycle.LifecycleException;
 18  
 import org.mule.api.lifecycle.Startable;
 19  
 import org.mule.api.lifecycle.Stoppable;
 20  
 import org.mule.api.processor.MessageProcessor;
 21  
 import org.mule.api.source.CompositeMessageSource;
 22  
 import org.mule.api.source.MessageSource;
 23  
 import org.mule.config.i18n.CoreMessages;
 24  
 import org.mule.util.ObjectUtils;
 25  
 
 26  
 import java.util.ArrayList;
 27  
 import java.util.Collections;
 28  
 import java.util.List;
 29  
 
 30  
 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
 31  
 
 32  
 import org.apache.commons.logging.Log;
 33  
 import org.apache.commons.logging.LogFactory;
 34  
 
 35  
 /**
 36  
  * Implementation of {@link CompositeMessageSource} that propagates both injection of {@link FlowConstruct}
 37  
  * and lifecycle to nested {@link MessageSource}s.
 38  
  * <p>
 39  
  * <li>This message source cannot be started without a listener set.
 40  
  * <li>If sources are added when this composie is started they will be started as well.
 41  
  * <li>If a {@link MessageSource} is started in isolation when composite is stopped then messages will be
 42  
  * lost.
 43  
  * <li>Message will only be received from endpoints if the connector is also started.
 44  
  */
 45  0
 public class StartableCompositeMessageSource
 46  
     implements CompositeMessageSource, Lifecycle, FlowConstructAware
 47  
 {
 48  0
     protected static final Log log = LogFactory.getLog(StartableCompositeMessageSource.class);
 49  
 
 50  
     protected MessageProcessor listener;
 51  0
     protected AtomicBoolean initialised = new AtomicBoolean(false);
 52  0
     protected AtomicBoolean started = new AtomicBoolean(false);
 53  0
     protected final List<MessageSource> sources = Collections.synchronizedList(new ArrayList<MessageSource>());
 54  0
     protected AtomicBoolean starting = new AtomicBoolean(false);
 55  
     protected FlowConstruct flowConstruct;
 56  0
     private final MessageProcessor internalListener = new InternalMessageProcessor();
 57  
 
 58  
     public void addSource(MessageSource source) throws MuleException
 59  
     {
 60  0
         synchronized (sources)
 61  
         {
 62  0
             sources.add(source);
 63  0
         }
 64  0
         source.setListener(internalListener);
 65  0
         if (initialised.get())
 66  
         {
 67  0
             if (source instanceof FlowConstructAware)
 68  
             {
 69  0
                 ((FlowConstructAware) source).setFlowConstruct(flowConstruct);
 70  
             }
 71  0
             if (source instanceof Initialisable)
 72  
             {
 73  0
                 ((Initialisable) source).initialise();
 74  
             }
 75  
         }
 76  0
         if (started.get() && source instanceof Startable)
 77  
         {
 78  0
             ((Startable) source).start();
 79  
         }
 80  0
     }
 81  
 
 82  
     public void removeSource(MessageSource source) throws MuleException
 83  
     {
 84  0
         if (started.get())
 85  
         {
 86  0
             if (source instanceof Stoppable)
 87  
             {
 88  0
                 ((Stoppable) source).stop();
 89  
             }
 90  0
             if (source instanceof Disposable)
 91  
             {
 92  0
                 ((Disposable) source).dispose();
 93  
             }
 94  
         }
 95  0
         synchronized (sources)
 96  
         {
 97  0
             sources.remove(source);
 98  0
         }
 99  0
     }
 100  
     
 101  
     public void setMessageSources(List<MessageSource> sources) throws MuleException
 102  
     {
 103  0
         this.sources.clear();
 104  0
         for (MessageSource messageSource : sources)
 105  
         {
 106  0
             addSource(messageSource);
 107  
         }
 108  0
     }
 109  
     
 110  
     public void initialise() throws InitialisationException
 111  
     {
 112  0
         if (listener == null)
 113  
         {
 114  0
             throw new InitialisationException(CoreMessages.objectIsNull("listener"), this);
 115  
         }
 116  0
         synchronized (sources)
 117  
         {
 118  0
             for (MessageSource source : sources)
 119  
             {
 120  0
                 if (source instanceof FlowConstructAware)
 121  
                 {
 122  0
                     ((FlowConstructAware) source).setFlowConstruct(flowConstruct);
 123  
                 }
 124  0
                 if (source instanceof Initialisable)
 125  
                 {
 126  0
                     ((Initialisable) source).initialise();
 127  
                 }
 128  
             }
 129  0
         }
 130  0
         initialised.set(true);
 131  0
     }
 132  
 
 133  
     public void start() throws MuleException
 134  
     {
 135  0
         if (listener == null)
 136  
         {
 137  0
             throw new LifecycleException(CoreMessages.objectIsNull("listener"), this);
 138  
         }
 139  
 
 140  0
         synchronized (sources)
 141  
         {
 142  0
             starting.set(true);
 143  0
             for (MessageSource source : sources)
 144  
             {
 145  0
                 if (source instanceof Startable)
 146  
                 {
 147  0
                     ((Startable) source).start();
 148  
                 }
 149  
             }
 150  
 
 151  0
             started.set(true);
 152  0
             starting.set(false);
 153  0
         }
 154  0
     }
 155  
 
 156  
     public void stop() throws MuleException
 157  
     {
 158  0
         synchronized (sources)
 159  
         {
 160  0
             for (MessageSource source : sources)
 161  
             {
 162  0
                 if (source instanceof Stoppable)
 163  
                 {
 164  0
                     ((Stoppable) source).stop();
 165  
                 }
 166  
             }
 167  
 
 168  0
             started.set(false);
 169  0
         }
 170  0
     }
 171  
     
 172  
     public void dispose()
 173  
     {
 174  0
         synchronized (sources)
 175  
         {
 176  0
             for (MessageSource source : sources)
 177  
             {
 178  0
                 if (source instanceof Disposable)
 179  
                 {
 180  0
                     ((Disposable) source).dispose();
 181  
                 }
 182  
             }
 183  0
         }
 184  0
     }
 185  
 
 186  
     public void setListener(MessageProcessor listener)
 187  
     {
 188  0
         this.listener = listener;
 189  0
     }
 190  
 
 191  
     public void setFlowConstruct(FlowConstruct pattern)
 192  
     {
 193  0
         this.flowConstruct = pattern;
 194  
 
 195  0
     }
 196  
 
 197  
     @Override
 198  
     public String toString()
 199  
     {
 200  0
         return String.format("%s [listener=%s, sources=%s, started=%s]", getClass().getSimpleName(),
 201  
             listener, sources, started);
 202  
     }
 203  
 
 204  0
     private class InternalMessageProcessor implements MessageProcessor
 205  
     {
 206  
         public InternalMessageProcessor()
 207  0
         {
 208  0
             super();
 209  0
         }
 210  
 
 211  
         public MuleEvent process(MuleEvent event) throws MuleException
 212  
         {
 213  0
             if (started.get() || starting.get())
 214  
             {
 215  0
                 return listener.process(event);
 216  
             }
 217  
             else
 218  
             {
 219  
                 // TODO i18n
 220  0
                 throw new IllegalStateException(String.format(
 221  
                     "A message was receieved from MessageSource, but CompositeMessageSource is stopped.%n"
 222  
                                     + "  Message: %s%n" + "  CompositeMessageSource: %s", event, this));
 223  
             }
 224  
         }
 225  
 
 226  
         @Override
 227  
         public String toString()
 228  
         {
 229  0
             return ObjectUtils.toString(this);
 230  
         }
 231  
     }
 232  
 }