/*
 * DefaultApplicationElementManager.java  $Revision: 1.4 $  $Date: 2007/10/03 04:39:39 $
 *
 * Copyright (C) 2007 Meldcraft Corporation
 *
 * This file is part of Scaffold.
 * 
 * Scaffold is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Scaffold is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Scaffold.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.meldcraft.application;

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

/**
 * @version $Revision: 1.4 $ $Date: 2007/10/03 04:39:39 $
 * @author Rob Richards
 */
public class DefaultApplicationElementManager
    implements ApplicationElementManager
{
    protected ApplicationContext    mContext;
    private Map                     mManagedElements = new HashMap();
    private Object                  mLocked = new Object();

    public DefaultApplicationElementManager(ApplicationContext context)
    {
        mContext = context;
    }

    public Object getApplicationElement(String name)
    {
        Object obj;
        synchronized(mManagedElements)
        {
            obj = mManagedElements.get(name);
            if (obj == null)
            {
                mManagedElements.put(name, mLocked);
            }
            else if (obj == mLocked)
            {
                throw new RuntimeException("Concurrent access to element " + name + " during element initialization");
            }
        }

        if (obj == null)
        {
            obj = setApplicationElement(name, null, null);
        }

        return obj;
    }

    public boolean addManagedElement(String name, Object element)
    {
        boolean ret = false;

        synchronized(mManagedElements)
        {
            Object obj = mManagedElements.get(name);
            if (obj == null)
            {
                mManagedElements.put(name, element);
                ret = true;
            }
            else if (obj == mLocked)
            {
                throw new RuntimeException("Concurrent access to element " + name + " during element initialization");
            }
        }

        return ret;
    }

    protected Object setApplicationElement(String name, Map defaults, Map overrides)
    {
        ManagedElementFactory fac = ManagedElementFactory.getInstance(mContext);
        Object obj = fac.createManagedElement(name, defaults, overrides);
        synchronized(mManagedElements)
        {
            mManagedElements.put(name, obj);
        }

        mContext.contextChanged(name, obj);

        return obj;
    }
}