View Javadoc

1   /*
2    * $Id: AbstractMessageProcessorChain.java 23018 2011-09-22 18:48:45Z pablo.lagreca $
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.processor.chain;
12  
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleException;
15  import org.mule.api.construct.FlowConstruct;
16  import org.mule.api.construct.FlowConstructAware;
17  import org.mule.api.context.MuleContextAware;
18  import org.mule.api.endpoint.ImmutableEndpoint;
19  import org.mule.api.lifecycle.Disposable;
20  import org.mule.api.lifecycle.Initialisable;
21  import org.mule.api.lifecycle.InitialisationException;
22  import org.mule.api.lifecycle.Lifecycle;
23  import org.mule.api.lifecycle.Startable;
24  import org.mule.api.lifecycle.Stoppable;
25  import org.mule.api.processor.MessageProcessor;
26  import org.mule.api.processor.MessageProcessorChain;
27  import org.mule.endpoint.EndpointAware;
28  import org.mule.processor.AbstractInterceptingMessageProcessor;
29  import org.mule.util.StringUtils;
30  
31  import java.util.Iterator;
32  import java.util.List;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  /**
38   * Builder needs to return a composite rather than the first MessageProcessor in the chain. This is so that if
39   * this chain is nested in another chain the next MessageProcessor in the parent chain is not injected into
40   * the first in the nested chain.
41   */
42  public abstract class AbstractMessageProcessorChain extends AbstractInterceptingMessageProcessor
43                                                      implements MessageProcessorChain, Lifecycle, FlowConstructAware, MuleContextAware, EndpointAware
44  {
45      protected final transient Log log = LogFactory.getLog(getClass());
46      protected String name;
47      protected List<MessageProcessor> processors;
48  
49      public AbstractMessageProcessorChain(String name, List<MessageProcessor> processors)
50      {
51          this.name = name;
52          this.processors = processors;
53      }
54  
55      public MuleEvent process(MuleEvent event) throws MuleException
56      {
57          if (log.isDebugEnabled())
58          {
59              log.debug(String.format("Invoking %s with event %s", this, event));
60          }
61          if (event == null)
62          {
63              return null;
64          }
65  
66          MuleEvent result = doProcess(event);
67          return processNext(result);
68      }
69  
70      protected abstract MuleEvent doProcess(MuleEvent event) throws MuleException;
71  
72      public void initialise() throws InitialisationException
73      {
74          for (MessageProcessor processor : processors)
75          {
76              // MULE-5002 TODO review MP Lifecycle
77              if (processor instanceof Initialisable /* && !(processor instanceof Transformer) */)
78              {
79                  ((Initialisable) processor).initialise();
80              }
81          }
82      }
83  
84      public void start() throws MuleException
85      {
86          for (MessageProcessor processor : processors)
87          {
88              if (processor instanceof Startable)
89              {
90                  ((Startable) processor).start();
91              }
92          }
93      }
94  
95      public void stop() throws MuleException
96      {
97          for (MessageProcessor processor : processors)
98          {
99              if (processor instanceof Stoppable)
100             {
101                 ((Stoppable) processor).stop();
102             }
103         }
104     }
105 
106     public void dispose()
107     {
108         for (MessageProcessor processor : processors)
109         {
110             if (processor instanceof Disposable)
111             {
112                 ((Disposable) processor).dispose();
113             }
114         }
115         processors.clear();
116     }
117 
118     public void setFlowConstruct(FlowConstruct flowConstruct)
119     {
120         for (MessageProcessor processor : processors)
121         {
122             if (processor instanceof FlowConstructAware)
123             {
124                 ((FlowConstructAware) processor).setFlowConstruct(flowConstruct);
125             }
126         }
127     }
128 
129     public String getName()
130     {
131         return name;
132     }
133 
134     @Override
135     public String toString()
136     {
137         StringBuilder string = new StringBuilder();
138         string.append(getClass().getSimpleName());
139         if (StringUtils.isNotBlank(name))
140         {
141             string.append(String.format(" '%s' ", name));
142         }
143 
144         Iterator<MessageProcessor> mpIterator = processors.iterator();
145 
146         final String nl = String.format("%n");
147 
148         // TODO have it print the nested structure with indents increasing for nested MPCs
149         if (mpIterator.hasNext())
150         {
151             string.append(String.format("%n[ "));
152             while (mpIterator.hasNext())
153             {
154                 MessageProcessor mp = mpIterator.next();
155                 final String indented = StringUtils.replace(mp.toString(), nl, String.format("%n  "));
156                 string.append(String.format("%n  %s", indented));
157                 if (mpIterator.hasNext())
158                 {
159                     string.append(", ");
160                 }
161             }
162             string.append(String.format("%n]"));
163         }
164 
165         return string.toString();
166     }
167 
168     public void setEndpoint(ImmutableEndpoint endpoint)
169     {
170         for (MessageProcessor processor : processors)
171         {
172             if (processor instanceof EndpointAware)
173             {
174                  ((EndpointAware) processor).setEndpoint(endpoint);
175             }
176         }
177     }
178 
179     public List<MessageProcessor> getMessageProcessors()
180     {
181         return processors;
182     }
183 
184 }