/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation and others.
 * 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view.model.jsp.analyzer;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.internal.proxy.core.IBeanProxy;
import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
import org.eclipse.jem.internal.proxy.core.IConfigurationContributor;
import org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory;
import org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry;
import org.eclipse.jem.internal.proxy.ide.IDERegistration;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ValidatorTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IJSFTagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IHandlerTagElement.TagHandlerType;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IJSFTagElement.TagType;
import org.eclipse.jst.jsf.core.JSFVersion;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.BeanProxyWrapper;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.ProxyException;
import org.eclipse.jst.jsf.designtime.internal.view.DTComponentIntrospector;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDComponentTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDConverterTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagHandlerElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDValidatorTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.IAttributeAdvisor.NullAttributeAdvisor;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;

/**
 * Utility class supporting methods to derive information from JSP tag
 * definitions (TLD)
 * 
 * @author cbateman
 * 
 */
public final class TagAnalyzer
{
    private static final String JAVAX_FACES_WEBAPP_CONVERTER_TAG = "javax.faces.webapp.ConverterTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_CONVERTER_ELTAG = "javax.faces.webapp.ConverterELTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_VALIDATOR_TAG = "javax.faces.webapp.ValidatorTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_VALIDATOR_ELTAG = "javax.faces.webapp.ValidatorELTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_FACET_TAG = "javax.faces.webapp.FacetTag"; //$NON-NLS-1$

    // private static final String JAVAX_FACES_WEBAPP_ACTIONLISTENER_TAG =
    // "javax.faces.webapp.ActionListenerTag";
    // private static final String JAVAX_FACES_WEBAPP_VALUECHANGELISTENER_TAG =
    // "javax.faces.webapp.ValueChangeListenerTag";
    private static final String JAVAX_FACES_WEBAPP_ATTRIBUTE_TAG = "javax.faces.webapp.AttributeTag"; //$NON-NLS-1$

    private final static Set<String> COMPONENT_TAG_HANDLER_TYPES_JSF11;
    private final static Set<String> COMPONENT_TAG_HANDLER_TYPES_JSF12;

    private final static Set<String> CONVERTER_TAG_HANDLER_TYPES_JSF11 = Collections
            .singleton(JAVAX_FACES_WEBAPP_CONVERTER_TAG);
    private final static Set<String> CONVERTER_TAG_HANDLER_TYPES_JSF12;

    private final static Set<String> VALIDATOR_TAG_HANDLER_TYPES_JSF11 = Collections
            .singleton(JAVAX_FACES_WEBAPP_VALIDATOR_TAG);
    private final static Set<String> VALIDATOR_TAG_HANDLER_TYPES_JSF12;

    private final static Set<String> FACET_TAG_HANDLER = Collections
            .singleton(JAVAX_FACES_WEBAPP_FACET_TAG);
    private final static Set<String> ATTRIBUTE_TAG_HANDLER = Collections
            .singleton(JAVAX_FACES_WEBAPP_ATTRIBUTE_TAG);
    // private final static Set<String> ACTIONLISTENER_TAG_HANDLER = Collections
    // .singleton(JAVAX_FACES_WEBAPP_ACTIONLISTENER_TAG);
    // private final static Set<String> VALUECHANGELISTENER_TAG_HANDLER =
    // Collections
    // .singleton(JAVAX_FACES_WEBAPP_VALUECHANGELISTENER_TAG);

    private final static Set<String> ALL_HANDLER_TAGS;

