1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.cxf.support;
12
13 import org.mule.api.MuleMessage;
14 import org.mule.api.transformer.TransformerException;
15 import org.mule.module.xml.transformer.DelayedResult;
16 import org.mule.transformer.types.DataTypeFactory;
17 import org.mule.transport.NullPayload;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.Comparator;
22 import java.util.LinkedList;
23 import java.util.List;
24
25 import javax.xml.stream.XMLStreamException;
26 import javax.xml.stream.XMLStreamReader;
27 import javax.xml.stream.XMLStreamWriter;
28 import javax.xml.transform.sax.SAXResult;
29
30 import javanet.staxutils.ContentHandlerToXMLStreamWriter;
31 import org.apache.cxf.databinding.stax.XMLStreamWriterCallback;
32 import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
33 import org.apache.cxf.interceptor.Fault;
34 import org.apache.cxf.message.Message;
35 import org.apache.cxf.message.MessageContentsList;
36 import org.apache.cxf.phase.Phase;
37 import org.apache.cxf.service.model.BindingOperationInfo;
38 import org.apache.cxf.service.model.MessagePartInfo;
39 import org.apache.cxf.staxutils.StaxUtils;
40 import org.xml.sax.SAXException;
41
42 public class OutputPayloadInterceptor extends AbstractOutDatabindingInterceptor
43 {
44
45 public OutputPayloadInterceptor()
46 {
47 super(Phase.PRE_LOGICAL);
48 }
49
50 @SuppressWarnings("unchecked")
51 public void handleMessage(Message message) throws Fault
52 {
53 MessageContentsList objs = MessageContentsList.getContentsList(message);
54 if (objs == null || objs.size() == 0)
55 {
56 return;
57 }
58
59 List<Object> originalParts = (List<Object>) objs.clone();
60
61 objs.clear();
62
63 for (Object o : originalParts)
64 {
65 if (o instanceof MuleMessage)
66 {
67 try
68 {
69 MuleMessage muleMsg = (MuleMessage) o;
70 final Object payload = cleanUpPayload(muleMsg.getPayload());
71
72 if (payload instanceof DelayedResult)
73 {
74 o = getDelayedResultCallback((DelayedResult)payload);
75 }
76 else if (payload instanceof XMLStreamReader)
77 {
78 o = new XMLStreamWriterCallback()
79 {
80 public void write(XMLStreamWriter writer) throws Fault, XMLStreamException
81 {
82 XMLStreamReader xsr = (XMLStreamReader)payload;
83 StaxUtils.copy(xsr, writer);
84 writer.flush();
85 xsr.close();
86 }
87 };
88 }
89 else if (payload instanceof NullPayload)
90 {
91 break;
92 }
93 else
94 {
95 o = muleMsg.getPayload(DataTypeFactory.create(XMLStreamReader.class));
96 }
97
98 objs.add(o);
99 }
100 catch (TransformerException e)
101 {
102 throw new Fault(e);
103 }
104 }
105 else
106 {
107
108 objs.add(o);
109 }
110 }
111
112
113
114 if (!isRequestor(message))
115 {
116 BindingOperationInfo bop = message.getExchange().get(BindingOperationInfo.class);
117 if (bop != null)
118 {
119 ensurePartIndexMatchListIndex(objs, bop.getOutput().getMessageParts());
120 }
121 }
122 }
123
124
125
126
127
128
129
130
131
132
133 protected void ensurePartIndexMatchListIndex(MessageContentsList contentList, List<MessagePartInfo> parts)
134 {
135
136
137
138 List<MessagePartInfo> sortedParts = new LinkedList<MessagePartInfo>();
139 sortedParts.addAll(parts);
140 sortPartsByIndex(sortedParts);
141
142 int currentIndex = 0;
143
144 for (MessagePartInfo part : sortedParts)
145 {
146 while (part.getIndex() > currentIndex)
147 {
148 contentList.add(currentIndex++, null);
149 }
150
151
152 currentIndex = part.getIndex() + 1;
153 }
154 }
155
156 private void sortPartsByIndex(List<MessagePartInfo> parts)
157 {
158 Collections.sort(parts, new Comparator<MessagePartInfo>()
159 {
160
161 public int compare(MessagePartInfo o1, MessagePartInfo o2)
162 {
163 if (o1.getIndex() < o2.getIndex())
164 {
165 return -1;
166 }
167 else if (o1.getIndex() == o2.getIndex())
168 {
169 return 0;
170 }
171 else
172 {
173 return 1;
174 }
175 }
176 });
177 }
178
179 protected Object cleanUpPayload(final Object payload)
180 {
181 final Object cleanedUpPayload;
182 if (payload instanceof Object[])
183 {
184 final Object[] payloadArray = (Object[]) payload;
185 final List<Object> payloadList = new ArrayList<Object>(payloadArray.length);
186 for (Object object : payloadArray)
187 {
188 if (object != null && object != MessageContentsList.REMOVED_MARKER)
189 {
190 payloadList.add(object);
191 }
192 }
193 if (payloadList.size() == payloadArray.length)
194 {
195 cleanedUpPayload = payload;
196 }
197 else
198 {
199 cleanedUpPayload = payloadList.size() == 1 ? payloadList.get(0) : payloadList.toArray();
200 }
201 }
202 else
203 {
204 cleanedUpPayload = payload;
205 }
206 return cleanedUpPayload;
207 }
208
209 protected Object getDelayedResultCallback(final DelayedResult r)
210 {
211 return new XMLStreamWriterCallback()
212 {
213 public void write(XMLStreamWriter writer) throws Fault, XMLStreamException
214 {
215 ContentHandlerToXMLStreamWriter handler = new ContentHandlerToXMLStreamWriter(writer) {
216
217 @Override
218 public void endDocument() throws SAXException
219 {
220 }
221
222 @Override
223 public void processingInstruction(String target, String data) throws SAXException
224 {
225 }
226
227 @Override
228 public void startDocument() throws SAXException
229 {
230 }
231
232 @Override
233 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
234 {
235 }
236
237 };
238
239 try
240 {
241 r.write(new SAXResult(handler));
242 }
243 catch (Exception e)
244 {
245 throw new Fault(e);
246 }
247 }
248 };
249 }
250
251 }