/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Cameron Bateman/Oracle - initial API and implementation
 * 
 ********************************************************************************/

package org.eclipse.jst.jsf.designtime;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.LifecycleListener;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils;
import org.eclipse.jst.jsf.designtime.context.AbstractDTExternalContextFactory;
import org.eclipse.jst.jsf.designtime.context.DTFacesContext;
import org.eclipse.jst.jsf.designtime.context.IExternalContextFactoryLocator;
import org.eclipse.jst.jsf.designtime.el.AbstractDTMethodResolver;
import org.eclipse.jst.jsf.designtime.el.AbstractDTPropertyResolver;
import org.eclipse.jst.jsf.designtime.el.AbstractDTVariableResolver;
import org.eclipse.jst.jsf.designtime.internal.BasicExtensionFactory.ExtensionData;
import org.eclipse.jst.jsf.designtime.internal.view.AbstractDTViewHandler;
import org.eclipse.jst.jsf.designtime.internal.view.IDTViewHandler;

/**
 * Per-web-application manager that manages design time information for a
 * corresponding project.
 * 
 * TODO: migrate to managed singleton
 * 
 * @author cbateman
 * 
 */
public final class DesignTimeApplicationManager
{
    private static final String SETTINGS_DIR_NAME = ".settings"; //$NON-NLS-1$
    private static final String ORG_ECLIPSE_JST_JSF_DESIGNTIME_APPMGR_PREFS = "org.eclipse.jst.jsf.designtime.appmgr.prefs"; //$NON-NLS-1$

    private static final String        PROPERTY_QUALIFIER                               = "org.eclipse.jst.jsf.designtime.internal";                     //$NON-NLS-1$
    private static final String        SESSION_PROPERTY_NAME_PROJECT                    = "DesignTimeApplicationManager";                                //$NON-NLS-1$
    private static final QualifiedName SESSION_PROPERTY_KEY_PROJECT                     = new QualifiedName(
                                                                                                PROPERTY_QUALIFIER,
                                                                                                SESSION_PROPERTY_NAME_PROJECT);

    private static final String        PERSIST_PROPERTY_NAME_EXTERNAL_CONTEXT_PROVIDER  = "ExternalContextProvider";                                     //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER   = new QualifiedName(
                                                                                                PROPERTY_QUALIFIER,
                                                                                                PERSIST_PROPERTY_NAME_EXTERNAL_CONTEXT_PROVIDER);

    private static final String        PERSIST_PROPERTY_NAME_VARIABLE_RESOLVER_PROVIDER = "VariableResolverProvider";                                    //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER  = new QualifiedName(
                                                                                                PROPERTY_QUALIFIER,
                                                                                                PERSIST_PROPERTY_NAME_VARIABLE_RESOLVER_PROVIDER);

    private static final String        PERSIST_PROPERTY_NAME_PROPERTY_RESOLVER_PROVIDER = "PropertyResolverProvider";                                    //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER  = new QualifiedName(
                                                                                                PROPERTY_QUALIFIER,
                                                                                                PERSIST_PROPERTY_NAME_PROPERTY_RESOLVER_PROVIDER);

    private static final String        PERSIST_PROPERTY_NAME_METHOD_RESOLVER_PROVIDER   = "MethodResolverProvider";                                      //$NON-NLS-1$
    private static final QualifiedName PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER    = new QualifiedName(
                                                                                                PROPERTY_QUALIFIER,
                                                                                                PERSIST_PROPERTY_NAME_METHOD_RESOLVER_PROVIDER);

    private static final String        PERSIST_PROPERTY_NAME_VIEW_HANDLER               = "ViewHandler";                                                 //$NON-NLS-1$

    private static final String        DEFAULT_EXTERNAL_CONTEXT_ID                      = "org.eclipse.jst.jsf.core.externalcontext.default";            //$NON-NLS-1$

    private static final String        DEFAULT_VARIABLE_RESOLVER_ID                     = "org.eclipse.jst.jsf.core.variableresolver.default.decorative"; //$NON-NLS-1$

    private static final String        DEFAULT_PROPERTY_RESOLVER_ID                     = "org.eclipse.jst.jsf.core.propertyresolver.default.decorative"; //$NON-NLS-1$

    private static final String        DEFAULT_METHOD_RESOLVER_ID                       = "org.eclipse.jst.jsf.core.methodresolver.default";             //$NON-NLS-1$

    private static final String        DEFAULT_VIEW_HANDLER_ID                          = "org.eclipse.jst.jsf.designtime.view.jspviewhandler";          //$NON-NLS-1$

    private static final Object        GET_INSTANCE_LOCK = new Object();

    /**
     * @param project
     * @return the app manager associated with project
     */
    public static DesignTimeApplicationManager getInstance(
            final IProject project)
    {
        if (!hasJSFDesignTime(project))
        {
            return null;
        }

        try
        {
            synchronized (GET_INSTANCE_LOCK)
            {
                DesignTimeApplicationManager manager = (DesignTimeApplicationManager) project
                        .getSessionProperty(SESSION_PROPERTY_KEY_PROJECT);

                if (manager != null && !project.equals(manager._project))
                {
                    if (!manager._isDisposed.get())
                    {
                        manager.dispose();
                    }
                    // bug 147729: pretend we starting with a new project (we kind of are)
                    manager = null;
                }

                if (manager == null)
                {
                    manager = new DesignTimeApplicationManager(project);
                    project.setSessionProperty(SESSION_PROPERTY_KEY_PROJECT,
                            manager);
                }

                return manager;
            }
        }
        catch (final CoreException ce)
        {
            Platform
                    .getLog(JSFCorePlugin.getDefault().getBundle())
                    .log(
                            new Status(
                                    IStatus.ERROR,
                                    JSFCorePlugin.getDefault().getBundle()
                                            .getSymbolicName(),
                                    0,
                                    "Problem loading design time appmanager", new Exception(ce))); //$NON-NLS-1$
        }

        return null;
    }