    static
    {
        // components
        // JSF 1.1
        Set<String> set = new HashSet<String>(8);
        set.add("javax.faces.webapp.UIComponentTag"); //$NON-NLS-1$
        set.add("javax.faces.webapp.UIComponentBodyTag"); //$NON-NLS-1$
        COMPONENT_TAG_HANDLER_TYPES_JSF11 = Collections.unmodifiableSet(set);

        // JSF 1.2
        set = new HashSet<String>(8);
        set.add("javax.faces.webapp.UIComponentTag"); //$NON-NLS-1$
        set.add("javax.faces.webapp.UIComponentBodyTag"); //$NON-NLS-1$
        set.add("javax.faces.webapp.UIComponentELTag"); //$NON-NLS-1$
        COMPONENT_TAG_HANDLER_TYPES_JSF12 = Collections.unmodifiableSet(set);

        // converters
        set = new HashSet<String>(8);
        set.add(JAVAX_FACES_WEBAPP_CONVERTER_TAG);
        set.add(JAVAX_FACES_WEBAPP_CONVERTER_ELTAG);
        CONVERTER_TAG_HANDLER_TYPES_JSF12 = Collections.unmodifiableSet(set);

        // validators
        set = new HashSet<String>(8);
        set.add(JAVAX_FACES_WEBAPP_VALIDATOR_TAG);
        set.add(JAVAX_FACES_WEBAPP_VALIDATOR_ELTAG);
        VALIDATOR_TAG_HANDLER_TYPES_JSF12 = Collections.unmodifiableSet(set);

        // tag handlers
        ALL_HANDLER_TAGS = new HashSet<String>();
        ALL_HANDLER_TAGS.addAll(FACET_TAG_HANDLER);
        ALL_HANDLER_TAGS.addAll(ATTRIBUTE_TAG_HANDLER);
        // ALL_HANDLER_TAGS.addAll(VALUECHANGELISTENER_TAG_HANDLER);
        // ALL_HANDLER_TAGS.addAll(ACTIONLISTENER_TAG_HANDLER);
    }

