001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2009 Sun Microsystems Inc.
015 * Portions Copyright 2010–2011 ApexIdentity Inc.
016 * Portions Copyright 2011-2016 ForgeRock AS.
017 */
018
019package org.forgerock.http.protocol;
020
021import java.io.IOException;
022
023import org.forgerock.util.promise.NeverThrowsException;
024import org.forgerock.util.promise.Promise;
025import org.forgerock.util.promise.PromiseImpl;
026import org.forgerock.util.promise.Promises;
027
028
029/**
030 * A response message.
031 */
032public final class Response extends MessageImpl<Response> {
033    /** The response status. */
034    private Status status;
035
036    private Exception cause;
037
038    /**
039     * Returns a {@link Promise} representing the {@code Response} for an
040     * asynchronous {@code Request} which has already completed. Attempts to get
041     * the {@code Response} will immediately return without blocking, and any
042     * listeners registered against the returned promise will be immediately
043     * invoked in the same thread as the caller.
044     *
045     * @param response
046     *            The {@code Response}.
047     * @return A {@link Promise} representing the {@code Response} for an
048     *         asynchronous {@code Request} which has already completed.
049     */
050    public static Promise<Response, NeverThrowsException> newResponsePromise(Response response) {
051        return Promises.newResultPromise(response);
052    }
053
054    /**
055     * Creates a new pending {@link Promise} implementation representing the
056     * {@code Response} for an asynchronous {@code Request}. The returned
057     * {@link PromiseImpl} must be completed once the {@code Response} is
058     * received by invoking the {@link PromiseImpl#handleResult(Object)
059     * handleResult} method.
060     *
061     * @return A new pending {@link Promise} implementation representing the
062     *         {@code Response} for an asynchronous {@code Request}.
063     */
064    public static PromiseImpl<Response, NeverThrowsException> newResponsePromiseImpl() {
065        return PromiseImpl.create();
066    }
067
068    /**
069     * Creates a new response.
070     */
071    public Response() {
072        // Nothing to do.
073    }
074
075    /**
076     * Creates a defensive copy of the given {@code response} message.
077     *
078     * @param response
079     *         response to be copied
080     * @throws IOException
081     *         when entity cannot be cloned
082     */
083    public Response(final Response response) throws IOException {
084        super(response);
085        status = response.status;
086        cause = response.cause;
087    }
088
089    /**
090     * Creates a new response with a default status.
091     *
092     * @param status The status to use for the Reponse.
093     */
094    public Response(Status status) {
095        this.status = status;
096    }
097
098    /**
099     * Returns the response status.
100     *
101     * @return The response status.
102     */
103    public Status getStatus() {
104        return status;
105    }
106
107    /**
108     * Returns the (possibly {@code null}) cause of this error message (assuming it is a 4xx or a 5xx).
109     *
110     * @return the (possibly {@code null}) cause of this error message (assuming it is a 4xx or a 5xx).
111     */
112    public Exception getCause() {
113        return cause;
114    }
115
116    /**
117     * Link a 'caused by' exception to this response.
118     * That can be used to determine if this error response was triggered by an exception (as opposed
119     * to obtained from a remote server).
120     * <b>Note:</b> this method does not change the {@code status} of this message, neither touch its content.
121     * It's up to the caller to ensure consistency (if required in the execution context).
122     *
123     * @param cause Cause of this error response
124     * @return This response.
125     */
126    public Response setCause(final Exception cause) {
127        this.cause = cause;
128        return this;
129    }
130
131    @Override
132    public Response setEntity(Object o) {
133        setEntity0(o);
134        return this;
135    }
136
137    /**
138     * Sets the response status code.
139     *
140     * @param status
141     *            The response status code.
142     * @return This response.
143     */
144    public Response setStatus(final Status status) {
145        this.status = status;
146        return this;
147    }
148
149    @Override
150    public Response setVersion(String version) {
151        setVersion0(version);
152        return this;
153    };
154}