com.mgmtp.jfunk.data.source.BaseDataSource.java Source code

Java tutorial

Introduction

Here is the source code for com.mgmtp.jfunk.data.source.BaseDataSource.java

Source

/*
 * Copyright (c) 2015 mgm technology partners 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 com.mgmtp.jfunk.data.source;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mgmtp.jfunk.common.JFunkConstants;
import com.mgmtp.jfunk.common.exception.JFunkException;
import com.mgmtp.jfunk.common.util.Configuration;
import com.mgmtp.jfunk.common.util.ExtendedProperties;
import com.mgmtp.jfunk.common.util.Predicates;
import com.mgmtp.jfunk.data.DataSet;

/**
 * Abstract {@link DataSource} implementation with functionality for handling fixed values.
 * 
 */
public abstract class BaseDataSource implements DataSource {
    protected final Logger log = LoggerFactory.getLogger(getClass());

    protected final Map<String, Map<String, String>> fixedValues = Maps.newHashMap();
    protected final Configuration configuration;
    private Set<String> formDataKeys;
    private final String name;
    private final Map<String, DataSet> currentDataSets = Maps.newHashMap();

    /**
     * Creates a new instance of the data source, reading fixed properties from the configuration.
     * 
     * @param configuration
     *            Configuration for the data source.
     */
    protected BaseDataSource(final Configuration configuration) {
        this.name = StringUtils.uncapitalize(StringUtils.substringBefore(getClass().getSimpleName(), "DataSource"));
        this.configuration = configuration;
    }

    protected Set<String> getFormDataKeys() {
        try {
            Map<String, String> view = Maps.filterKeys(configuration,
                    Predicates.startsWith(JFunkConstants.FORM_DATA_PREFIX));
            formDataKeys = Sets.newHashSetWithExpectedSize(view.size());

            for (String key : view.keySet()) {
                String fixedPropsFilenameKey = key;
                int i = fixedPropsFilenameKey.lastIndexOf('.');
                String dataKey = fixedPropsFilenameKey.substring(9, i);
                formDataKeys.add(dataKey);

                // Load fixed properties
                String fixedPropsFilename = configuration.get(fixedPropsFilenameKey);
                if (StringUtils.isNotEmpty(fixedPropsFilename)) {
                    InputStream is = null;
                    try {
                        ExtendedProperties fixedProps = new ExtendedProperties();
                        is = configuration.openStream(fixedPropsFilename);
                        fixedProps.load(is);

                        for (Entry<String, String> entry : fixedProps.entrySet()) {
                            setFixedValue(dataKey, entry.getKey(), entry.getValue());
                        }
                    } finally {
                        IOUtils.closeQuietly(is);
                    }
                }
            }
        } catch (IOException ex) {
            throw new JFunkException("Error loading form data keys.", ex);
        }
        return formDataKeys;
    }

    /**
     * Returns the next {@link DataSet} for the specified key. Implementations must override this
     * method.
     * 
     * @param key
     *            The key.
     * @return The {@link DataSet}, or null, if none is available.
     */
    protected abstract DataSet getNextDataSetImpl(String key);

    /**
     * Returns the next {@link DataSet} for the specified key. Fixed values are applied to the
     * result.
     * 
     * @param key
     *            The key.
     * @return The {@link DataSet}, or null, if none is available.
     */
    @Override
    public DataSet getNextDataSet(final String key) {
        DataSet data = getNextDataSetImpl(key);
        if (data != null) {
            copyFixedValues(key, data);
            currentDataSets.put(key, data);
        }
        return data;
    }

    @Override
    public DataSet getCurrentDataSet(final String key) {
        return currentDataSets.get(key);
    }

    @Override
    public Map<String, DataSet> getCurrentDataSets() {
        return currentDataSets;
    }

    private void copyFixedValues(final String key, final DataSet data) {
        Map<String, String> map = fixedValues.get(key);
        if (map != null) {
            for (Entry<String, String> entry : map.entrySet()) {
                data.setFixedValue(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Resets (= removes) a specific fixed value from the specified {@link DataSet}.
     * 
     * @param dataSetKey
     *            The {@link DataSet} key.
     * @param entryKey
     *            The entry key.
     */
    @Override
    public void resetFixedValue(final String dataSetKey, final String entryKey) {
        Map<String, String> map = fixedValues.get(dataSetKey);
        if (map != null) {
            if (map.remove(entryKey) == null) {
                log.warn("Entry " + dataSetKey + "." + entryKey + " could not be found in map of fixed values");
            }
            if (map.isEmpty()) {
                fixedValues.remove(dataSetKey);
            }
        }
        DataSet dataSet = getCurrentDataSets().get(dataSetKey);
        if (dataSet != null) {
            dataSet.resetFixedValue(entryKey);
        }
    }

    /**
     * Resets (= removes) fixed values for the specified {@link DataSet} key.
     * 
     * @param dataSetKey
     *            The {@link DataSet} key.
     */
    @Override
    public void resetFixedValues(final String dataSetKey) {
        fixedValues.remove(dataSetKey);
        DataSet dataSet = getCurrentDataSets().get(dataSetKey);
        if (dataSet != null) {
            dataSet.resetFixedValues();
        }
    }

    /**
     * Resets (= removes) all fixed values.
     */
    @Override
    public void resetFixedValues() {
        fixedValues.clear();
        for (DataSet ds : getCurrentDataSets().values()) {
            ds.resetFixedValues();
        }
    }

    /**
     * Sets a fixed value.
     * 
     * @param dataSetKey
     *            The {@link DataSet} key.
     * @param entryKey
     *            The entry key.
     * @param value
     *            The fixed value.
     */
    @Override
    public void setFixedValue(final String dataSetKey, final String entryKey, final String value) {
        Map<String, String> map = fixedValues.get(dataSetKey);
        if (map == null) {
            map = Maps.newHashMap();
            fixedValues.put(dataSetKey, map);
        }
        map.put(entryKey, value);

        DataSet dataSet = getCurrentDataSet(dataSetKey);
        if (dataSet != null) {
            dataSet.setFixedValue(entryKey, value);
        }
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void copyDataSetKey(final String key, final String newKey) {
        if (currentDataSets.containsKey(key)) {
            DataSet data = currentDataSets.get(key);
            currentDataSets.put(newKey, data);
        }
    }

    @Override
    public void removeDataSet(final String key) {
        if (currentDataSets.containsKey(key)) {
            currentDataSets.remove(key);
        }
    }

    /**
     * Derived classes have to reset themselves.
     */
    protected abstract void doReset();

    @Override
    public void reset() {
        formDataKeys = null;
        currentDataSets.clear();
        fixedValues.clear();
        // Derived classes have to reset themselves
        doReset();
        log.debug("Finished reset");
    }
}