/*
 * 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.utils.cache;

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.utils.StringHelper;
import com.queplix.core.utils.dao.AbstractPropertyFactory;
import com.queplix.core.utils.log.AbstractLogger;
import com.queplix.core.utils.log.Log;
import org.jboss.cache.PropertyConfigurator;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>JBoss cache manager. Serves as singleton wrapper for JBoss TreeCache</p>
 *
 * @author [ALB] Baranov Andrey
 * @version 1.0
 */

public final class JBossCacheManager {

    // ------------------------------------------------------- Constants

    /**
     * Property JBOSS Cache external file.
     * Use JVM parameter to set it. Ex.: -DjbossCache.configuration=/path/to/jbossCache.*
     */
    public static final String jbossCacheConfig = System.getProperty(
            "jbossCache.configuration");

    // Singleton.
    private static final JBossCacheManager o = new JBossCacheManager();

    // ------------------------------------------------------- Fields

    // Logger.
    protected AbstractLogger logger = Log.getLog(getClass());

    // Map of <code>JBossCacheWrapper</code> objects.
    protected Map map;

    // ------------------------------------------------------- Public methods

    //
    // Constructors.
    //

    private JBossCacheManager() {
        map = Collections.synchronizedMap(new HashMap());
    }

    public static final JBossCacheManager getInstance() {
        return o;
    }

    /**
     * JBoss cache getter.
     *
     * @return JBossCacheWrapper
     */
    public JBossCacheWrapper get() {
        if(!StringHelper.isEmpty(jbossCacheConfig)) {
            return get(jbossCacheConfig);
        } else {
            return get(AbstractPropertyFactory.SYS_CONFIG_PREFIX
                    + "jbosscache-service.xml");
        }
    }

    /**
     * JBoss cache getter.
     *
     * @param configName cache config name
     * @return JBossCacheWrapper
     */
    public synchronized JBossCacheWrapper get(String configName) {
        JBossCacheWrapper cache = (JBossCacheWrapper) map.get(configName);

        if(cache == null) {
            try {
                cache = new JBossCacheWrapper(configName);
                PropertyConfigurator config = new PropertyConfigurator();
                config.configure(cache, configName);
                cache.startService();
            } catch (Exception ex) {
                logger.ERROR(ex);
                throw new GenericSystemException(ex);
            }

            map.put(configName, cache);

            logger.INFO(
                    "New JBoss TreeCache cache '" + configName + "' created!");
        }

        // Ok.
        return cache;
    }
}
