001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.jbi.messaging;
018
019 import java.io.ByteArrayInputStream;
020 import java.io.ByteArrayOutputStream;
021 import java.io.Externalizable;
022 import java.io.IOException;
023 import java.io.ObjectInput;
024 import java.io.ObjectInputStream;
025 import java.io.ObjectOutput;
026 import java.io.ObjectOutputStream;
027 import java.net.URI;
028 import java.util.Collections;
029 import java.util.HashMap;
030 import java.util.Map;
031 import java.util.Set;
032
033 import javax.jbi.messaging.ExchangeStatus;
034 import javax.jbi.messaging.Fault;
035 import javax.jbi.messaging.MessagingException;
036 import javax.jbi.messaging.NormalizedMessage;
037 import javax.jbi.servicedesc.ServiceEndpoint;
038 import javax.transaction.Transaction;
039 import javax.xml.namespace.QName;
040
041 import org.apache.servicemix.components.util.CopyTransformer;
042 import org.apache.servicemix.jbi.framework.ComponentNameSpace;
043
044 /**
045 * ExchangePacket is responsible for carrying MessageExchange payloads
046 *
047 * @version $Revision: 564607 $
048 */
049 public class ExchangePacket implements Externalizable {
050
051 private static final long serialVersionUID = -9110837382914609624L;
052
053 protected URI pattern;
054
055 protected String exchangeId;
056
057 protected ComponentNameSpace destinationId;
058
059 protected ComponentNameSpace sourceId;
060
061 protected ExchangeStatus status = ExchangeStatus.ACTIVE;
062
063 protected QName serviceName;
064
065 protected QName interfaceName;
066
067 protected QName operationName;
068
069 protected Exception error;
070
071 protected Map properties;
072
073 protected NormalizedMessageImpl in;
074
075 protected NormalizedMessageImpl out;
076
077 protected FaultImpl fault;
078
079 protected ServiceEndpoint endpoint;
080
081 protected transient Transaction transactionContext;
082
083 protected Boolean persistent;
084
085 protected boolean aborted;
086
087 public ExchangePacket() {
088 }
089
090 public ExchangePacket(ExchangePacket packet) throws MessagingException {
091 this.destinationId = packet.destinationId;
092 this.endpoint = null; // packet.endpoint;
093 this.error = null;
094 this.exchangeId = null; // ???;
095 this.interfaceName = packet.interfaceName;
096 CopyTransformer ct = new CopyTransformer();
097 if (packet.in != null) {
098 in = new NormalizedMessageImpl();
099 ct.transform(null, packet.in, in);
100 }
101 if (packet.out != null) {
102 out = new NormalizedMessageImpl();
103 ct.transform(null, packet.out, out);
104 }
105 if (packet.fault != null) {
106 fault = new FaultImpl();
107 ct.transform(null, packet.fault, fault);
108 }
109 this.operationName = packet.operationName;
110 this.pattern = packet.pattern;
111 if (packet.properties != null && packet.properties.size() > 0) {
112 getProperties().putAll(packet.properties);
113 }
114 this.serviceName = packet.serviceName;
115 this.sourceId = packet.sourceId;
116 this.status = packet.status;
117 this.transactionContext = packet.transactionContext;
118 this.persistent = packet.persistent;
119 }
120
121 /**
122 * @return Returns the endpoint.
123 */
124 public ServiceEndpoint getEndpoint() {
125 return endpoint;
126 }
127
128 /**
129 * @param endpoint
130 * The endpoint to set.
131 */
132 public void setEndpoint(ServiceEndpoint endpoint) {
133 this.endpoint = endpoint;
134 }
135
136 /**
137 * @return Returns the transactionContext.
138 */
139 public Transaction getTransactionContext() {
140 return transactionContext;
141 }
142
143 /**
144 * @param transactionContext
145 * The transactionContext to set.
146 */
147 public void setTransactionContext(Transaction transactionContext) {
148 this.transactionContext = transactionContext;
149 }
150
151 /**
152 * @return Returns the interfaceName.
153 */
154 public QName getInterfaceName() {
155 return interfaceName;
156 }
157
158 /**
159 * @param interfaceName
160 * The interfaceName to set.
161 */
162 public void setInterfaceName(QName interfaceName) {
163 this.interfaceName = interfaceName;
164 }
165
166 /**
167 * @return Returns the operationName.
168 */
169 public QName getOperationName() {
170 return operationName;
171 }
172
173 /**
174 * @param operationName
175 * The operationName to set.
176 */
177 public void setOperationName(QName operationName) {
178 this.operationName = operationName;
179 }
180
181 /**
182 * @return Returns the serviceName.
183 */
184 public QName getServiceName() {
185 return serviceName;
186 }
187
188 /**
189 * @param serviceName
190 * The serviceName to set.
191 */
192 public void setServiceName(QName serviceName) {
193 this.serviceName = serviceName;
194 }
195
196 /**
197 * @param status
198 * The status to set.
199 */
200 public void setStatus(ExchangeStatus status) {
201 this.status = status;
202 }
203
204 /**
205 * @return the status
206 */
207 public ExchangeStatus getStatus() {
208 return status;
209 }
210
211 /**
212 * @return Returns the pattern.
213 */
214 public URI getPattern() {
215 return pattern;
216 }
217
218 /**
219 * @param pattern
220 * The pattern to set.
221 */
222 public void setPattern(URI pattern) {
223 this.pattern = pattern;
224 }
225
226 /**
227 * @return Returns the error.
228 */
229 public Exception getError() {
230 return error;
231 }
232
233 /**
234 * @param error
235 * The error to set.
236 */
237 public void setError(Exception error) {
238 this.error = error;
239 this.status = ExchangeStatus.ERROR;
240 }
241
242 /**
243 * @return Returns the exchangeId.
244 */
245 public String getExchangeId() {
246 return exchangeId;
247 }
248
249 /**
250 * @param exchangeId
251 * The exchangeId to set.
252 */
253 public void setExchangeId(String exchangeId) {
254 this.exchangeId = exchangeId;
255 }
256
257 /**
258 * @return Returns the properties.
259 */
260 public Map getProperties() {
261 if (properties == null) {
262 // No need to have concurrent access, as the
263 // message exchange can only be used from a single thread at a time
264 properties = new HashMap();
265 }
266 return properties;
267 }
268
269 /**
270 * @param name
271 * @return the property from the exchange
272 */
273 public Object getProperty(String name) {
274 if (properties != null) {
275 return properties.get(name);
276 }
277 return null;
278 }
279
280 /**
281 * set a named property on the exchange
282 *
283 * @param name
284 * @param value
285 */
286 public void setProperty(String name, Object value) {
287 if (value == null) {
288 if (properties != null) {
289 properties.remove(name);
290 }
291 } else {
292 getProperties().put(name, value);
293 }
294 }
295
296 /**
297 * @return property names
298 */
299 public Set getPropertyNames() {
300 if (properties != null) {
301 return Collections.unmodifiableSet(properties.keySet());
302 }
303 return Collections.EMPTY_SET;
304 }
305
306 /**
307 * @return Returns the sourceId.
308 */
309 public ComponentNameSpace getSourceId() {
310 return sourceId;
311 }
312
313 /**
314 * @param sourceId
315 * The sourceId to set.
316 */
317 public void setSourceId(ComponentNameSpace sourceId) {
318 this.sourceId = sourceId;
319 }
320
321 /**
322 * @return Returns the destinationId.
323 */
324 public ComponentNameSpace getDestinationId() {
325 return destinationId;
326 }
327
328 /**
329 * @param destinationId
330 * The destinationId to set.
331 */
332 public void setDestinationId(ComponentNameSpace destinationId) {
333 this.destinationId = destinationId;
334 }
335
336 /**
337 * @return Returns the fault.
338 */
339 public Fault getFault() {
340 return fault;
341 }
342
343 /**
344 * @param fault
345 * The fault to set.
346 */
347 public void setFault(FaultImpl fault) {
348 this.fault = fault;
349 }
350
351 /**
352 * @return Returns the in.
353 */
354 public NormalizedMessage getIn() {
355 return in;
356 }
357
358 /**
359 * @param in
360 * The in to set.
361 */
362 public void setIn(NormalizedMessageImpl in) {
363 this.in = in;
364 }
365
366 /**
367 * @return Returns the out.
368 */
369 public NormalizedMessage getOut() {
370 return out;
371 }
372
373 /**
374 * @param out
375 * The out to set.
376 */
377 public void setOut(NormalizedMessageImpl out) {
378 this.out = out;
379 }
380
381 /**
382 * @return pretty print
383 */
384 public String toString() {
385 return "ExchangePacket[: id=" + exchangeId + ", serviceDest=" + serviceName + ",endpoint=" + endpoint + "]";
386 }
387
388 /**
389 * Write to a Stream
390 *
391 * @param output
392 * @throws IOException
393 */
394 public void writeExternal(ObjectOutput output) throws IOException {
395 output.writeUTF(pattern.toString());
396 output.writeUTF(exchangeId != null ? exchangeId : "");
397 output.writeUTF(status.toString());
398 output.writeObject(destinationId);
399 output.writeObject(sourceId);
400 output.writeObject(serviceName);
401 output.writeObject(interfaceName);
402 output.writeObject(operationName);
403 output.writeObject(error);
404 output.writeObject(properties);
405 output.writeObject(in);
406 output.writeObject(out);
407 output.writeObject(fault);
408 output.writeObject(endpoint);
409 output.writeByte((persistent == null) ? 0 : persistent.booleanValue() ? 1 : 2);
410 }
411
412 /**
413 * Read from a stream
414 *
415 * @param input
416 * @throws IOException
417 * @throws ClassNotFoundException
418 */
419 public void readExternal(ObjectInput input) throws IOException, ClassNotFoundException {
420 pattern = URI.create(input.readUTF());
421 exchangeId = input.readUTF();
422 status = ExchangeStatus.valueOf(input.readUTF());
423 destinationId = (ComponentNameSpace) input.readObject();
424 sourceId = (ComponentNameSpace) input.readObject();
425 serviceName = (QName) input.readObject();
426 interfaceName = (QName) input.readObject();
427 operationName = (QName) input.readObject();
428 error = (Exception) input.readObject();
429 properties = (Map) input.readObject();
430 in = (NormalizedMessageImpl) input.readObject();
431 out = (NormalizedMessageImpl) input.readObject();
432 fault = (FaultImpl) input.readObject();
433 endpoint = (ServiceEndpoint) input.readObject();
434 byte p = input.readByte();
435 persistent = (p == 0) ? null : p == 1 ? Boolean.TRUE : Boolean.FALSE;
436 }
437
438 /**
439 * Creates a copy of the packet so it can be sent to another destination
440 *
441 * @throws MessagingException
442 */
443 public ExchangePacket copy() throws MessagingException {
444 return new ExchangePacket(this);
445 }
446
447 public Boolean getPersistent() {
448 return persistent;
449 }
450
451 public void setPersistent(Boolean persistent) {
452 this.persistent = persistent;
453 }
454
455 public boolean isAborted() {
456 return aborted;
457 }
458
459 public void setAborted(boolean timedOut) {
460 this.aborted = timedOut;
461 }
462
463 /**
464 * Retrieve the serialized from of this packet
465 *
466 * @return the serialized packet
467 * @throws IOException
468 */
469 public byte[] getData() throws IOException {
470 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
471 ObjectOutputStream os = new ObjectOutputStream(buffer);
472 os.writeObject(this);
473 os.close();
474 return buffer.toByteArray();
475 }
476
477 /**
478 * Deserialize an ExchangePacket.
479 *
480 * @param data
481 * the serialized packet
482 * @return the deserialized packet
483 * @throws IOException
484 * @throws ClassNotFoundException
485 */
486 public static ExchangePacket readPacket(byte[] data) throws IOException, ClassNotFoundException {
487 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
488 return (ExchangePacket) ois.readObject();
489 }
490
491 }