/*******************************************************************************
 * 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.internal.jsp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.resource.EventResult;
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.common.internal.resource.ResourceLifecycleEvent.EventType;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.ReasonType;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.TraitValueHelper;
import org.eclipse.jst.jsf.common.metadata.query.ITaglibDomainMetaDataModelContext;
import org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.context.symbol.IComponentSymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.SymbolFactory;
import org.eclipse.jst.jsf.context.symbol.source.AbstractContextSymbolFactory;
import org.eclipse.jst.jsf.context.symbol.source.ISymbolConstants;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.designtime.DesignTimeApplicationManager;
import org.eclipse.jst.jsf.designtime.context.DTFacesContext;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Processes a JSP model to determine information of interest about it such
 * as what tags are currently in use.  Listens to the model and updates it's
 * information when the model changes.
 *
 * @author cbateman
 *
 */
public class JSPModelProcessor
{
    /**
     * Pass to force refresh arguments
     */
    public final static boolean FORCE_REFRESH = true;

    /**
     * Pass to runAfter argument of refresh to indicate there is nothing
     * to run when the refresh job completes.
     */
    public final static Runnable NO_RUN_AFTER = null;

    /**
     * Pass to runAfter argument of refresh to indicate that the caller
     * should be blocked until the job completes.
     */
    public final static Runnable RUN_ON_CURRENT_THREAD = new Runnable()
    {
        public void run()
        {
            // do nothing
        }
    };

    /**
     * An init-time setting that is used to stop the model processor from
     * automatically refreshing when the file it is tracking changes. The can
     * only be set once at init is permanent for the static life timpe of
     * JSPModelProcessor.
     *
     * Note that it does not turn off listening for file delete events because
     * the singleton management still needs to know if it can dispose of an
     * instance.
     */
    private final static boolean                         DISABLE_WKSPACE_CHANGE_REFRESH = System
                                                                                                .getProperty("org.eclipse.jst.jsf.jspmodelprocessor.disable.wkspace.change.refresh") != null; //$NON-NLS-1$
    private final static Map<IFile, JSPModelProcessor>  RESOURCE_MAP =
        new HashMap<IFile, JSPModelProcessor>();
    private final static java.util.concurrent.locks.Lock CRITICAL_SECTION =
        new  ReentrantLock();
    private static LifecycleListener  LIFECYCLE_LISTENER;

