/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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.queplix.core.modules.config.utils;

import com.queplix.core.modules.config.error.NoSuchPropertyException;
import com.queplix.core.utils.cache.Cache;
import com.queplix.core.utils.log.AbstractLogger;
import com.queplix.core.utils.log.Log;

/**
 * System Property Manager.
 *
 * @author [ALB] Baranov Andrey
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:30:16 $
 */

public final class SysPropertyManager {

    // =================================================== Constants and fields

    // Logger.
    private static AbstractLogger logger = Log.getLog(SysPropertyManager.class);

    // ========================================================= Initialization

    // Private constuctor - blocks instantiation.

    private SysPropertyManager() {
    }

    // ========================================================= Public methods

    /**
     * Delete system property.
     *
     * @param propId property id
     */
    public static void deleteProperty(String propId) {

        if(logger.getLogger().isDebugEnabled()) {
            logger.DEBUG("Try to delete system property" +
                    ". Id: " + propId + ".");
        }

        // Delete record.
        ConfigPropertyFactory.getInstance().getSysPropertyDAO().deleteProperty(
                propId);

        // Remove from cache.
        Cache cache = ConfigPropertyFactory.getInstance().getSysPropertyCache();
        cache.remove(propId);
    }

    /**
     * Create system property.
     *
     * @param propId property id
     * @param value  some value
     */
    public static void createProperty(String propId, String value) {

        if(logger.getLogger().isDebugEnabled()) {
            logger.DEBUG("Try to create system property" +
                    ". Id: " + propId +
                    ". Value: " + value + ".");
        }

        // Insert new record.
        ConfigPropertyFactory.getInstance().getSysPropertyDAO().createProperty(
                propId, value);

        // Store in cache.
        Cache cache = ConfigPropertyFactory.getInstance().getSysPropertyCache();
        cache.put(propId, value);
    }

    /**
     * Set system property.
     *
     * @param propId property id
     * @param value  some value
     */
    public static void setProperty(String propId, String value) {

        if(logger.getLogger().isDebugEnabled()) {
            logger.DEBUG("Try to update system property" +
                    ". Id: " + propId +
                    ". Value: " + value + ".");
        }

        // Update record.
        boolean areEqual = false;

        Cache cache = ConfigPropertyFactory.getInstance().getSysPropertyCache();
        if(cache.containsKey(propId)) {
            String cachedValue = (String) cache.get(propId);
            if(cachedValue != null) {
                if(cachedValue.equals(value)) {
                    areEqual = true;
                }
            } else if(value == null) {
                areEqual = true;
            }
        }
        if(!areEqual) {
            int rows = ConfigPropertyFactory.getInstance().getSysPropertyDAO()
                    .updateProperty(propId, value);

            if(rows == 0) {
                // insert record
                createProperty(propId, value);
            } else {
                // store in cache
                cache.put(propId, value);
            }
        }
    }

    /**
     * Get system property.
     *
     * @param propId property id
     * @return String
     * @throws NoSuchPropertyException
     */
    public static String getProperty(String propId)
            throws NoSuchPropertyException {

        if(logger.getLogger().isDebugEnabled()) {
            logger.DEBUG("Try to get system property" +
                    ". Id: " + propId + ".");
        }

        // Try to find out in cache.
        String value = null;

        Cache cache = ConfigPropertyFactory.getInstance().getSysPropertyCache();
        if(!cache.containsKey(propId)) {
            // Load property from database.
            value = ConfigPropertyFactory.getInstance().getSysPropertyDAO()
                    .loadProperty(propId);

            // Store in cache.
            cache.put(propId, value);

        } else {
            // Found in cache!
            if(logger.getLogger().isDebugEnabled()) {
                logger.DEBUG("Property '" + propId + "' found in cache.");
            }
            value = (String) cache.get(propId);
        }

        return value;
    }

    /**
     * Flushes property from the cache.
     *
     * @param propId property id
     */
    public static void flushCache(String propId) {
        Cache cache = ConfigPropertyFactory.getInstance().getSysPropertyCache();
        cache.remove(propId);
    }
}
