All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.n52.svalbard.decode.json.JSONDecoder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2015-2022 52°North Spatial Information Research GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.n52.svalbard.decode.json;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.joda.time.DateTime;
import org.n52.janmayen.exception.CompositeException;
import org.n52.janmayen.stream.Streams;
import org.n52.shetland.ogc.OGCConstants;
import org.n52.shetland.ogc.gml.CodeType;
import org.n52.shetland.ogc.gml.CodeWithAuthority;
import org.n52.shetland.ogc.gml.time.IndeterminateValue;
import org.n52.shetland.ogc.gml.time.Time;
import org.n52.shetland.ogc.gml.time.TimeInstant;
import org.n52.shetland.ogc.gml.time.TimePeriod;
import org.n52.shetland.util.DateTimeHelper;
import org.n52.shetland.util.DateTimeParseException;
import org.n52.svalbard.coding.json.JSONConstants;
import org.n52.svalbard.decode.AbstractDelegatingDecoder;
import org.n52.svalbard.decode.Decoder;
import org.n52.svalbard.decode.DecoderKey;
import org.n52.svalbard.decode.JsonDecoderKey;
import org.n52.svalbard.decode.exception.DecodingException;
import org.n52.svalbard.decode.exception.NoDecoderForKeyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
 * TODO JavaDoc
 *
 * @author Christian Autermann
 * @since 1.0.0
 */
public abstract class JSONDecoder
        extends AbstractDelegatingDecoder {
    private static final Logger LOGGER = LoggerFactory.getLogger(JSONDecoder.class);
    private final Set decoderKeys = new LinkedHashSet<>();

    public JSONDecoder(Class type) {
        this(Collections.singleton(new JsonDecoderKey(type)));
    }

    public JSONDecoder(DecoderKey... keys) {
        this(Streams.stream(keys).collect(toSet()));
    }

    @SuppressFBWarnings({ "EI_EXPOSE_REP2" })
    public JSONDecoder(Collection keys) {
        if (keys != null) {
            this.decoderKeys.addAll(keys);
        }
    }

    private  Decoder getDecoder(Class type)
            throws DecodingException {
        JsonDecoderKey key = new JsonDecoderKey(type);
        Decoder decoder = getDecoder(key);
        if (decoder == null) {
            throw new NoDecoderForKeyException(key);
        }
        return decoder;
    }

    protected  T decodeJsonToObject(JsonNode json, Class type)
            throws DecodingException {
        if (json == null || json.isNull() || json.isMissingNode()) {
            return null;
        }
        return getDecoder(type).decode(json);
    }

    protected  List decodeJsonToObjectList(JsonNode node, Class type)
            throws DecodingException {
        Decoder decoder = getDecoder(type);
        if (node.isArray()) {
            CompositeException exceptions = new CompositeException();
            List list = Streams.stream(node)
                                  .filter(JsonNode::isObject)
                                  .map(exceptions.wrapFunction(decoder::decode))
                                  .filter(Optional::isPresent).map(Optional::get)
                                  .collect(toList());
            exceptions.throwIfNotEmpty(DecodingException::new);
            return list;
        } else if (node.isObject()) {
            return Collections.singletonList(decoder.decode(node));
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public Set getKeys() {
        return Collections.unmodifiableSet(decoderKeys);
    }

    @Override
    public T decode(JsonNode objectToDecode)
            throws DecodingException {
        return decodeJSON(objectToDecode, true);
    }

    protected TimeInstant parseTimeInstant(JsonNode node)
            throws DateTimeParseException {
        if (node.isTextual()) {
            return new TimeInstant(parseDateTime(node.textValue()));
        } else if (node.path(JSONConstants.INDETERMINATE_VALUE).isTextual()) {
            return new TimeInstant(new IndeterminateValue(node.path(JSONConstants.INDETERMINATE_VALUE).textValue()));
        }
        return null;
    }

    protected TimePeriod parseTimePeriod(JsonNode node)
            throws DateTimeParseException {
        if (node.isArray()) {
            ArrayNode array = (ArrayNode) node;
            String startTime = array.get(0).textValue();
            String endTime = array.get(1).textValue();
            DateTime start = parseDateTime(startTime);
            DateTime end = parseDateTime(endTime);
            return new TimePeriod(start, end);
        } else {
            return null;
        }
    }

    protected DateTime parseDateTime(String time)
            throws DateTimeParseException {
        return DateTimeHelper.parseIsoString2DateTime(time);
    }

    protected Time parseTime(JsonNode node)
            throws DateTimeParseException {
        if (node.isArray()) {
            return parseTimePeriod(node);
        } else if (node.isTextual()) {
            return parseTimeInstant(node);
        } else {
            return null;
        }
    }

    protected CodeWithAuthority parseCodeWithAuthority(JsonNode node) {
        if (node.isObject()) {
            String value = node.path(JSONConstants.VALUE).textValue();
            String codespace = node.path(JSONConstants.CODESPACE).textValue();
            if (codespace == null || codespace.isEmpty()) {
                codespace = OGCConstants.UNKNOWN;
            }
            return new CodeWithAuthority(value, codespace);
        } else if (node.isTextual()) {
            return new CodeWithAuthority(node.textValue(), OGCConstants.UNKNOWN);
        } else {
            return null;
        }
    }

    protected CodeType parseCodeType(JsonNode node) {
        try {
            if (node.isObject()) {
                CodeType ct = new CodeType(node.path(JSONConstants.VALUE).textValue());
                if (node.has(JSONConstants.CODESPACE)) {
                    ct.setCodeSpace(new URI(node.path(JSONConstants.CODESPACE).textValue()));
                }
                return ct;
            } else if (node.isTextual()) {
                return new CodeType(node.textValue());
            }
        } catch (URISyntaxException e) {
            LOGGER.error("Error while creating URI!", e);
        }
        return null;
    }

    public abstract T decodeJSON(JsonNode node, boolean validate)
            throws DecodingException;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy