/*
 * 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.utils.StringHelper;
import com.queplix.core.utils.dao.AbstractPropertyFactory;
import com.queplix.core.utils.dao.InterfaceProperty;

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

/**
 * <p>Cache Facotory. Initializes Cache instances
 * and keep references on them.</p>
 *
 * @author Baranov Andrey [ALB]
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:31:18 $
 * @see Cache
 */

public final class CacheFactory
        extends AbstractPropertyFactory {

    // ================================================================= Constants

    /**
     * 'Name' property name
     */
    public static final String NAME_PROPERTY = "name";

    // Single instance.
    private static final CacheFactory o = new CacheFactory();

    // ================================================================= Variables

    // Map of Cache objects.
    private final Map map = Collections.synchronizedMap(new HashMap());

    // ================================================================= Static methods

    /**
     * Get single instance
     *
     * @return CacheFactory object
     */
    public static CacheFactory getInstance() {
        return o;
    }

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

    /**
     * Get Cache instance by the name <code>name</code>.
     *
     * @param name unique cache name
     * @return Cache
     */
    public Cache getCache(String name) {
        return (Cache) map.get(name);
    }

    /**
     * Returns Map of Cache objects.
     * WARNING: use it carefully for debug purposes only
     *
     * @return Map
     */
    public Map getMap() {
        return map;
    }

    /*
     * No javadoc
     * @see AbstractPropertyFactory#initObject(String,Object[])
     */
    public InterfaceProperty initObject(String className, Object[] params) {

        // Get cache name.
        String cacheName = null;
        Properties prop = __toProperties(params);
        if(prop != null) {
            cacheName = (String) prop.get(NAME_PROPERTY);
        }
        if(StringHelper.isEmpty(cacheName)) {
            throw new NullPointerException(
                    "Cannot find property: " + NAME_PROPERTY);
        }

        // Try to find in Map.
        InterfaceProperty cache = getCache(cacheName);

        if(cache == null) {
            // Create new Cache.
            cache = __initObject(className, prop);

            // Put to the map.
            map.put(cacheName, cache);

            INFO("Cache '" + cacheName + "' created!");
        }

        return cache;
    }

}
