/** * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL * 1.0 (the "Licenses"). You can select the license that you prefer but you may * not use this file except in compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the LGPL 3.0 license at * http://www.opensource.org/licenses/lgpl-3.0 * * You can obtain a copy of the LGPL 2.1 license at * http://www.opensource.org/licenses/lgpl-2.1 * * You can obtain a copy of the CDDL 1.0 license at * http://www.opensource.org/licenses/cddl1 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://www.restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet */ package org.restlet; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import org.restlet.data.MediaType; import org.restlet.data.RecipientInfo; import org.restlet.data.Warning; import org.restlet.representation.Representation; import org.restlet.representation.StringRepresentation; /** * Generic message exchanged between components. * * @author Jerome Louvel */ public abstract class Message { /** The modifiable attributes map. */ private volatile ConcurrentMap<String, Object> attributes; /** The date and time at which the message was originated. */ private volatile Date date; /** The payload of the message. */ private volatile Representation entity; /** The optional cached text. */ private volatile String entityText; /** Callback invoked when an error occurs when sending the message. */ private volatile Uniform onError; /** Callback invoked after sending the message. */ private volatile Uniform onSent; /** The intermediary recipients info. */ private volatile List<RecipientInfo> recipientsInfo; /** The additional warnings information. */ private volatile List<Warning> warnings; /** * Constructor. */ public Message() { this((Representation) null); } /** * Constructor. * * @param entity * The payload of the message. */ public Message(Representation entity) { this.attributes = null; // this.cacheDirectives = null; this.date = null; this.entity = entity; this.entityText = null; this.onSent = null; this.recipientsInfo = null; this.warnings = null; } /** * Returns the entity representation. * * @return The entity representation. */ public Representation getEntity() { return this.entity; } /** * Returns the callback invoked when an error occurs when sending the * message. * * @return The callback invoked when an error occurs when sending the * message. */ public Uniform getOnError() { return onError; } /** * Returns the callback invoked after sending the message. * * @return The callback invoked after sending the message. */ public Uniform getOnSent() { return onSent; } /** * Returns the intermediary recipient information.<br> * <br> * Note that when used with HTTP connectors, this property maps to the "Via" * headers. * * @return The intermediary recipient information. */ public List<RecipientInfo> getRecipientsInfo() { // Lazy initialization with double-check. List<RecipientInfo> r = this.recipientsInfo; if (r == null) { synchronized (this) { r = this.recipientsInfo; if (r == null) { this.recipientsInfo = r = new CopyOnWriteArrayList<RecipientInfo>(); } } } return r; } /** * Returns the additional warnings information.<br> * <br> * Note that when used with HTTP connectors, this property maps to the * "Warning" headers. * * @return The additional warnings information. */ public List<Warning> getWarnings() { // Lazy initialization with double-check. List<Warning> r = this.warnings; if (r == null) { synchronized (this) { r = this.warnings; if (r == null) { this.warnings = r = new CopyOnWriteArrayList<Warning>(); } } } return r; } /** * Indicates if a content is available and can be sent or received. Several * conditions must be met: the content must exists and have some available * data. * * @return True if a content is available and can be sent. */ public boolean isEntityAvailable() { // The declaration of the "result" variable is a workaround for the GWT // platform. Please keep it! boolean result = (getEntity() != null) && getEntity().isAvailable(); return result; } /** * Releases the message's entity if present. * * @see org.restlet.representation.Representation#release() */ public void release() { if (getEntity() != null) { getEntity().release(); } } /** * Sets the date and time at which the message was originated. * * @param date * The date and time at which the message was originated. */ public void setDate(Date date) { this.date = date; } /** * Sets the entity representation. * * @param entity * The entity representation. */ public void setEntity(Representation entity) { this.entity = entity; } /** * Sets a textual entity. * * @param value * The represented string. * @param mediaType * The representation's media type. */ public void setEntity(String value, MediaType mediaType) { setEntity(new StringRepresentation(value, mediaType)); } /** * Sets the callback invoked when an error occurs when sending the message. * * @param onError * The callback invoked when an error occurs when sending the * message. */ public void setOnError(Uniform onError) { this.onError = onError; } /** * Sets the callback invoked after sending the message. * * @param onSentCallback * The callback invoked after sending the message. */ public void setOnSent(Uniform onSentCallback) { this.onSent = onSentCallback; } /** * Sets the modifiable list of intermediary recipients. Note that when used * with HTTP connectors, this property maps to the "Via" headers. This * method clears the current list and adds all entries in the parameter * list. * * @param recipientsInfo * A list of intermediary recipients. */ public void setRecipientsInfo(List<RecipientInfo> recipientsInfo) { synchronized (getRecipientsInfo()) { if (recipientsInfo != getRecipientsInfo()) { getRecipientsInfo().clear(); if (recipientsInfo != null) { getRecipientsInfo().addAll(recipientsInfo); } } } } /** * Sets the additional warnings information. Note that when used with HTTP * connectors, this property maps to the "Warning" headers. This method * clears the current list and adds all entries in the parameter list. * * @param warnings * The warnings. */ public void setWarnings(List<Warning> warnings) { synchronized (getWarnings()) { if (warnings != getWarnings()) { getWarnings().clear(); if (warnings != null) { getWarnings().addAll(warnings); } } } } }