001: /*
002: * $Id: DefaultMessageAdapter.java 10489 2008-01-23 17:53:38Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.transport;
012:
013: import org.mule.api.MuleRuntimeException;
014: import org.mule.api.ThreadSafeAccess;
015: import org.mule.api.transport.MessageAdapter;
016: import org.mule.api.transport.MutableMessageAdapter;
017: import org.mule.config.i18n.CoreMessages;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import javax.activation.DataHandler;
023:
024: /**
025: * <code>DefaultMessageAdapter</code> can be used to wrap an arbitary object where
026: * no special 'apapting' is needed. The adapter allows for a set of properties to be
027: * associated with an object.
028: */
029:
030: public final class DefaultMessageAdapter extends AbstractMessageAdapter
031: implements MutableMessageAdapter {
032: /**
033: * Serial version
034: */
035: private static final long serialVersionUID = 1908152148142575505L;
036:
037: /**
038: * The message object wrapped by this adapter
039: */
040: protected Object message;
041:
042: protected DefaultMessageAdapter() {
043: super ();
044: }
045:
046: /**
047: * Creates a default message adapter with properties and attachments
048: *
049: * @param message the message to wrap. If this is null and NullPayload object
050: * will be used
051: * @see NullPayload
052: */
053: public DefaultMessageAdapter(Object message) {
054: if (message == null) {
055: this .message = NullPayload.getInstance();
056: } else {
057: this .message = message;
058: }
059: }
060:
061: public DefaultMessageAdapter(Object message, MessageAdapter previous) {
062: super (previous);
063: if (previous != null) {
064: if (message == null) {
065: this .message = NullPayload.getInstance();
066: } else {
067: this .message = message;
068: }
069: // MULE-1564
070: // this is an iterator over a concurrent map and so is weakly consistent (not fail-safe)
071: // that means we don't get errors here, but may see changed values.
072: // so we can make this safe to null values (although not predictable) by simply checking values
073: for (Iterator iterator = previous.getAttachmentNames()
074: .iterator(); iterator.hasNext();) {
075: String name = (String) iterator.next();
076: try {
077: DataHandler dh = previous.getAttachment(name);
078: if (null == dh) {
079: logger
080: .warn("Detected concurrent access to attachment "
081: + name + " for " + previous);
082: // new Throwable().printStackTrace();
083: } else {
084: addAttachment(name, dh);
085: }
086: } catch (Exception e) {
087: throw new MuleRuntimeException(CoreMessages
088: .failedToReadPayload(), e);
089: }
090: }
091: for (Iterator iterator = previous.getPropertyNames()
092: .iterator(); iterator.hasNext();) {
093: String name = (String) iterator.next();
094: try {
095: Object value = previous.getProperty(name);
096: if (null == value) {
097: logger
098: .warn("Detected concurrent access to property "
099: + name + " for " + previous);
100: // new Throwable().printStackTrace();
101: } else {
102: setProperty(name, value);
103: }
104: } catch (Exception e) {
105: throw new MuleRuntimeException(CoreMessages
106: .failedToReadPayload(), e);
107: }
108: }
109: } else {
110: throw new IllegalArgumentException(
111: "previousAdapter may not be null");
112: }
113: }
114:
115: /**
116: * Creates a default message adapter with properties and attachments
117: *
118: * @param message the message to wrap. If this is null and NullPayload object
119: * will be used
120: * @param properties a map properties to set on the adapter. Can be null.
121: * @param attachments a map attaches (DataHandler objects) to set on the adapter.
122: * Can be null.
123: * @see NullPayload
124: * @see javax.activation.DataHandler
125: */
126: public DefaultMessageAdapter(Object message, Map properties,
127: Map attachments) {
128: this (message);
129: if (properties != null) {
130: this .properties.addInboundProperties(properties);
131: }
132: if (attachments != null) {
133: this .attachments.putAll(attachments);
134: }
135: }
136:
137: /** {@inheritDoc} */
138: public Object getPayload() {
139: return message;
140: }
141:
142: /** {@inheritDoc} */
143: public void setPayload(Object payload) {
144: synchronized (message) {
145: message = payload;
146: }
147: }
148:
149: /** {@inheritDoc} */
150: public String getUniqueId() {
151: return id;
152: }
153:
154: ////////////////////////// ThreadSafeAccess impl ////////////////////
155:
156: /** {@inheritDoc} */
157: public ThreadSafeAccess newThreadCopy() {
158: return new DefaultMessageAdapter(getPayload(), this);
159: }
160:
161: }
|