001    package com.nimbusds.oauth2.sdk;
002    
003    
004    import net.jcip.annotations.Immutable;
005    
006    import net.minidev.json.JSONObject;
007    
008    import com.nimbusds.oauth2.sdk.token.AccessToken;
009    import com.nimbusds.oauth2.sdk.token.RefreshToken;
010    import com.nimbusds.oauth2.sdk.token.TokenPair;
011    
012    import com.nimbusds.oauth2.sdk.http.CommonContentTypes;
013    import com.nimbusds.oauth2.sdk.http.HTTPResponse;
014    
015    
016    /**
017     * Access token response from the Token endpoint. This class is immutable.
018     *
019     * <p>Example HTTP response:
020     *
021     * <pre>
022     * HTTP/1.1 200 OK
023     * Content-Type: application/json;charset=UTF-8
024     * Cache-Control: no-store
025     * Pragma: no-cache
026     *
027     * {
028     *   "access_token"      : "2YotnFZFEjr1zCsicMWpAA",
029     *   "token_type"        : "example",
030     *   "expires_in"        : 3600,
031     *   "refresh_token"     : "tGzv3JOkF0XG5Qx2TlKWIA",
032     *   "example_parameter" : "example_value"
033     * }
034     * </pre>
035     *
036     * <p>Related specifications:
037     *
038     * <ul>
039     *     <li>OAuth 2.0 (RFC 6749), sections 4.1.4, 4.3.3,  4.4.3 and 5.1.
040     * </ul>
041     *
042     * @author Vladimir Dzhuvinov
043     * @version $version$ (2013-02-13)
044     */
045    @Immutable
046    public class AccessTokenResponse 
047            extends TokenResponse
048            implements SuccessResponse {
049    
050    
051            /**
052             * The access token.
053             */
054            private final AccessToken accessToken;
055            
056            
057            /**
058             * Optional refresh token.
059             */
060            private final RefreshToken refreshToken;
061            
062            
063            /**
064             * Creates a new access token response.
065             *
066             * @param accessToken  The access token. Must not be {@code null}.
067             * @param refreshToken Optional refresh token, {@code null} if none.
068             */
069            public AccessTokenResponse(final AccessToken accessToken,
070                                       final RefreshToken refreshToken) {
071                                       
072                    if (accessToken == null)
073                            throw new IllegalArgumentException("The access token must not be null");
074                    
075                    this.accessToken = accessToken;
076                    
077                    this.refreshToken = refreshToken;
078            }
079    
080    
081            /**
082             * Creates a new access token response.
083             *
084             * @param tokenPair The access and refresh token pair. Must not be 
085             *                  {@code null}.
086             */
087            public AccessTokenResponse(final TokenPair tokenPair) {
088                                       
089                    this(tokenPair.getAccessToken(), tokenPair.getRefreshToken());
090            }
091            
092            
093            /**
094             * Gets the access token.
095             *
096             * @return The access token.
097             */
098            public AccessToken getAccessToken() {
099            
100                    return accessToken;
101            }
102            
103            
104            /**
105             * Gets the optional refresh token.
106             *
107             * @return The refresh token, {@code null} if none.
108             */
109            public RefreshToken getRefreshToken() {
110            
111                    return refreshToken;
112            }
113    
114    
115            /**
116             * Gets the access and refresh token pair.
117             *
118             * @return The access and refresh token pair. Must not be {@code null}.
119             */
120            public TokenPair getTokenPair() {
121    
122                    return new TokenPair(accessToken, refreshToken);
123            }
124            
125            
126            /**
127             * Returns the JSON object representing this access token response.
128             *
129             * <p>Example JSON object:
130             *
131             * <pre>
132             * {
133             *   "access_token" : "SlAV32hkKG",
134             *   "token_type"   : "Bearer",
135             *   "refresh_token": "8xLOxBtZp8",
136             *   "expires_in"   : 3600
137             * }
138             * </pre>
139             *
140             * @return The JSON object.
141             *
142             * @throws SerializeException If this access token response couldn't be
143             *                            serialised to a JSON object.
144             */
145            public JSONObject toJSONObject()
146                    throws SerializeException {
147            
148                    JSONObject o = accessToken.toJSONObject();
149    
150                    if (refreshToken != null)
151                            o.putAll(refreshToken.toJSONObject());
152                    
153                    return o;
154            }
155            
156            
157            @Override
158            public HTTPResponse toHTTPResponse()
159                    throws SerializeException {
160            
161                    HTTPResponse httpResponse = new HTTPResponse(HTTPResponse.SC_OK);
162                    
163                    httpResponse.setContentType(CommonContentTypes.APPLICATION_JSON);
164                    httpResponse.setCacheControl("no-store");
165                    httpResponse.setPragma("no-cache");
166                    
167                    httpResponse.setContent(toJSONObject().toString());
168                    
169                    return httpResponse;
170            }
171            
172            
173            /**
174             * Parses an access token response from the specified JSON object.
175             *
176             * @param jsonObject The JSON object to parse. Must not be {@code null}.
177             *
178             * @return The access token response.
179             *
180             * @throws ParseException If the JSON object couldn't be parsed to an
181             *                        access token response.
182             */
183            public static AccessTokenResponse parse(final JSONObject jsonObject)
184                    throws ParseException {
185                    
186                    AccessToken accessToken = AccessToken.parse(jsonObject);
187                    
188                    RefreshToken refreshToken = RefreshToken.parse(jsonObject);
189                    
190                    return new AccessTokenResponse(accessToken, refreshToken);
191            }
192            
193            
194            /**
195             * Parses an access token response from the specified HTTP response.
196             *
197             * @param httpResponse The HTTP response. Must not be {@code null}.
198             *
199             * @return The access token response.
200             *
201             * @throws ParseException If the HTTP response couldn't be parsed to an 
202             *                        access token response.
203             */
204            public static AccessTokenResponse parse(final HTTPResponse httpResponse)
205                    throws ParseException {
206                    
207                    httpResponse.ensureStatusCode(HTTPResponse.SC_OK);
208                    
209                    JSONObject jsonObject = httpResponse.getContentAsJSONObject();
210                    
211                    return parse(jsonObject);
212            }
213    }