    /**
     * Tries to determine the component type of the component that corresponds
     * to the JSP tag defined by tldDecl.
     * 
     * @param tldDecl
     * @param project
     * @return get the component type from the tag definition or null if none.
     */
    public static String findComponentType(final TLDElementDeclaration tldDecl,
            final IProject project)
    {
        final String className = tldDecl.getTagclass();

        final IConfigurationContributor[] contributor = new IConfigurationContributor[]
        { new ServletBeanProxyContributor(project) };

        ProxyFactoryRegistry registry = null;
        try
        {
            registry = getProxyFactoryRegistry(contributor, project);
    
            if (registry != null)
            {

                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
                final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                        classTypeProxy);
    
                try
                {
                    classTypeWrapper.init();
                    return classTypeWrapper.callStringMethod("getComponentType"); //$NON-NLS-1$
                }
                catch (final ProxyException tp)
                {
                    if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
                    {
                        JSFCoreTraceOptions.log("TagAnalyzer.findComponentType", tp); //$NON-NLS-1$
                    }
                }
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;
    }

    /**
     * Tries to introspect tldDecl's tag class to determine what the identifier
     * of the underlying Converter that is used to register it in the app config
     * 
     * @param tldDecl
     * @param project
     * @return the converter type identifier for the tldDecl or null if not
     *         found
     */
    public static String findConverterType(final TLDElementDeclaration tldDecl,
            final IProject project)
    {
        // TODO: allow for pluggable resolver?

        // This one is more hacky and less prone to success than the component
        // type finder because the ConverterTag doesn't initialize its type
        // field on construction. Instead, both MyFaces and RI seem to do it
        // based on the doStartTag method. They also don't provide a standard
        // interface for acquiring the id so instead we make some guess on
        // the internal field name.
        ProxyFactoryRegistry registry = null;
        try
        {
            final String className = tldDecl.getTagclass();
    
            final IConfigurationContributor[] contributor = new IConfigurationContributor[]
            { new ServletBeanProxyContributor(project) };
            registry = getProxyFactoryRegistry(
                    contributor, project);
    
            if (registry != null)
            {
                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
    
                try
                {
                    final IType type = JavaCore.create(project).findType(className);
    
                    if (type != null
                            && DTComponentIntrospector
                                    .isTypeNameInstanceOfClass(
                                            type,
                                            Collections
                                                    .singleton(JAVAX_FACES_WEBAPP_CONVERTER_ELTAG)))
                    {
                        return findConverterType_InELTag(factory, classTypeProxy,project);
                    }
                    // the assumption is that this is a component tag, so we assume
                    // it is one.
                    else if (type != null
                            && DTComponentIntrospector
                                    .isTypeNameInstanceOfClass(
                                            type,
                                            Collections
                                                    .singleton(JAVAX_FACES_WEBAPP_CONVERTER_TAG)))
                    {
                        return findConverterType_InTag(factory, classTypeProxy, project);
                    }
                }
                catch (final JavaModelException jme)
                {
                    // suppress for now
                }
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;
    }

    private static String findConverterType_InTag(
            final IStandardBeanTypeProxyFactory factory,
            final IBeanTypeProxy classTypeProxy, final IProject project)
    {
        final IBeanTypeProxy nullPageContextType = factory
                .getBeanTypeProxy("javax.servlet.jsp.PageContext"); //$NON-NLS-1$
        final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                classTypeProxy);

        try
        {
            classTypeWrapper.init();

            callSuppressExceptions(classTypeWrapper, "setPageContext", //$NON-NLS-1$
                    new IBeanProxy[]
                    { null }, new IBeanTypeProxy[]
                    { nullPageContextType });
            callSuppressExceptions(classTypeWrapper, "doStartTag"); //$NON-NLS-1$

            final IBeanTypeProxy converterProxy = factory
                    .getBeanTypeProxy(JAVAX_FACES_WEBAPP_CONVERTER_TAG);

            // hopefully doStartTag set the converter field before it
            // failed.
            // now try to guess what it's called
            String converterId = getStringField(classTypeWrapper,
                    converterProxy, "converterId"); //$NON-NLS-1$

            if (converterId != null)
            {
                return converterId;
            }

            converterId = getStringField(classTypeWrapper, converterProxy,
                    "_converterId"); //$NON-NLS-1$

            if (converterId != null)
            {
                return converterId;
            }

            // no? look for a CONVERTER_ID
            converterId = getStringField(classTypeWrapper, classTypeProxy,
                    "CONVERTER_ID"); //$NON-NLS-1$
        }
        catch (final ProxyException tp)
        {
            // fall through
        }
        return null;
    }

    private static String findConverterType_InELTag(
            final IStandardBeanTypeProxyFactory factory,
            final IBeanTypeProxy classTypeProxy, final IProject project)
    {
        final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                classTypeProxy);
        final IBeanTypeProxy elExpressionType = factory
                .getBeanTypeProxy("javax.el.ValueExpression"); //$NON-NLS-1$

        if (elExpressionType == null)
        {
            return null;
        }

        try
        {
            classTypeWrapper.init();

            callSuppressExceptions(classTypeWrapper, "doStartTag"); //$NON-NLS-1$

            // no? look for a CONVERTER_ID
            final IBeanProxy converterId = getFieldInParents(classTypeWrapper,
                    classTypeProxy, "CONVERTER_ID_EXPR"); //$NON-NLS-1$

            if (converterId != null)
            {
                converterId.getTypeProxy().isKindOf(elExpressionType);
                final BeanProxyWrapper elExprValue = new BeanProxyWrapper(project,
                        converterId.getTypeProxy());
                final String value = elExprValue
                        .callStringMethod("getExpressionString"); //$NON-NLS-1$
                System.out.println("Expression string:" + value); //$NON-NLS-1$
            }

            //            
            //
            // final IBeanTypeProxy converterProxy = factory
            // .getBeanTypeProxy(JAVAX_FACES_WEBAPP_CONVERTER_TAG);

        }
        catch (final ProxyException tp)
        {
            // fall through
        }
        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return the validator type identifier for the tldDecl or null if not
     *         found
     */
    public static String findValidatorType(final TLDElementDeclaration tldDecl,
            final IProject project)
    {
        // TODO: allow for pluggable resolver?

        // This one is more hacky and less prone to success than the component
        // type finder because the Validator doesn't initialize its type
        // field on construction. Instead, both MyFaces and RI seem to do it
        // based on the doStartTag method. They also don't provide a standard
        // interface for acquiring the id so instead we make some guess on
        // the internal field name.
        final String className = tldDecl.getTagclass();

        final IConfigurationContributor[] contributor = new IConfigurationContributor[]
        { new ServletBeanProxyContributor(project) };

        ProxyFactoryRegistry registry = null;

        try
        {
            registry = getProxyFactoryRegistry(contributor, project);
    
            if (registry != null)
            {
                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
                final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                        classTypeProxy);
                final IBeanTypeProxy converterProxy = factory
                        .getBeanTypeProxy(JAVAX_FACES_WEBAPP_VALIDATOR_TAG);
                try
                {
                    classTypeWrapper.init();
    
                    callSuppressExceptions(classTypeWrapper, "doStartTag"); //$NON-NLS-1$
                    callSuppressExceptions(classTypeWrapper, "createValidator"); //$NON-NLS-1$
    
                    // hopefully doStartTag set the converter field before it
                    // failed.
                    // now try to guess what it's called
                    String validatorId = getStringField(classTypeWrapper,
                            converterProxy, "validatorId"); //$NON-NLS-1$
    
                    if (validatorId != null)
                    {
                        return validatorId;
                    }
    
                    validatorId = getStringField(classTypeWrapper, converterProxy,
                            "_validatorId"); //$NON-NLS-1$
    
                    if (validatorId != null)
                    {
                        return validatorId;
                    }
    
                    // no? then see if there's a VALIDATOR_ID field *on the tag*
                    validatorId = getStringField(classTypeWrapper, classTypeProxy,
                            "VALIDATOR_ID"); //$NON-NLS-1$
    
                    if (validatorId != null)
                    {
                        return validatorId;
                    }
                }
                catch (final ProxyException tp)
                {
                    // fall through
                }
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;

    }

    private static IBeanProxy getFieldInParents(
            final BeanProxyWrapper classTypeWrapper,
            final IBeanTypeProxy typeProxy, final String fieldName)
    {
        try
        {
            return classTypeWrapper.getFieldValueIncludeParents(fieldName,
                    typeProxy);
        }
        catch (final ProxyException e)
        {
            // suppress
        }

        return null;
    }

    private static String getStringField(
            final BeanProxyWrapper classTypeWrapper,
            final IBeanTypeProxy typeProxy, final String fieldName)
    {
        try
        {
            return classTypeWrapper.getStringFieldValue(fieldName, typeProxy);
        }
        catch (final ProxyException e)
        {
            // suppress
        }

        return null;
    }

    private static void callSuppressExceptions(
            final BeanProxyWrapper classTypeWrapper, final String methodName)
    {
        try
        {
            classTypeWrapper.call(methodName);
        }
        catch (final ProxyException tp)
        {
            // suppress this since it may well throw an exception
            // depending on what assumptions the tag class is making
            // that won't be true because we're not in a servlet
        }
    }

    private static void callSuppressExceptions(
            final BeanProxyWrapper classTypeWrapper, final String methodName,
            final IBeanProxy[] args, final IBeanTypeProxy[] argTypes)
    {
        try
        {
            classTypeWrapper.call(methodName, args, argTypes);
        }
        catch (final ProxyException tp)
        {
            // suppress this since it may well throw an exception
            // depending on what assumptions the tag class is making
            // that won't be true because we're not in a servlet
        }

    }

    /**
     * @param project
     * @return a new proxy factory registry or null;
     * 
     * TODO: caching?
     */
    private static ProxyFactoryRegistry getProxyFactoryRegistry(
            final IConfigurationContributor[] configuration,
            final IProject project)
    {
        try
        {
            return IDERegistration.startAnImplementation(configuration, false,
                    project, project.getName(), JSFCorePlugin.PLUGIN_ID,
                    new NullProgressMonitor());
        }
        catch (final CoreException e)
        {
            JSFCorePlugin.log("Error starting vm for project: " //$NON-NLS-1$
                    + project.getName(), e);
        }

        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return the tag element for the tldDecl
     */
    public static TLDTagElement createTLDTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
        {
            JSFCoreTraceOptions
                    .log(String
                            .format(
                                    "TagAnalyzer.createTLDTagElement: Start tld=%s, project=%s", //$NON-NLS-1$
                                    tldDecl.getNodeName(), project.getName()));
        }
        long startTime = 0;
        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
        {
            startTime = System.nanoTime();
        }

        try
        {
            final IJavaProject javaProject = JavaCore.create(project);
            final String typeName = tldDecl.getTagclass();

            if (typeName == null
                    || JavaConventions.validateJavaTypeName(typeName,
                            JavaCore.VERSION_1_3,
                            JavaCore.VERSION_1_3).getSeverity() == IStatus.ERROR)
            {
                JSFCorePlugin.log(
                        "Bad tag class name in " + tldDecl.toString(), //$NON-NLS-1$
                        new Throwable());
                return null;
            }

            final IType type = javaProject.findType(typeName);
            
            if (type == null)
            {
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
                {
                    JSFCoreTraceOptions.log("Type not found for: "+typeName); //$NON-NLS-1$
                }
                return null;
            }
            final TagType tagType = getJSFComponentTagType(type, project);

            if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
            {
                JSFCoreTraceOptions.log(String.format(
                        "Tag class type=%s\nTag type=%s", type, tagType)); //$NON-NLS-1$
            }

            if (tagType == TagType.COMPONENT)
            {
                final TLDTagElement element = createComponentTagElement(tldDecl, project);
                
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create component tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
            else if (tagType == TagType.CONVERTER)
            {
                final TLDTagElement element =  createConverterTagElement(tldDecl, project);
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create converter tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
            else if (tagType == TagType.VALIDATOR)
            {
                final TLDTagElement element =  createValidatorTagElement(tldDecl, project);
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create validator tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
            else if (tagType == TagType.HANDLER)
            {
                final TLDTagElement element =  createHandlerTagElement(tldDecl, type);
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create handler tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
        }
        catch (final JavaModelException jme)
        {
            JSFCorePlugin.log(jme, "Trying to get type for TLD"); //$NON-NLS-1$
        }

        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return a component tag element for tldDecl
     */
    public static TLDTagElement createComponentTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        final String componentType = findComponentType(tldDecl, project);

        if (componentType != null)
        {
            final String componentClass = DTComponentIntrospector
                    .findComponentClass(componentType, project);

            if (componentClass != null && !"".equals(componentClass.trim())) //$NON-NLS-1$
            {
                final ComponentTypeInfo typeInfo = DTComponentIntrospector
                        .getComponent(componentType, componentClass, project,
                                new IConfigurationContributor[]
                                {new ServletBeanProxyContributor(project)});

                if (typeInfo != null)
                {
                    final TLDComponentTagElement tagElement = new TLDComponentTagElement(
                            tldDecl, typeInfo, new NullAttributeAdvisor());
                    return tagElement;
                }
            }
        }

        // TODO: really return null?
        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return a converter tag element for tldDecl
     */
    public static TLDTagElement createConverterTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        final String converterId = findConverterType(tldDecl, project);

        if (converterId != null)
        {
            final String converterClass = DTComponentIntrospector
                    .findConverterClass(converterId, project);

            if (converterClass != null && !"".equals(converterClass.trim())) //$NON-NLS-1$
            {
                final ConverterTypeInfo typeInfo = DTComponentIntrospector
                        .getConverter(converterId, converterClass);
                final TLDConverterTagElement tagElement = new TLDConverterTagElement(
                        tldDecl, typeInfo, new NullAttributeAdvisor());
                return tagElement;
            }
        }

        // we know (actually we assume by contract) that this a converter
        // so create an unknown converter tag for it
        return new TLDConverterTagElement(tldDecl, ConverterTypeInfo.UNKNOWN, new NullAttributeAdvisor());
    }

    /**
     * @param tldDecl
     * @param project
     * @return a validator tag element for the tldDec
     */
    public static TLDTagElement createValidatorTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        final String validatorId = findValidatorType(tldDecl, project);

        if (validatorId != null)
        {
            final String validatorClass = DTComponentIntrospector
                    .findValidatorClass(validatorId, project);

            if (validatorClass != null && !"".equals(validatorClass.trim())) //$NON-NLS-1$
            {
                final ValidatorTypeInfo typeInfo = DTComponentIntrospector
                        .getValidator(validatorId, validatorClass);
                final TLDValidatorTagElement tagElement = new TLDValidatorTagElement(
                        tldDecl, typeInfo, new NullAttributeAdvisor());
                return tagElement;
            }
        }
        // we know (actually we assume by contract) that this a validator
        // so create an unknown converter tag for it
        return new TLDValidatorTagElement(tldDecl, ValidatorTypeInfo.UNKNOWN, new NullAttributeAdvisor());
    }

    /**
     * @param tldDecl
     * @param type
     * @return the tag element for a JSF handler
     */
    public static TLDTagElement createHandlerTagElement(
            final TLDElementDeclaration tldDecl, final IType type)
    {
        if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                FACET_TAG_HANDLER))
        {
            return new TLDTagHandlerElement(tldDecl, TagHandlerType.FACET, new NullAttributeAdvisor());
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                ATTRIBUTE_TAG_HANDLER))
        {
            return new TLDTagHandlerElement(tldDecl, TagHandlerType.ATTRIBUTE, new NullAttributeAdvisor());
        }
        // else if (isTypeNameInstanceOfClass(type, ACTIONLISTENER_TAG_HANDLER))
        // {
        // return new TLDTagHandlerElement(tldDecl,
        // TagHandlerType.ACTIONLISTENER);
        // }
        // else if (isTypeNameInstanceOfClass(type,
        // VALUECHANGELISTENER_TAG_HANDLER))
        // {
        // return new TLDTagHandlerElement(tldDecl,
        // TagHandlerType.VALUECHANGELISTENER);
        // }
        return null;
    }

    /**
     * @param type
     * @param project
     * @return true if type represents a JSF component action class (spec 9.2.2)
     */
    public static IJSFTagElement.TagType getJSFComponentTagType(
            final IType type, final IProject project)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
        {
            JSFCoreTraceOptions
                    .log(String
                            .format(
                                    "TagAnalyzer.getJSFComponentTagType: Determining Tag Type for type %s on project %s", //$NON-NLS-1$
                                    type.getFullyQualifiedName(), project
                                            .toString()));
        }

        Set<String> componentTags = null;
        Set<String> converterTags = null;
        Set<String> validatorTags = null;

        final JSFVersion jsfVersion = ServletBeanProxyContributor.getProjectVersion(project);

        // v1.1(9.2.2): JSF component tags must sub-class one of these
        if (jsfVersion == JSFVersion.V1_0 || jsfVersion == JSFVersion.V1_1)
        {
            componentTags = COMPONENT_TAG_HANDLER_TYPES_JSF11;
            converterTags = CONVERTER_TAG_HANDLER_TYPES_JSF11;
            validatorTags = VALIDATOR_TAG_HANDLER_TYPES_JSF11;
        }
        // v1.2(9.2.2): JSF component tags must sub-class UIComponentELTag
        // the original two are included because we must be backward
        // compatible
        else if (jsfVersion == JSFVersion.V1_2)
        {
            componentTags = COMPONENT_TAG_HANDLER_TYPES_JSF12;
            converterTags = CONVERTER_TAG_HANDLER_TYPES_JSF12;
            validatorTags = VALIDATOR_TAG_HANDLER_TYPES_JSF12;
        }

        TagType tagType = null;

        if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                componentTags))
        {
            tagType = TagType.COMPONENT;
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                converterTags))
        {
            tagType = TagType.CONVERTER;
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                validatorTags))
        {
            tagType = TagType.VALIDATOR;
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                ALL_HANDLER_TAGS))
        {
            tagType = TagType.HANDLER;
        }

        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
        {
            JSFCoreTraceOptions.log(String.format(
                    "TagAnalyzer.getJSFComponentTagType: tag type is %s", //$NON-NLS-1$
                    tagType != null ? tagType.toString() : "null")); //$NON-NLS-1$
        }
        return tagType;
    }


}
