001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.eclipse.aether.spi.connector.transport.http.RFC9457;
020
021import java.lang.reflect.Type;
022import java.net.URI;
023
024import com.google.gson.Gson;
025import com.google.gson.GsonBuilder;
026import com.google.gson.JsonDeserializationContext;
027import com.google.gson.JsonDeserializer;
028import com.google.gson.JsonElement;
029import com.google.gson.JsonObject;
030import com.google.gson.JsonParseException;
031
032public class RFC9457Parser {
033    private static Gson gson = new GsonBuilder()
034            .registerTypeAdapter(RFC9457Payload.class, new RFC9457PayloadAdapter())
035            .create();
036
037    public static RFC9457Payload parse(String data) {
038        return gson.fromJson(data, RFC9457Payload.class);
039    }
040
041    private static class RFC9457PayloadAdapter implements JsonDeserializer<RFC9457Payload> {
042        @Override
043        public RFC9457Payload deserialize(
044                final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
045                throws JsonParseException {
046            JsonObject asJsonObject = json.getAsJsonObject();
047            URI type = parseNullableURI(asJsonObject, "type", "about:blank");
048            Integer status = parseStatus(asJsonObject);
049            String title = parseNullableString(asJsonObject, "title");
050            String detail = parseNullableString(asJsonObject, "detail");
051            URI instance = parseNullableURI(asJsonObject, "instance", null);
052            return new RFC9457Payload(type, status, title, detail, instance);
053        }
054    }
055
056    private static Integer parseStatus(JsonObject jsonObject) {
057        return jsonObject.get("status") == null || jsonObject.get("status").isJsonNull()
058                ? null
059                : jsonObject.get("status").getAsInt();
060    }
061
062    private static String parseNullableString(JsonObject jsonObject, String key) {
063        return jsonObject.get(key) == null || jsonObject.get(key).isJsonNull()
064                ? null
065                : jsonObject.get(key).getAsString();
066    }
067
068    private static URI parseNullableURI(JsonObject jsonObject, String key, String defaultValue) {
069        return !jsonObject.has(key) || jsonObject.get(key).isJsonNull()
070                ? defaultValue != null ? URI.create(defaultValue) : null
071                : URI.create(jsonObject.get(key).getAsString());
072    }
073}