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