    /**
     * @param file The file to get the model processor for
     * @return the processor for a particular model, creating it if it does not
     *         already exist
     * @throws CoreException if an attempt to get the model associated with file
     *         fails due to reasons other than I/O problems
     */
    public static JSPModelProcessor get(final IFile file) throws CoreException
    {
        CRITICAL_SECTION.lock();
        try
        {
            if (!file.isAccessible())
            {
                throw new CoreException(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, "File must be accessible")); //$NON-NLS-1$
            }

            JSPModelProcessor processor = RESOURCE_MAP.get(file);

            if (processor == null)
            {
                if (LIFECYCLE_LISTENER == null)
                {
                    LIFECYCLE_LISTENER = new LifecycleListener(file, ResourcesPlugin.getWorkspace());
                }
                else
                {
                    LIFECYCLE_LISTENER.addResource(file);
                }

                processor = new JSPModelProcessor(file,LIFECYCLE_LISTENER);
                RESOURCE_MAP.put(file, processor);
            }

            return processor;
        }
        finally
        {
            CRITICAL_SECTION.unlock();
        }
    }

    /**
     * Disposes of the JSPModelProcessor associated with model
     * @param file the model processor to be disposed
     */
    private static void dispose(final IFile file)
    {
        CRITICAL_SECTION.lock();
        try
        {
            final JSPModelProcessor processor = RESOURCE_MAP.get(file);

            if (processor != null)
            {
                RESOURCE_MAP.remove(file);

                if (!processor.isDisposed())
                {
                    processor.dispose();
                    LIFECYCLE_LISTENER.removeResource(file);
                }

            }

            if (RESOURCE_MAP.isEmpty())
            {
                // if we no longer have any resources being tracked,
                // then dispose the lifecycle listener
                LIFECYCLE_LISTENER.dispose();
                LIFECYCLE_LISTENER = null;
            }
        }
        finally
        {
            CRITICAL_SECTION.unlock();
        }
    }

    private final IFile             _file;
    private LifecycleListener       _lifecycleListener;
    private IResourceLifecycleListener  _resListener;
    private volatile boolean                 _isDisposed;
    private Map<Object, ISymbol>    _requestMap;
    private Map<Object, ISymbol>    _sessionMap;
    private Map<Object, ISymbol>    _applicationMap;
    private Map<Object, ISymbol>    _noneMap;
    private Map<Object, ISymbol>    _viewMap;
    private Map<Object, ISymbol>    _flashMap;

    // used to avoid infinite recursion in refresh.  Must never be null
    private final CountingMutex     _lastModificationStampMonitor = new CountingMutex();

    /**
     * Construct a new JSPModelProcessor for model
     *
     * @param model
     */
    private JSPModelProcessor(final IFile  file, final LifecycleListener lifecycleListener)
    {
        _file = file;
        _lifecycleListener = lifecycleListener;
        _resListener = new IResourceLifecycleListener()
        {
            public EventResult acceptEvent(final ResourceLifecycleEvent event)
            {
                final EventResult result = EventResult.getDefaultEventResult();

                // not interested
                if (!_file.equals(event.getAffectedResource()))
                {
                    return result;
                }

                if (event.getEventType() == EventType.RESOURCE_INACCESSIBLE)
                {
                    dispose(_file);
                }
                else if (event.getEventType() == EventType.RESOURCE_CHANGED)
                {
                    // if the file has changed contents on disk, then
                    // invoke an unforced refresh of the JSP file
                    if (event.getReasonType() == ReasonType.RESOURCE_CHANGED_CONTENTS
                            && !DISABLE_WKSPACE_CHANGE_REFRESH)
                    {
                        refresh(! FORCE_REFRESH, NO_RUN_AFTER);
                    }
                }

                return result;
            }
        };

        lifecycleListener.addListener(_resListener);
    }

    private IDOMModel getModelForFile(final IFile file)
            throws CoreException, IOException
    {
        final IModelManager modelManager =
            StructuredModelManager.getModelManager();

        final IStructuredModel model = modelManager.getModelForRead(file);

        if (model instanceof IDOMModel)
        {
            return (IDOMModel) model;
        }
        else if (model != null)
        {
            // only release from read if we don't find a DOMModelForJSP
            // if the model is correct, it will be released in dispose
            model.releaseFromRead();
        }
        
        JSFCorePlugin.log("Couldn't get valid model for file: "+file.toString(), new Exception()); //$NON-NLS-1$
        return null;
    }

    private void dispose()
    {
        if (!_isDisposed)
        {
            // ensure the resource listener is disposed
            _lifecycleListener.removeListener(_resListener);
            _resListener = null;
            _lifecycleListener = null;

            if (_requestMap != null)
            {
                _requestMap.clear();
                _requestMap = null;
            }

            if (_sessionMap != null)
            {
                _sessionMap.clear();
                _sessionMap = null;
            }

            if (_applicationMap != null)
            {
                _applicationMap.clear();
                _applicationMap = null;
            }

            if (_noneMap != null)
            {
                _noneMap.clear();
                _noneMap = null;
            }

            // mark as disposed
            _isDisposed = true;
        }
    }

    /**
     * @return true if this model processor has been disposed.  Disposed
     * processors should not be used.
     */
    public boolean isDisposed()
    {
        return _isDisposed;
    }

    /**
     * If isModelDirty() returns true, then it means that a call
     * to refresh(false) will trigger a reprocess of the underlying document.
     *
     * @return true if the underlying JSP model is considered to be dirty
     */
    public boolean isModelDirty()
    {
        final long currentModificationStamp = _file.getModificationStamp();
        return _lastModificationStampMonitor.hasChanged(currentModificationStamp);
    }



    /**
     * Refreshes the processor's cache of information from its associated
     * JSP file.
     *
     * @param forceRefresh
     * @param runAfter
     */
    public void refresh(final boolean forceRefresh, final Runnable runAfter)
    {
        if (isDisposed())
        {
            throw new IllegalStateException(
                    "Processor is disposed for file: " + _file.toString()); //$NON-NLS-1$
        }

        if (runAfter == RUN_ON_CURRENT_THREAD)
        {
            try
            {
                runOnCurrentThread(forceRefresh);
            } 
            catch (final CoreException e)
            {
                JSFCorePlugin.log(e, "Running JSP model processor"); //$NON-NLS-1$
            } 
            catch (final OperationCanceledException e)
            {
                // ignore
            } 
        } 
        else
        {
            runOnWorkspaceJob(forceRefresh, runAfter);
        }

    }
    private void runOnWorkspaceJob(final boolean forceRefresh, final Runnable runAfter)
    {
    	WorkspaceJob refreshJob = new WorkspaceJob(NLS.bind(Messages
                .getString("JSPModelProcessor.0"), _file)) { //$NON-NLS-1$
            @Override
            public IStatus runInWorkspace(IProgressMonitor monitor)
                    throws CoreException
            {
                RefreshRunnable runnable = new RefreshRunnable(forceRefresh);
                runnable.run(monitor);
                return Status.OK_STATUS;
            }
        };
        refreshJob.setSystem(true);
        refreshJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
        if (runAfter != null)
        {
            refreshJob.addJobChangeListener(new JobChangeAdapter()
            {
                @Override
                public void done(final IJobChangeEvent event)
                {
                    runAfter.run();
                }
            });
        }
        refreshJob.schedule();
    }

    private void runOnCurrentThread(final boolean forceRefresh) throws CoreException, OperationCanceledException
    {
        ResourcesPlugin.getWorkspace().run(new RefreshRunnable(forceRefresh), _file, 0, null);
    }
    
    private final class RefreshRunnable implements IWorkspaceRunnable
    {
        private final boolean _forceRefresh;

        public RefreshRunnable(final boolean forceRefresh)
        {
            _forceRefresh = forceRefresh;
        }

        public void run(final IProgressMonitor monitor)
                throws CoreException
        {
            synchronized (_lastModificationStampMonitor)
            {
                if (!_lastModificationStampMonitor.compareAndSetSignalled(false, true))
                {
                    // if this calls succeeds, then this thread has obtained the
                    // lock already and has called through here before.
                    // return immediately to ensure that we don't recurse
                    // infinitely
                    return;
                }
                IDOMModel model = null;
                try
                {
                    // only refresh if forced or if the underlying file has
                    // changed
                    // since the last run
                    if (_forceRefresh || isModelDirty())
                    {
                        model = getModelForFile(_file);
                        if (model != null)
                        {
                            refreshInternal(model);
                        }
                        _lastModificationStampMonitor.setModificationStamp(_file.getModificationStamp());
                    }
                }
                catch (final IOException e)
                {
                    IStatus status = new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID,"Error refreshing internal model", e); //$NON-NLS-1$
                    final CoreException e2 = new CoreException(status);
                    throw e2;
                }
                // make sure that we unsignal the monitor before releasing the
                // mutex
                finally
                {
                    _lastModificationStampMonitor.setSignalled(false);
                    if (model != null)
                    {
                        model.releaseFromRead();
                    }
                }
            }
        }
    }



    private void refreshInternal(final IDOMModel model)
    {
        final IStructuredDocumentContext context =
            IStructuredDocumentContextFactory.INSTANCE.getContext(model.getStructuredDocument(), -1);
        final ITaglibContextResolver taglibResolver =
            IStructuredDocumentContextResolverFactory.INSTANCE.getTaglibContextResolver(context);
        final IDOMDocument document = model.getDocument();
        getApplicationMap().clear();
        getRequestMap().clear();
        getSessionMap().clear();

        if (taglibResolver == null) {
            // unusual, but protect against possible NPE
            JSFCorePlugin.log(IStatus.ERROR, "Program Error: taglib resolver is null."); //$NON-NLS-1$
            return;
        }

        //long curTime = System.currentTimeMillis();
        recurseChildNodes(model, document.getChildNodes(), taglibResolver);
        //long netTime = System.currentTimeMillis() - curTime;
        //System.out.println("Net time to recurse document: "+netTime);
    }

    private void recurseChildNodes(final IDOMModel model,
                                   final NodeList nodes,
                                    final ITaglibContextResolver taglibResolver)
    {
        for (int i = 0; i < nodes.getLength(); i++)
        {
            final Node child = nodes.item(i);

            // process attributes at this node before recursing
            processAttributes(model, child, taglibResolver);
            recurseChildNodes(model, child.getChildNodes(), taglibResolver);
        }
    }

    private void processAttributes(final IDOMModel model, final Node node,
                                    final ITaglibContextResolver taglibResolver)
    {
        if (taglibResolver.hasTag(node))
        {
            final String uri =
                taglibResolver.getTagURIForNodeName(node);
            final String elementName = node.getLocalName();

            for (int i = 0; i < node.getAttributes().getLength(); i++)
            {
                final Node attribute = node.getAttributes().item(i);

                processSymbolContrib(model, uri, elementName, attribute);
                processSetsLocale(uri, elementName, attribute);
            }
        }
    }

    private void processSymbolContrib(final IDOMModel model, final String uri, final String elementName, final Node attribute)
    {
        final SymbolContribAggregator  aggregator =
            SymbolContribAggregator.
               create(_file.getProject(), uri, elementName, attribute.getLocalName());

        if (aggregator != null)
        {
            final AbstractContextSymbolFactory factory = aggregator.getFactory();
            final String symbolName = attribute.getNodeValue();

            if (factory != null)
            {
//                long curTime = System.currentTimeMillis();
                final IStructuredDocumentContext context =
                    IStructuredDocumentContextFactory.INSTANCE.
                        getContext(model.getStructuredDocument(),
                           attribute);

                if (factory.supports(context))
                {
                    final List problems = new ArrayList();
                    final ISymbol symbol =
                        factory.create(symbolName,
                                      ISymbolConstants.SYMBOL_SCOPE_REQUEST, //TODO:
                                      context,
                                      problems,
                                      // TODO: add meta-data for signature
                                      new AdditionalContextSymbolInfo(aggregator.getStaticType(), aggregator.getValueExpressionAttr()));

    //                long netTime = System.currentTimeMillis() - curTime;
    //                System.out.println("Time to process loadBundle: "+netTime);

                    if (symbol != null)
                    {
                        updateMap(symbol, aggregator.getScope());
                    }
                }
            }
            else
            {
                final IComponentSymbol componentSymbol =
                    SymbolFactory.eINSTANCE.createIComponentSymbol();
                componentSymbol.setName(symbolName);

                updateMap(componentSymbol, aggregator.getScope());
            }
        }
    }
    
    @SuppressWarnings("deprecation")
    private void processSetsLocale(final String uri, final String elementName, Node attribute)
    {
        LocaleSetAggregator  aggregator = LocaleSetAggregator.create(_file.getProject(), uri, elementName, attribute.getLocalName());

        if (aggregator != null)
        {
            DesignTimeApplicationManager  dtAppMgr =
                DesignTimeApplicationManager.getInstance(_file.getProject());

            if (dtAppMgr != null)
            {
                DTFacesContext facesContext = dtAppMgr.getFacesContext(_file);
                
                if (facesContext != null)
                {
                    facesContext.setLocaleString(attribute.getNodeValue());
                }
            }
        }
    }

   /**
     * @param scopeName - one of "request", "session" or "application" or "view" if JSF2.x
     * @return an unmodifable map containing all known symbols for
     * that scope.  If scopeName is not found, returns the empty map.
     */
    public Map<Object, ISymbol> getMapForScope(final String scopeName)
    {
        final Map<Object, ISymbol> map = getMapForScopeInternal(scopeName);

        if (map != null)
        {
            return Collections.unmodifiableMap(map);
        }

        return Collections.EMPTY_MAP;
    }

    private void updateMap(final ISymbol symbol, final String  scopeName)
    {
        final Map<Object, ISymbol> map = getMapForScopeInternal(scopeName);

        if (map != null)
        {
            map.put(symbol.getName(), symbol);
        }
        else
        {
            Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Throwable())); //$NON-NLS-1$
        }
    }

    private Map<Object, ISymbol> getMapForScopeInternal(final String scopeName)
    {
        if (ISymbolConstants.SYMBOL_SCOPE_REQUEST_STRING.equals(scopeName))
        {
            return getRequestMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_SESSION_STRING.equals(scopeName))
        {
            return getSessionMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_APPLICATION_STRING.equals(scopeName))
        {
            return getApplicationMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_NONE_STRING.equals(scopeName))
        {
            return getNoneMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_VIEW_STRING.equals(scopeName))
        {
            return getViewMap();
        }
        else if (ISymbolConstants.SYMBOL_SCOPE_FLASH_STRING.equals(scopeName))
        {
            return getFlashMap();
        }

        Platform.getLog(JSFCorePlugin.getDefault().getBundle()).log(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, 0, "Scope not found: "+scopeName, new Throwable())); //$NON-NLS-1$
        return null;

    }

    private Map getRequestMap()
    {
        if (_requestMap == null)
        {
            _requestMap = new HashMap<Object, ISymbol>();
        }

        return _requestMap;
    }

    private Map<Object, ISymbol> getSessionMap()
    {
        if (_sessionMap == null)
        {
            _sessionMap = new HashMap<Object, ISymbol>();
        }

        return _sessionMap;
    }

    private Map<Object, ISymbol> getApplicationMap()
    {
        if (_applicationMap == null)
        {
            _applicationMap = new HashMap<Object, ISymbol>();
        }

        return _applicationMap;
    }

    private Map<Object, ISymbol> getNoneMap()
    {
        if (_noneMap == null)
        {
            _noneMap = new HashMap<Object, ISymbol>();
        }

        return _noneMap;
    }
    
    private Map<Object, ISymbol> getViewMap()
    {
        if (_viewMap == null)
        {
        	_viewMap = new HashMap<Object, ISymbol>();
        }

        return _viewMap;
    }
    
    private Map<Object, ISymbol> getFlashMap()
    {
        if (_flashMap == null)
        {
        	_flashMap = new HashMap<Object, ISymbol>();
        }

        return _flashMap;
    }

    /**
     * Aggregates the sets-locale meta-data
     *
     * @author cbateman
     */
    private static class LocaleSetAggregator
    {
        private final static String SETS_LOCALE = "sets-locale"; //$NON-NLS-1$

        private static LocaleSetAggregator create(final IProject project,
                                              final String uri,
                                              final String elementName, final String attributeName)
        {
            final ITaglibDomainMetaDataModelContext mdContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, uri);
            final Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, elementName+"/"+attributeName, SETS_LOCALE); //$NON-NLS-1$

            if (TraitValueHelper.getValueAsBoolean(trait))
            {
                return new LocaleSetAggregator();
            }

            return null;
        }
    }

    /**
     * Aggregates all the symbol contributor meta-data into a single object
     *
     * @author cbateman
     *
     */
    private static class SymbolContribAggregator
    {
        private final static String CONTRIBUTES_VALUE_BINDING =
            "contributes-value-binding"; //$NON-NLS-1$
        private final static String VALUE_BINDING_SCOPE = "value-binding-scope"; //$NON-NLS-1$
        private final static String VALUE_BINDING_SYMBOL_FACTORY =
            "value-binding-symbol-factory"; //$NON-NLS-1$
        private final static String STATIC_TYPE_KEY = "optional-value-binding-static-type"; //$NON-NLS-1$
        private final static String VALUEEXPRESSION_ATTR_NAME_KEY = "optional-value-binding-valueexpr-attr"; //$NON-NLS-1$

        /**
         * @param attributeName
         * @return a new instance only if attributeName is a symbol contributor
         */
        private static SymbolContribAggregator create(final IProject project,
                                              final String uri,
                                              final String elementName,
                                              final String attributeName)
        {
            final String entityKey = elementName+"/"+attributeName; //$NON-NLS-1$
            final ITaglibDomainMetaDataModelContext mdContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, uri);
            Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, CONTRIBUTES_VALUE_BINDING);

            final boolean contribsValueBindings = TraitValueHelper.getValueAsBoolean(trait);

            if (contribsValueBindings)
            {
                String scope = null;
                String symbolFactory = null;

                trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, VALUE_BINDING_SCOPE);
                scope = TraitValueHelper.getValueAsString(trait);

                if (scope != null && !scope.equals("")) //$NON-NLS-1$
                {
                    trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, VALUE_BINDING_SYMBOL_FACTORY);
                    symbolFactory = TraitValueHelper.getValueAsString(trait);
                }

                trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, STATIC_TYPE_KEY);

                String staticType = null;

                if (trait != null)
                {
                    staticType = TraitValueHelper.getValueAsString(trait);
                }

                trait = TaglibDomainMetaDataQueryHelper.getTrait(mdContext, entityKey, VALUEEXPRESSION_ATTR_NAME_KEY);

                String valueExprAttr = null;
                if (trait != null)
                {
                    valueExprAttr = TraitValueHelper.getValueAsString(trait);
                }

                return new SymbolContribAggregator(scope, symbolFactory, staticType, valueExprAttr);
            }

            return null;
        }

        private final Map<String, String>   _metadata = new HashMap<String, String>(4);

        SymbolContribAggregator(final String scope, final String factory, final String staticType, final String valueExprAttr)
        {
            _metadata.put("scope", scope); //$NON-NLS-1$
            _metadata.put("factory", factory); //$NON-NLS-1$
            _metadata.put("staticType", staticType); //$NON-NLS-1$
            _metadata.put("valueExprAttr", valueExprAttr); //$NON-NLS-1$
        }

        /**
         * @return the scope
         */
        public String getScope()
        {
            return _metadata.get("scope"); //$NON-NLS-1$
        }

        /**
         * @return the factory
         */
        public AbstractContextSymbolFactory getFactory()
        {
            return JSFCommonPlugin.getSymbolFactories().get(_metadata.get("factory")); //$NON-NLS-1$
        }

        public String getStaticType()
        {
            return _metadata.get("staticType"); //$NON-NLS-1$
        }

        public String getValueExpressionAttr()
        {
            return _metadata.get("valueExprAttr"); //$NON-NLS-1$
        }
    }

    private final static class CountingMutex extends Object
    {
        private long                    _lastModificationStamp = -1;
        private boolean _signalled = false;
        private final ILock _lock = Job.getJobManager().newLock();

        /**
         * Similar to AtomicBoolean.compareAndSet.  If the signalled flag
         * is the same as expect then update is written to the flag.  Otherwise,
         * nothing happens.
         * @param expect the value of _signalled where update occurs
         * @param update the value written to _signalled if _signalled == expect
         * 
         * @return true if the signalled flag was set to update
         */
        public boolean compareAndSetSignalled(final boolean expect, final boolean update) {
            final boolean[] value = new boolean[1];
            safeRun(new Runnable() {
            public void run()
            {
                if (_signalled == expect)
                {
                    _signalled = update;
                    value[0] = true;
                }
                else
                {
                    value[0] = false;
                }
            }});      
            return value[0];
        }

        public boolean hasChanged(final long currentModificationStamp)
        {
            final boolean[] value = new boolean[1];
            safeRun(new Runnable() {
            public void run()
            {
                value[0] = (_lastModificationStamp != currentModificationStamp);
            }});                
            return value[0];
        }

        /**
         * @param signalled
         */
        public void setSignalled(final boolean signalled) {
            safeRun(new Runnable() {
                public void run()
                {
                    _signalled = signalled;
                }});
        }

        public void setModificationStamp(final long newValue)
        {
            safeRun(new Runnable() {
                public void run()
                {
                    _lastModificationStamp = newValue;
                }});
        }
        
        private void safeRun(final Runnable runnable)
        {
            _lock.acquire();
            try
            {
                runnable.run();
            }
            finally
            {
                _lock.release();
            }
        }
    }
}
