001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2020, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.openid.connect.sdk.federation.api;
019
020
021import net.jcip.annotations.Immutable;
022import net.minidev.json.JSONObject;
023
024import com.nimbusds.oauth2.sdk.ErrorObject;
025import com.nimbusds.oauth2.sdk.ParseException;
026import com.nimbusds.oauth2.sdk.http.HTTPResponse;
027import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
028
029
030/**
031 * Federation API error.
032 *
033 * <ul>
034 *     <li>OpenID Connect Federation 1.0, section 6.4.
035 * </ul>
036 */
037@Immutable
038public class FederationAPIError extends ErrorObject {
039        
040        
041        /**
042         * The operation type.
043         */
044        private final OperationType operationType;
045        
046        
047        /**
048         * Creates a new federation API error.
049         *
050         * @param operationType The operation type, {@code null} if not
051         *                      specified.
052         * @param code          The error code, {@code null} if not specified.
053         * @param description   The error description, {@code null} if not
054         *                      specified.
055         */
056        public FederationAPIError(final OperationType operationType, final String code, final String description) {
057                this(operationType, code, description, 0);
058        }
059        
060        
061        /**
062         * Creates a new federation API error.
063         *
064         * @param operationType  The operation type, {@code null} if not
065         *                       specified.
066         * @param code           The error code, {@code null} if not specified.
067         * @param description    The error description, {@code null} if not
068         *                       specified.
069         * @param httpStatusCode The HTTP status code, zero if not specified.
070         */
071        public FederationAPIError(final OperationType operationType,
072                                  final String code,
073                                  final String description,
074                                  final int httpStatusCode) {
075                super(code, description, httpStatusCode);
076                this.operationType = operationType;
077        }
078        
079        
080        /**
081         * Returns the operation type.
082         *
083         * @return The operation type, {@code null} if not specified.
084         */
085        public OperationType getOperationType() {
086                return operationType;
087        }
088        
089        
090        /**
091         * Returns a copy of this federation API error with the specified HTTP
092         * status code.
093         *
094         * @param httpStatusCode The HTTP status code, zero if not specified.
095         *
096         * @return The new federation API error.
097         */
098        public FederationAPIError withStatusCode(final int httpStatusCode) {
099                return new FederationAPIError(getOperationType(), getCode(), getDescription(), httpStatusCode);
100        }
101        
102        
103        @Override
104        public JSONObject toJSONObject() {
105                JSONObject jsonObject = super.toJSONObject();
106                if (getOperationType() != null) {
107                        jsonObject.put("operation", getOperationType().getValue());
108                }
109                return jsonObject;
110        }
111        
112        
113        /**
114         * Parses a federation API error object from the specified JSON object.
115         *
116         * @param jsonObject The JSON object to parse. Must not be
117         *                   {@code null}.
118         *
119         * @return The federation API error object.
120         */
121        public static FederationAPIError parse(final JSONObject jsonObject) {
122                ErrorObject errorObject = ErrorObject.parse(jsonObject);
123                OperationType operationType = null;
124                try {
125                        operationType = new OperationType(JSONObjectUtils.getString(jsonObject, "operation"));
126                } catch (ParseException e) {
127                        // ignore
128                }
129                return new FederationAPIError(operationType, errorObject.getCode(), errorObject.getDescription());
130        }
131        
132        
133        /**
134         * Parses a federation API error object from the specified HTTP
135         * response.
136         *
137         * @param httpResponse The HTTP response to parse. Must not be
138         *                     {@code null}.
139         *
140         * @return The federation API error object.
141         */
142        public static FederationAPIError parse(final HTTPResponse httpResponse) {
143                JSONObject jsonObject;
144                try {
145                        jsonObject = httpResponse.getContentAsJSONObject();
146                } catch (ParseException e) {
147                        jsonObject = new JSONObject();
148                }
149                return FederationAPIError.parse(jsonObject).withStatusCode(httpResponse.getStatusCode());
150        }
151}