Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
AbstractMessageSplitter |
|
| 0.0;0 |
1 | /* | |
2 | * $Id: AbstractMessageSplitter.java 19191 2010-08-25 21:05:23Z 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.routing.outbound; | |
12 | ||
13 | import org.mule.DefaultMuleMessage; | |
14 | import org.mule.api.MuleEvent; | |
15 | import org.mule.api.MuleException; | |
16 | import org.mule.api.MuleMessage; | |
17 | import org.mule.api.processor.MessageProcessor; | |
18 | import org.mule.api.processor.MessageRouter; | |
19 | import org.mule.api.routing.CouldNotRouteOutboundMessageException; | |
20 | import org.mule.api.routing.RoutingException; | |
21 | import org.mule.routing.CorrelationMode; | |
22 | ||
23 | import java.util.ArrayList; | |
24 | import java.util.HashMap; | |
25 | import java.util.List; | |
26 | import java.util.Map; | |
27 | ||
28 | /** | |
29 | * <code>AbstractMessageSplitter</code> is an outbound Message Splitter used to split | |
30 | * the contents of a received message into sub parts that can be processed by other | |
31 | * components. Each Part is fired as a separate event to each endpoint on the router. The | |
32 | * targets can have filters on them to receive only certain message parts. | |
33 | */ | |
34 | 0 | public abstract class AbstractMessageSplitter extends FilteringOutboundRouter implements MessageRouter |
35 | { | |
36 | @Override | |
37 | public MuleEvent route(MuleEvent event) throws RoutingException | |
38 | { | |
39 | 0 | MuleMessage message = event.getMessage(); |
40 | ||
41 | 0 | String correlationId = event.getFlowConstruct().getMessageInfoMapping().getCorrelationId(message); |
42 | ||
43 | 0 | List<MuleEvent> results = new ArrayList<MuleEvent>(); |
44 | 0 | int correlationSequence = 1; |
45 | 0 | SplitMessage splitMessage = getMessageParts(message, getRoutes()); |
46 | ||
47 | // Cache the properties here because for some message types getting the | |
48 | // properties can be expensive | |
49 | 0 | Map props = new HashMap(); |
50 | 0 | for (String propertyKey : message.getOutboundPropertyNames()) |
51 | { | |
52 | 0 | Object value = message.getOutboundProperty(propertyKey); |
53 | 0 | if (value != null) |
54 | { | |
55 | 0 | props.put(propertyKey, value); |
56 | } | |
57 | 0 | } |
58 | ||
59 | 0 | for (int i = 0; i < splitMessage.size(); i++) |
60 | { | |
61 | 0 | SplitMessage.MessagePart part = splitMessage.getPart(i); |
62 | ||
63 | MuleMessage sendMessage; | |
64 | 0 | if (part.getPart() instanceof MuleMessage) |
65 | { | |
66 | 0 | sendMessage = (MuleMessage) part.getPart(); |
67 | } | |
68 | else | |
69 | { | |
70 | 0 | sendMessage = new DefaultMuleMessage(part.getPart(), props, muleContext); |
71 | } | |
72 | ||
73 | try | |
74 | { | |
75 | 0 | if (enableCorrelation != CorrelationMode.NEVER) |
76 | { | |
77 | 0 | boolean correlationSet = message.getCorrelationId() != null; |
78 | 0 | if (!correlationSet && (enableCorrelation == CorrelationMode.IF_NOT_SET)) |
79 | { | |
80 | 0 | sendMessage.setCorrelationId(correlationId); |
81 | } | |
82 | ||
83 | // take correlation group size from the message properties, set by concrete | |
84 | // message splitter implementations | |
85 | 0 | sendMessage.setCorrelationGroupSize(splitMessage.size()); |
86 | 0 | sendMessage.setCorrelationSequence(correlationSequence++); |
87 | } | |
88 | ||
89 | 0 | if (part.getEndpoint().getExchangePattern().hasResponse()) |
90 | { | |
91 | 0 | results.add(sendRequest(event, sendMessage, part.getEndpoint(), true)); |
92 | } | |
93 | else | |
94 | { | |
95 | 0 | sendRequest(event, sendMessage, part.getEndpoint(), false); |
96 | } | |
97 | } | |
98 | 0 | catch (MuleException e) |
99 | { | |
100 | 0 | throw new CouldNotRouteOutboundMessageException(event, part.getEndpoint(), e); |
101 | 0 | } |
102 | } | |
103 | ||
104 | 0 | return resultsHandler.aggregateResults(results, event, muleContext); |
105 | } | |
106 | ||
107 | ||
108 | /** | |
109 | * Implementing classes should create a {@link org.mule.routing.outbound.SplitMessage} instance and for | |
110 | * each part can associate an endpoint. | |
111 | * Note that No state should be stored on the router itself. The {@link SplitMessage} provides the parts and | |
112 | * endpoint mapping info in order for the correct dispatching to occur. | |
113 | * <p/> | |
114 | * If users do not want to associate a message part with an endpoint, but just dispatch parts over the targets in | |
115 | * a round-robin way, they should use the {@link org.mule.routing.outbound.AbstractRoundRobinMessageSplitter} instead. | |
116 | * | |
117 | * @param message the current message being processed | |
118 | * @param endpoints A list of {@link org.mule.api.endpoint.OutboundEndpoint} that will be used to dispatch each of the parts | |
119 | * @return a {@link org.mule.routing.outbound.SplitMessage} instance that contains the message parts and the | |
120 | * endpoint to associate with the message part. | |
121 | * @see org.mule.routing.outbound.SplitMessage | |
122 | * @see org.mule.routing.outbound.AbstractRoundRobinMessageSplitter | |
123 | */ | |
124 | protected abstract SplitMessage getMessageParts(MuleMessage message, List <MessageProcessor> endpoints); | |
125 | ||
126 | } |