/*
 * 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.client.common;

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

/**
 * Cache created objects.
 *
 * @author Sergey Kozmin
 * @since 10.04.2007
 */
public abstract class AbstractCachingFactory {
    private static final Object EMPTY_OBJECT = new Object();

    private Map cachedObjects = new HashMap();

    /**
     * Create object for the given key.
     *
     * @param key key for object
     * @return object to be cached
     */
    protected abstract Object createObject(String key);

    /**
     * In this method, user should initialize created object, before it will
     * be cached. That is the same object, that was created by calling.
     * This method is created to separate creating and initialization methods,
     * so that could be implemented in different classes.
     * {@link #createObject(String)} method.
     *
     * @param key key for object
     * @param obj object
     */
    protected abstract void initObject(String key, Object obj);

    protected Object getObject(String key) {
        Object value = cachedObjects.get(key);
        if(value == null) {//value wasn't put to map
            value = createObject(key);
            initObject(key, value);
            if(value == null) {
                cachedObjects.put(key, EMPTY_OBJECT);
            } else {
                cachedObjects.put(key, value);
            }
        } else if(value == EMPTY_OBJECT) {//empty value was put to map last time
            value = null;
        }
        return value;
    }

    protected void clearCache(String key) {
        cachedObjects.remove(key);
    }

    protected void clearCache() {
        cachedObjects.clear();
    }
}
