org.openmhealth.schema.domain.omh.AdditionalPropertySupport.java Source code

Java tutorial

Introduction

Here is the source code for org.openmhealth.schema.domain.omh.AdditionalPropertySupport.java

Source

/*
 * Copyright 2016 Open mHealth
 *
 * 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.openmhealth.schema.domain.omh;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.google.common.base.Splitter;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * An interface for schema classes that support additional properties.
 *
 * @author Emerson Farrugia
 */
public interface AdditionalPropertySupport {

    /**
     * Sets an additional property. This method supports dot-separated paths by creating nested maps when necessary.
     *
     * @param path  the path of the property to set
     * @param value the value of the property to set
     */
    @SuppressWarnings("unchecked")
    @JsonAnySetter
    default void setAdditionalProperty(String path, Object value) {

        checkNotNull(path, "A path hasn't been specified.");
        checkArgument(!path.isEmpty(), "An empty path has been specified.");

        Iterator<String> names = Splitter.on(".").omitEmptyStrings().split(path).iterator();
        Map<String, Object> currentCollection = getAdditionalProperties();

        while (names.hasNext()) {
            String currentName = names.next();

            // set the value, potentially overriding an existing value
            if (!names.hasNext()) {
                currentCollection.put(currentName, value);
                break;
            }

            // traverse into a collection if one exists
            if (currentCollection.get(currentName) instanceof Map) {
                currentCollection = (Map<String, Object>) currentCollection.get(currentName);
                continue;
            }

            // create a new collection, potentially overriding an existing value
            Map<String, Object> map = new HashMap<>();
            currentCollection.put(currentName, map);
            currentCollection = map;
        }
    }

    /**
     * Gets an additional property.
     *
     * @param name the name of the additional property to retrieve
     * @return the property value, if present
     */
    default Optional<Object> getAdditionalProperty(String name) {

        checkNotNull(name, "A name hasn't been specified.");
        checkArgument(!name.isEmpty(), "An empty name has been specified.");

        return Optional.ofNullable(getAdditionalProperties().get(name));
    }

    /**
     * Gets the additional properties.
     *
     * @return the additional properties as a map
     */
    @JsonAnyGetter
    Map<String, Object> getAdditionalProperties();
}