//    private void checkAndMaybeUpdateProject(final IProject project)
//    {
//    	boolean needsPropertyStore = false;
//
//    	synchronized(this)
//    	{
//    		if (!project.equals(_project))
//    		{
//    			_lifecycleListener.removeResource(_project);
//    			_project = project;
//    			_lifecycleListener.addResource(_project);
//    			_properties.setProject(project);
//    			needsPropertyStore = true;
//    		}
//    	}
//    	
//    	if (needsPropertyStore)
//    	{
//    		_properties.store();
//    	}
//    }

    private synchronized void dispose()
    {
        if (_isDisposed.compareAndSet(false, true))
        {
            // dispose viewhandler
            removeViewHandler();
            _lifecycleListener.dispose();
            _facesContexts.clear();
        }
    }

    /**
     * <p>
     * The criteria for a project having a JSF design time are:
     * </p>
     * 
     * <ul>
     * <li>project is non-null.</li>
     * <li>project is accessible (project.isAccessible() == true)</li>
     * <li>project has a JSF facet (this implies that it's dependent facets are
     * also present).</li>
     * </ul>
     * 
     * @param project
     * @return true if project can have a JSF DesignTimeApplicationManager
     *         associated with it. getInstance(project) uses this determine if
     *         should construct an instance for a project.
     */
    public static boolean hasJSFDesignTime(final IProject project)
    {
        return project != null && project.isAccessible()
                && JSFAppConfigUtils.isValidJSFProject(project);
    }

    // instance definition
    // _project must be writable in case the manager needs to be retargetted
    // after a rename/move etc.
    private final IProject                       _project;
    private final IExternalContextFactoryLocator _locator;
    private final LifecycleListener              _lifecycleListener;
    private final AtomicBoolean                  _isDisposed;
    private final ViewHandlerManager             _viewHandlerManager;
    private final Map<IFile, DTFacesContext>     _facesContexts;

    private DesignTimeApplicationManager(final IProject project)
    {
        _project = project;
        _locator = new MyExternalContextFactoryLocator();
        _isDisposed = new AtomicBoolean();
        _lifecycleListener = new LifecycleListener(_project);
        _lifecycleListener.addListener(new IResourceLifecycleListener()
        {
            public EventResult acceptEvent(final ResourceLifecycleEvent event)
            {
                if (event.getAffectedResource() == _project)
                {
                    if (event.getEventType() == ResourceLifecycleEvent.EventType.RESOURCE_INACCESSIBLE
                            && event.getReasonType() == ResourceLifecycleEvent.ReasonType.RESOURCE_PROJECT_CLOSED)
                    {
                        dispose();
                    }
                }
                return EventResult.getDefaultEventResult();
            }
        });

        final PropertyFileManager properties = new PropertyFileManager(_project);

        _viewHandlerManager = new ViewHandlerManager(properties);
        _facesContexts = new HashMap<IFile, DTFacesContext>();
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @param file
     *            must not be null
     * @return the faces context for the file or null if not found
     */
    public DTFacesContext getFacesContext(final IFile file)
    {
        checkIsDisposed();
        if (!hasDTFacesContext(file))
        {
            return null;
        }

        synchronized (_facesContexts)
        {
            DTFacesContext context = _facesContexts.get(file);
            if (context == null)
            {
                context = new DTFacesContext(file, _locator);
                context.initialize(_lifecycleListener);
                _facesContexts.put(file, context);
            }
            return context;
        }
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * Only files for which a runtime request context will be generated have a
     * corresponding design time context. This is generally confined to view
     * definition files such as JSP's.
     * 
     * General criteria for a file to have a design time faces context are: -
     * the file is non-null and isAccessible() - the file has designtime view
     * handler (getViewHandler(file) != null) and it supports the content type
     * of file.
     * 
     * getFacesContext uses this to decide whether to generate a context for an
     * IFile.
     * 
     * @param file
     * @return true if file has a design time faces context
     */
    public boolean hasDTFacesContext(final IFile file)
    {
        checkIsDisposed();
        final IDTViewHandler viewHandler = getViewHandler();

        if (file != null && file.isAccessible() && viewHandler != null
                && viewHandler.supportsViewDefinition(file))
        {
            return true;
        }
        return false;
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the design time view handler for this webapp (project).
     */
    public IDTViewHandler getViewHandler()
    {
    	checkIsDisposed();
      /* NOTE: it is critical that view handler calls _NEVER_ take the 
         DesignTimeApplicationManager lock.  let ViewHandlerManager manage it
         instead.*/
        return _viewHandlerManager.getViewHandler(_project, _lifecycleListener);
    }

    /**
     * Remove and dispose of any currently registered view handler
     */
    private void removeViewHandler()
    {
        /* NOTE: it is critical that view handler calls _NEVER_ take the 
        DesignTimeApplicationManager lock.  let ViewHandlerManager manage it
        instead.*/
        _viewHandlerManager.removeViewHandler(_project);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * Sets the persistent id on this project that will be used to load the view
     * handler.
     * 
     * @param viewHandlerId
     */
    public void setViewHandlerId(final String viewHandlerId)
    {
        checkIsDisposed();
        /* NOTE: it is critical that view handler calls _NEVER_ take the 
        DesignTimeApplicationManager lock.  let ViewHandlerManager manage it
        instead.*/
        _viewHandlerManager.setViewHandlerId(_project, viewHandlerId);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @param resolverPluginId
     * @throws CoreException
     */
    public synchronized void setExternalContextProvider(
            final String resolverPluginId) throws CoreException
    {
        checkIsDisposed();
        _project.setPersistentProperty(
                PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER,
                resolverPluginId);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the id of the active design time external context provider
     */
    public synchronized String getExternalContextProvider()
    {
    	checkIsDisposed();
        return getResolverId(PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER,
                DEFAULT_EXTERNAL_CONTEXT_ID);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the designtime variable resolver for this application
     */
    public synchronized AbstractDTVariableResolver getVariableResolver()
    {
        checkIsDisposed();
        ExtensionData<AbstractDTVariableResolver> extData = null;

        final String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER);
        if (id != null)
        {
            extData = JSFCorePlugin.getVariableResolvers(id);
        }

        if (extData == null)
        {
            extData = JSFCorePlugin
                    .getVariableResolvers(DEFAULT_VARIABLE_RESOLVER_ID);
        }

        return extData.getInstance(_project);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * Sets the plugin used to determine the designtime variable resolver. To
     * reset to the default, pass null.
     * 
     * @param resolverPluginId
     * @throws CoreException --
     *             if the setting the new value fails
     */
    public synchronized void setVariableResolverProvider(
            final String resolverPluginId) throws CoreException
    {
        checkIsDisposed();
        _project.setPersistentProperty(
                PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER,
                resolverPluginId);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the id of the active design time variable resolver
     */
    public synchronized String getVariableResolverProvider()
    {
    	checkIsDisposed();
        return getResolverId(PERSIST_PROPERTY_KEY_VARIABLE_RESOLVER_PROVIDER,
                DEFAULT_VARIABLE_RESOLVER_ID);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the default property resolver that will be used if no other is
     *         provided. The default property resolver is intended to match the
     *         similar resolver used by the runtime.
     */
    public synchronized AbstractDTPropertyResolver getDefaultPropertyResolver()
    {
        checkIsDisposed();
        return JSFCorePlugin.getPropertyResolver(DEFAULT_PROPERTY_RESOLVER_ID)
                .getInstance(_project);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the designtime property resolver for this application
     */
    public synchronized AbstractDTPropertyResolver getPropertyResolver()
    {
        checkIsDisposed();

        ExtensionData<AbstractDTPropertyResolver> extData = null;

        final String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER);
        if (id != null)
        {
            extData = JSFCorePlugin.getPropertyResolver(id);
        }

        if (extData == null)
        {
            extData = JSFCorePlugin
                    .getPropertyResolver(DEFAULT_PROPERTY_RESOLVER_ID);
        }

        return extData.getInstance(_project);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @param resolverPluginId
     * @throws CoreException --
     *             if setting the provider fails
     */
    public synchronized void setPropertyResolverProvider(
            final String resolverPluginId) throws CoreException
    {
        checkIsDisposed();
        _project.setPersistentProperty(
                PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER,
                resolverPluginId);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the id of the active design time variable resolver
     */
    public synchronized String getPropertyResolverProvider()
    {
        checkIsDisposed();
        return getResolverId(PERSIST_PROPERTY_KEY_PROPERTY_RESOLVER_PROVIDER,
                DEFAULT_PROPERTY_RESOLVER_ID);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the designtime method resolver for this application
     */
    public synchronized AbstractDTMethodResolver getMethodResolver()
    {
    	checkIsDisposed();
        ExtensionData<AbstractDTMethodResolver> extData = null;

        final String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER);
        if (id != null)
        {
            extData = JSFCorePlugin.getMethodResolvers(id);
        }

        if (extData == null)
        {
            extData = JSFCorePlugin
                    .getMethodResolvers(DEFAULT_METHOD_RESOLVER_ID);
        }

        return extData.getInstance(_project);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @param resolverPluginId
     * @throws CoreException --
     *             if setting the plugin fails
     */
    public synchronized void setMethodResolverProvider(
            final String resolverPluginId) throws CoreException
    {
        checkIsDisposed();
        _project
                .setPersistentProperty(
                        PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER,
                        resolverPluginId);
    }

    /**
     * Method is thread-safe and may block the caller.
     * 
     * @return the id of the active design time variable resolver
     */
    public synchronized String getMethodResolverProvider()
    {
        checkIsDisposed();
        return getResolverId(PERSIST_PROPERTY_KEY_METHOD_RESOLVER_PROVIDER,
                DEFAULT_METHOD_RESOLVER_ID);
    }

    private String getResolverId_OLD(final QualifiedName pluginKey)
    {
        String pluginId = null;

        try
        {
            pluginId = _project.getPersistentProperty(pluginKey);
        }
        catch (final CoreException ce)
        {
            JSFCorePlugin.getDefault().getLog().log(
                    new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0,
                            "Error getting plugin property", //$NON-NLS-1$
                            ce));
            pluginId = null;
            // fall-through and use the default
        }

        return pluginId;
    }

    private String getResolverId(final QualifiedName key,
            final String defaultValue)
    {
        String id = defaultValue;

        try
        {
            final String userId = _project.getPersistentProperty(key);

            if (userId != null)
            {
                id = userId;
            }
        }
        catch (final CoreException ce)
        {
            // do nothing; fall through and return default
        }

        return id;
    }

    private class MyExternalContextFactoryLocator implements
            IExternalContextFactoryLocator
    {
        public AbstractDTExternalContextFactory getFactory()
        {
            ExtensionData<AbstractDTExternalContextFactory> extData = null;

            final String id = getResolverId_OLD(PERSIST_PROPERTY_KEY_EXTERNAL_CONTEXT_PROVIDER);
            if (id != null)
            {
                extData = JSFCorePlugin.getExternalContextProviders(id);
            }

            if (extData == null)
            {
                extData = JSFCorePlugin
                        .getExternalContextProviders(DEFAULT_EXTERNAL_CONTEXT_ID);
            }

            return extData.getInstance(_project);
        }
    }

    private void checkIsDisposed()
    {
        // TODO: need to add isDisposed to this and throw an exception
        // for now, we just log what's happening to aid debugging
        if (_isDisposed.get())
        {
            JSFCorePlugin
                    .log(
                            "A call to a disposed DesignTimeApplicationManager was attempted", //$NON-NLS-1$
                            new Throwable(
                                    "This exception is only to record a stack trace")); //$NON-NLS-1$
        }
    }

    private static class ViewHandlerManager
    {
        private final PropertyFileManager _propertyFileManager;

        ViewHandlerManager(final PropertyFileManager properties)
        {
            _propertyFileManager = properties;
        }

        public synchronized void removeViewHandler(final IProject project)
        {
            final String viewHandlerId = _propertyFileManager
                    .getProperty(PERSIST_PROPERTY_NAME_VIEW_HANDLER,
                            DEFAULT_VIEW_HANDLER_ID);

            if (viewHandlerId != null)
            {
                final ExtensionData<AbstractDTViewHandler> extData =
                    JSFCorePlugin.getViewHandlers(viewHandlerId);
                
                if (extData != null)
                {
                    final AbstractDTViewHandler handler = extData.removeInstance(project);
                    if (handler != null)
                    {
                        handler.dispose();
                    }
                }
            }
        }

        public synchronized IDTViewHandler getViewHandler(
                final IProject project, final LifecycleListener listener)
        {
            final String viewHandlerId = _propertyFileManager
                    .getProperty(PERSIST_PROPERTY_NAME_VIEW_HANDLER,
                            DEFAULT_VIEW_HANDLER_ID);

            if (viewHandlerId != null)
            {
                ExtensionData<AbstractDTViewHandler> viewHandlers = JSFCorePlugin
                        .getViewHandlers(viewHandlerId);
                if (viewHandlers == null)
                {
                    viewHandlers = JSFCorePlugin
                            .getViewHandlers(DEFAULT_VIEW_HANDLER_ID);
                }

                final AbstractDTViewHandler viewHandler = viewHandlers
                        .getInstance(project);
                viewHandler.setLifecycleListener(listener);
                return viewHandler;
            }
            return null;
        }

        public void setViewHandlerId(final IProject project,
                final String viewHandlerId)
        {
            // remove any previous handler before the id is lost
            removeViewHandler(project);
            _propertyFileManager.setProperty(
                    PERSIST_PROPERTY_NAME_VIEW_HANDLER, viewHandlerId);
        }
    }
    
    private static class PropertyFileManager
    {
        private final Properties                     _properties;
        private IProject                             _project;

        PropertyFileManager(final IProject project)
        {
            _project = project;
            _properties = new Properties();
            load(_project, _properties);
        }

        private synchronized IProject getProject()
        {
            return _project;
        }

        public void setProperty(final String key, final String value) {
            _properties.setProperty(key, value);
            store();
        }

        public String getProperty(final String key, final String defaultValue) {
            return _properties.getProperty(key, defaultValue);
        }

        public void store()
        {
            final IWorkspaceRunnable storeJob = new IWorkspaceRunnable()
            {
                public void run(IProgressMonitor monitor) throws CoreException {
                    IFile propFile;

                    try {
                        propFile = getPropsFile(getProject());
                        if (propFile != null) {
                            final ByteArrayOutputStream outstream = new ByteArrayOutputStream();
                            // properties will thread-safe save to the array
                            // stream
                            // no further locking is needed since we have
                            // already have a lock
                            // on the workspace sub-tree for the settings file
                            // if this job
                            // is running.
                            _properties.store(outstream, null);
                            propFile.setContents(new ByteArrayInputStream(
                                    outstream.toByteArray()), true, true, null);
                        }
                    } catch (final CoreException e) {
                        JSFCorePlugin.log(e, "Problem storing properties"); //$NON-NLS-1$
                    } catch (final IOException e) {
                        JSFCorePlugin.log(e, "Problem storing properties"); //$NON-NLS-1$
                    }
                }
            };

            final IWorkspace workspace = ResourcesPlugin.getWorkspace();
            
            try
            {
                // need to lock the project tree, since may need to create
                // .settings directory
                workspace.run(storeJob, getProject(), IWorkspace.AVOID_UPDATE,
                        null);
            } catch (CoreException ce)
            {
                JSFCorePlugin.log(ce, "Problem storing properties"); //$NON-NLS-1$
            }
        }

        private static void load(final IProject project,
                final Properties properties)
        {
            try
            {
                final IFile propFile = getPropsFileHandle(project);

                if (propFile != null && propFile.isAccessible())
                {
                    InputStream inStream = null;

                    try
                    {
                        inStream = propFile.getContents();
                        properties.load(inStream);
                    } 
                    finally
                    {
                        if (inStream != null)
                        {
                            inStream.close();
                        }
                    }
                }
            } 
            catch (final CoreException ce)
            {
                JSFCorePlugin.log(ce, "Problem loading properties"); //$NON-NLS-1$
            } 
            catch (final IOException ce)
            {
                JSFCorePlugin.log(ce, "Problem loading properties"); //$NON-NLS-1$
            }
        }

        private static IFile getPropsFile(final IProject project) throws CoreException
        {
            final IFolder folder = project.getFolder(new Path(SETTINGS_DIR_NAME));
            if (!folder.exists())
            {
                folder.create(false, true, null);
            }

            final IFile file = folder.getFile(new Path(ORG_ECLIPSE_JST_JSF_DESIGNTIME_APPMGR_PREFS));

            if (!file.exists())
            {
                file.create(new ByteArrayInputStream(new byte[0]), false, null);
            }

            return file;
        }
        
        /**
         * @param project
         * @return the file handle for the properties file.  Doesn't create the
         * resource if it doesn't exist
         */
        private static IFile getPropsFileHandle(final IProject project)
        {
            return project.getFile(new Path(SETTINGS_DIR_NAME).append(ORG_ECLIPSE_JST_JSF_DESIGNTIME_APPMGR_PREFS));
        }
    }
}
