org.n52.iceland.config.json.JsonSettingsDao.java Source code

Java tutorial

Introduction

Here is the source code for org.n52.iceland.config.json.JsonSettingsDao.java

Source

/*
 * Copyright 2015 52North Initiative for Geospatial Open Source
 * Software 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.iceland.config.json;

import java.util.HashSet;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;

import javax.inject.Inject;

import org.n52.iceland.config.SettingType;
import org.n52.iceland.config.SettingValue;
import org.n52.iceland.config.SettingsDao;
import org.n52.iceland.i18n.LocaleHelper;
import org.n52.iceland.i18n.MultilingualString;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.n52.iceland.exception.ConfigurationError;

/**
 *
 * @author Christian Autermann, Daniel Nst
 */
public class JsonSettingsDao extends AbstractJsonDao implements SettingsDao {

    private JsonSettingsEncoder settingsEncoder;

    private JsonSettingValueFactory settingValueFactory;

    @Inject
    public void setSettingValueFactory(JsonSettingValueFactory settingValueFactory) {
        this.settingValueFactory = settingValueFactory;
    }

    @Inject
    public void setSettingsEncoder(JsonSettingsEncoder settingsEncoder) {
        this.settingsEncoder = settingsEncoder;
    }

    protected JsonSettingsEncoder getSettingsEncoder() {
        return this.settingsEncoder;
    }

    @Override
    public Set<SettingValue<?>> getSettingValues() {
        readLock().lock();
        try {
            JsonNode node = getConfiguration().path(JsonConstants.SETTINGS);
            Set<SettingValue<?>> values = new HashSet<>(node.size());
            node.fieldNames().forEachRemaining(key -> values.add(createSettingValue(key, node.path(key))));
            return values;
        } finally {
            readLock().unlock();
        }
    }

    @Override
    public SettingValue<?> getSettingValue(String key) {
        readLock().lock();
        try {
            JsonNode node = getConfiguration().path(JsonConstants.SETTINGS).path(key);
            if (!node.isObject()) {
                return null;
            }
            return createSettingValue(key, node);
        } finally {
            readLock().unlock();
        }
    }

    @Override
    public void deleteSettingValue(String key) {
        writeLock().lock();
        try {
            getConfiguration().with(JsonConstants.SETTINGS).remove(key);
        } finally {
            writeLock().unlock();
        }
        configuration().scheduleWrite();
    }

    @Override
    public void saveSettingValue(SettingValue<?> value) {
        writeLock().lock();
        try {
            ObjectNode settings = getConfiguration().with(JsonConstants.SETTINGS);
            JsonNode node = settings.path(value.getKey());
            ObjectNode settingNode = (ObjectNode) Optional.ofNullable(node.isObject() ? node : null)
                    .orElseGet(() -> settings.putObject(value.getKey()));
            settingNode.put(JsonConstants.TYPE, value.getType().toString());
            settingNode.set(JsonConstants.VALUE, this.settingsEncoder.encodeValue(value));
        } finally {
            writeLock().unlock();
        }
        configuration().scheduleWrite();
    }

    @Override
    public void deleteAll() {
        this.configuration().delete();
    }

    protected SettingValue<?> createSettingValue(String key, JsonNode node) {
        SettingType type = SettingType.fromString(node.path(JsonConstants.TYPE).asText(null));
        Object value = decodeValue(type, node.path(JsonConstants.VALUE));
        return new JsonSettingValue<>(type).setKey(key).setValue(value);
    }

    protected Object decodeValue(SettingType type, JsonNode node) {
        switch (type) {
        case INTEGER:
            if (!node.canConvertToInt()) {
                numberDecodeError(type, node);
            }
            return node.intValue();
        case NUMERIC:
            if (!node.isDouble()) {
                numberDecodeError(type, node);
            }
            return node.doubleValue();
        case BOOLEAN:
            return node.booleanValue();
        case TIMEINSTANT:
            return this.settingValueFactory.parseTimeInstant(node.textValue());
        case FILE:
            return this.settingValueFactory.parseFile(node.textValue());
        case STRING:
            return node.textValue();
        case URI:
            return this.settingValueFactory.parseUri(node.textValue());
        case MULTILINGUAL_STRING:
            return decodeMultilingualString(node);
        case CHOICE:
            return node.textValue();
        default:
            throw new ConfigurationError(String.format("Unknown Type %s", type));
        }
    }

    protected MultilingualString decodeMultilingualString(JsonNode json) {
        MultilingualString mls = new MultilingualString();
        json.fields().forEachRemaining(e -> {
            Locale locale = LocaleHelper.fromString(e.getKey());
            mls.addLocalization(locale, e.getValue().asText());
        });
        return mls;
    }

    private void numberDecodeError(SettingType type, JsonNode node) {
        throw new ConfigurationError(String.format("Cannot decode setting to %s type: node type = %s, value = >%s<",
                type, node.getNodeType(), node.toString()));
    }

}