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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jst.jsf.common.dom.AttrDOMAdapter;
import org.eclipse.jst.jsf.common.dom.AttributeIdentifier;
import org.eclipse.jst.jsf.common.dom.DOMAdapter;
import org.eclipse.jst.jsf.common.internal.types.CompositeType;
import org.eclipse.jst.jsf.common.internal.types.IAssignable;
import org.eclipse.jst.jsf.common.internal.types.TypeComparator;
import org.eclipse.jst.jsf.common.internal.types.TypeComparatorDiagnosticFactory;
import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
import org.eclipse.jst.jsf.common.internal.types.TypeTransformer;
import org.eclipse.jst.jsf.common.runtime.internal.model.ViewObject;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentFactory;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterDecorator;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.region.Region2AttrAdapter;
import org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter;
import org.eclipse.jst.jsf.core.jsfappconfig.internal.IJSFAppConfigManager;
import org.eclipse.jst.jsf.core.jsfappconfig.internal.JSFAppConfigManagerFactory;
import org.eclipse.jst.jsf.designtime.DTAppManagerUtil;
import org.eclipse.jst.jsf.designtime.internal.view.DTUIViewRoot;
import org.eclipse.jst.jsf.designtime.internal.view.IDTViewHandler.ViewHandlerException;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewDefnAdapter;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewDefnAdapter.DTELExpression;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewObjectMappingService;
import org.eclipse.jst.jsf.designtime.internal.view.XMLViewObjectMappingService.ElementData;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterForClassType;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterType;
import org.eclipse.jst.jsf.metadataprocessors.MetaDataEnabledProcessingFactory;
import org.eclipse.jst.jsf.metadataprocessors.features.ELIsNotValidException;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidELValues;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidValues;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidationMessage;
import org.eclipse.jst.jsf.validation.internal.AbstractXMLViewValidationStrategy;
import org.eclipse.jst.jsf.validation.internal.JSFValidationContext;
import org.eclipse.jst.jsf.validation.internal.el.ELExpressionValidator;
import org.eclipse.jst.jsf.validation.internal.el.ELValidationUtil;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

/**
 * An XML view validation strategy that validates
 * 
 * @author cbateman
 * 
 */
public class AttributeValidatingStrategy extends
AbstractXMLViewValidationStrategy
{
    private static final  String       DISABLE_ALTERATIVE_TYPES_KEY = "jsfCoreDisableConverterValidation"; //$NON-NLS-1$
    private static final  String       ENABLE_ALTERATIVE_TYPES_KEY  = "jsfCoreEnableConverterValidation"; //$NON-NLS-1$
    static final boolean               DEBUG;
    static
    {
        final String value = Platform
        .getDebugOption("org.eclipse.jst.jsf.validation.internal.el/debug/jspsemanticsvalidator"); //$NON-NLS-1$
        DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
    }

    /**
     * identifier
     */
    public final static String         ID           = "org.eclipse.jst.jsf.validation.strategy.AttributeValidatingStrategy"; //$NON-NLS-1$
    private final static String        DISPLAY_NAME = "Attribute Validator"; //$NON-NLS-1$

    private final JSFValidationContext _validationContext;
    private final TypeComparator       _typeComparator;
    private Set<String>                _conversionTypes;

    /**
     * Default constructor
     * 
     * @param validationContext
     */
    public AttributeValidatingStrategy(final JSFValidationContext validationContext)
    {
        super(ID, DISPLAY_NAME);

        _validationContext = validationContext;
        _typeComparator = new TypeComparator(
                new TypeComparatorDiagnosticFactory(validationContext
                        .getPrefs().getTypeComparatorPrefs()));
    }

    @Override
    public boolean isInteresting(final DOMAdapter domAdapter)
    {
        return (domAdapter instanceof AttrDOMAdapter);
    }

    @Override
    public void validate(final DOMAdapter domAdapter)
    {
        if (domAdapter instanceof AttrDOMAdapter)
        {
            final long curTime = System.nanoTime();
            final Region2AttrAdapter attrAdapter = (Region2AttrAdapter) domAdapter;
            // check that this is attribute value region - 221722
            if (attrAdapter.getAttributeValueRegion() != null)
            {
                final IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE
                .getContext(attrAdapter.getDocumentContext()
                        .getStructuredDocument(), attrAdapter
                        .getOwningElement().getDocumentContext()
                        .getDocumentPosition()
                        + attrAdapter.getAttributeValueRegion()
                        .getStart());

                validateAttributeValue(context, attrAdapter);
            }
            if (DEBUG)
            {
                System.out.println(String.format("Validation for attribute: %s took %d" //$NON-NLS-1$
                    , domAdapter.toString()
                    , Long.valueOf(System.nanoTime()-curTime)));
            }
        }
    }

    /**
     * Validates the attribute value. Reports any problems to the reporter in
     * the JSFValidationContext.
     * 
     * @param context
     * @param attrAdapter
     */
    private void validateAttributeValue(
            final IStructuredDocumentContext context,
            final Region2AttrAdapter attrAdapter)
    {
        // so of the code in run calls out into extension code or code
        // dependent on external data (meta-data)
        SafeRunner.run(new ISafeRunnable()
        {
            public void handleException(final Throwable exception)
            {
                JSFCorePlugin.log(String.format(
                        "Error validating attribute: %s on element %s", //$NON-NLS-1$
                        attrAdapter.getNodeName(), attrAdapter
                        .getOwningElement().getNodeName()), exception);
            }

            public void run() throws Exception
            {
                final Region2ElementAdapter elementAdapter =
                    attrAdapter.getOwningElement();
                // if there's elText then validate it
                // TODO: this approach will fail with mixed expressions
                if (!checkIfELAndValidate(elementAdapter, attrAdapter, context))
                {
                    validateNonELAttributeValue(context, attrAdapter);
                }
            }
        });
    }

    private boolean checkIfELAndValidate(final Region2ElementAdapter elementAdapter,
            final Region2AttrAdapter attrAdapter,
            final IStructuredDocumentContext context)
    {
        int offsetOfFirstEL = -1;
        final String attrValue = attrAdapter.getValue();

        // TODO: should find and validate all
        offsetOfFirstEL = attrValue.indexOf('#');

        if (offsetOfFirstEL != -1 && offsetOfFirstEL < attrValue.length() - 1
                && attrValue.charAt(offsetOfFirstEL + 1) == '{')
        {
            offsetOfFirstEL += 2;
        }
        else
        {
            offsetOfFirstEL = -1;
        }

        final XMLViewDefnAdapter adapter = DTAppManagerUtil
        .getXMLViewDefnAdapter(context);

        boolean isEL = false;
        if (adapter != null && offsetOfFirstEL != -1)
        {
            try
            {
                // use the attribute's context plus the offset into the
                // whole attribute value to find where we think the el
                // expression starts. Add one since the attribute value
                // string returned by attrAdapter will have the value quotes
                // removed, but the region offsets include the quotes.
                IStructuredDocumentContext elContext = IStructuredDocumentContextFactory.INSTANCE
                .getContext(context.getStructuredDocument(), context
                        .getDocumentPosition()
                        + offsetOfFirstEL + 1);
                final DTELExpression elExpression = adapter
                .getELExpression(elContext);
                if (elExpression != null)
                {
                    final String elText = elExpression.getText();

                    if (DEBUG)
                    {
                        System.out.println(addDebugSpacer(3) + "EL attrVal= " //$NON-NLS-1$
                                + elText);
                    }

                    elContext = elExpression.getDocumentContext();
                    // EL validation is user configurable because
                    // it can be computationally costly.
                    if (_validationContext.shouldValidateEL())
                    {
                        // also, skip the validation if the expression is empty
                        // or only whitespace, since the parser doesn't handle
                        // it
                        // anyway.
                        if ("".equals(elText.trim())) //$NON-NLS-1$
                        {
                            final int offset = elContext.getDocumentPosition() - 1;
                            final int length = elText.length() + 2;
                            final Diagnostic diagnostic = _validationContext
                            .getDiagnosticFactory()
                            .create_EMPTY_EL_EXPRESSION();
                            // detected empty EL expression
                            if (_validationContext.shouldValidateEL())
                            {
                                _validationContext.getReporter().report(
                                        diagnostic, offset, length);
                            }
                        }
                        else
                        {
                            final List elVals = MetaDataEnabledProcessingFactory
                            .getInstance()
                            .getAttributeValueRuntimeTypeFeatureProcessors(
                                    IValidELValues.class,
                                    elContext,
                                    attrAdapter
                                    .getAttributeIdentifier());
                            final String safeELText = elText.replaceAll(
                                    "[\n\r\t]", " "); //$NON-NLS-1$ //$NON-NLS-2$
                            validateELExpression(context, elContext, elVals,
                                    elementAdapter, attrAdapter, safeELText);
                            isEL = true;
                        }
                    } else {
                        isEL = true;
                    }
                }
            }
            catch (final ViewHandlerException e)
            {
                // fall through to return false
            }
        }

        // is el if we've already detected it or if the step 2 method
        // finds it. Run the method first to avoid short-circuiting
        final boolean isEL2 = checkIfELAndValidate2(attrAdapter, context);

        return isEL || isEL2;
    }

    /**
     * Checks the region to see if it contains an EL attribute value. If it
     * does, validates it
     * 
     * @return true if validated EL, false otherwise
     */
    private boolean checkIfELAndValidate2(final Region2AttrAdapter attrAdapter,
            final IStructuredDocumentContext sDocContext)
    {
        final ITextRegion attrValueRegion = attrAdapter
                .getAttributeValueRegion();
        if (attrValueRegion instanceof ITextRegionCollection)
        {
            final ITextRegionCollection parentRegion = ((ITextRegionCollection) attrValueRegion);
            if (parentRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)
            {
                final ITextRegionList regionList = parentRegion.getRegions();

                if (regionList.size() >= 3)
                {
                    final ITextRegion openQuote = regionList.get(0);
                    final ITextRegion vblOpen = regionList.get(1);

                    if ((openQuote.getType() == DOMJSPRegionContexts.XML_TAG_ATTRIBUTE_VALUE_DQUOTE || openQuote
                            .getType() == DOMJSPRegionContexts.JSP_VBL_DQUOTE || 
                            openQuote.getType() == DOMJSPRegionContexts.JSP_TAG_ATTRIBUTE_VALUE_DQUOTE)
                            && vblOpen.getType() == DOMJSPRegionContexts.JSP_VBL_OPEN)
                    {
                        boolean foundClosingQuote = false;
                        for (int i = 2; !foundClosingQuote
                                && i < regionList.size(); i++)
                        {
                            final ITextRegion searchRegion = regionList.get(i);
                            if (searchRegion.getType() == DOMJSPRegionContexts.JSP_VBL_CLOSE)
                            {
                                foundClosingQuote = true;
                            }
                        }

                        if (!foundClosingQuote
                                && _validationContext.shouldValidateEL())
                        {
                            final int offset = sDocContext
                                    .getDocumentPosition() + 1;
                            final int length = parentRegion.getText().length();
                            final Diagnostic diagnostic = _validationContext
                                    .getDiagnosticFactory()
                                    .create_MISSING_CLOSING_EXPR_BRACKET();
                            _validationContext.getReporter().report(diagnostic,
                                    offset, length);
                        }
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void validateELExpression(final IStructuredDocumentContext context,
            final IStructuredDocumentContext elContext, final List elVals,
            final Region2ElementAdapter elementAdapter,
            final Region2AttrAdapter attrAdapter, final String elText)
    {
        // Call EL validator which will perform at least the syntactical
        // validation
        final ELExpressionValidator elValidator = new ELExpressionValidator(
                elContext, elText, _validationContext
                        .getSymbolResolverFactory(), _validationContext
                        .getReporter());
        elValidator.validateXMLNode();

        final CompositeType exprType = elValidator.getExpressionType();
        if (exprType != null)
        {
        	// Ignore the expression whose last two segments are of types Object.
        	final CompositeType boxedType = TypeTransformer
            	.transformBoxPrimitives(exprType);
        	final String[] testSignatures = boxedType.getSignatures();
        	if (testSignatures.length > 0 && TypeConstants.TYPE_JAVAOBJECT.equals(testSignatures[0])) 
        	{
        		if (elText.indexOf('.') != -1) 
        		{
        			String elText2 = elText.substring(0, elText.lastIndexOf('.'));
                    final ELExpressionValidator elValidator2 = new ELExpressionValidator(
                            elContext, elText2, _validationContext
                                    .getSymbolResolverFactory(), _validationContext
                                    .getReporter());
                    elValidator2.validateXMLNode();

                    final CompositeType exprType2 = elValidator.getExpressionType();
                	final CompositeType boxedType2 = TypeTransformer.transformBoxPrimitives(exprType2);
                	final String[] testSignatures2 = boxedType2.getSignatures();
                	if (testSignatures2.length > 0 && TypeConstants.TYPE_JAVAOBJECT.equals(testSignatures2[0])) 
                	{
                		return;
                	}
        		}
        	}
        	
            for (final Iterator it = elVals.iterator(); it.hasNext();)
            {
                final IValidELValues elval = (IValidELValues) it.next();
                final String attributeVal = attrAdapter.getValue();
                CompositeType expectedType;
                Diagnostic status = null;
                try
                {
                    expectedType = elval.getExpectedRuntimeType();

                    if (expectedType != null)
                    {
                        expectedType = maybeAddAlternativeTypes(
                                expectedType, exprType, elementAdapter,
                                attrAdapter);
                        if (ELValidationUtil.isProjectEL22(_validationContext.getFile())) {
                        	expectedType = addEL22Alternatives(expectedType);
                        }
                        status = _typeComparator.calculateTypeCompatibility(
                                expectedType, exprType);
                        if (status.getSeverity() != Diagnostic.OK)
                        {
                            reportValidationMessage(status, context,
                                    attributeVal);
                        }
                    }
                }
                catch (final ELIsNotValidException e)
                {
                    reportValidationMessage(createValidationMessage(context,
                            attributeVal, IStatus.WARNING, e.getMessage(),
                            _validationContext.getFile()), context,
                            attributeVal);
                }
            }
        }
    }

    private CompositeType addEL22Alternatives(final CompositeType expectedType) {
    	CompositeType type = expectedType;
    	if (expectedType != null) {
    		final int assignmentTypeMask = expectedType.getAssignmentTypeMask();
    		if ((assignmentTypeMask & IAssignable.ASSIGNMENT_TYPE_RHS) != 0 ||
    				assignmentTypeMask == IAssignable.ASSIGNMENT_TYPE_NONE) {
        		int assignmentType = IAssignable.ASSIGNMENT_TYPE_NONE;
        		if ((assignmentTypeMask & IAssignable.ASSIGNMENT_TYPE_RHS) != 0) {
        			assignmentType = IAssignable.ASSIGNMENT_TYPE_RHS;
        		}
        		final List<String> signatures = new ArrayList<String>();
        		for (final String signature: expectedType.getSignatures()) {
        			signatures.add(signature);
            		final List<String> methodSignatures = new ArrayList<String>();
            		for (int i = 0; i < 20; i++) {
            			final String methodSignature = Signature.createMethodSignature(
            					methodSignatures.toArray(new String[i]),
            					Signature.getElementType(signature)); 
            			signatures.add(methodSignature);
            			methodSignatures.add("Ljava.lang.String;"); //$NON-NLS-1$
            		}
        		}
        		type = new CompositeType(
        				signatures.toArray(new String[signatures.size()]),
        				assignmentType);
    		}
    	}
    	return type;
    }

    private boolean disableAlternativeTypes()
    {
        if (hasProperty(DISABLE_ALTERATIVE_TYPES_KEY))
        {
            return true;
        }

        if (hasProperty(ENABLE_ALTERATIVE_TYPES_KEY))
        {
            return false;
        }
        
//      As of Helios, alternative type is disabled by default
        return true;
        
//        final IPreferenceStore prefStore = JSFCorePlugin.getDefault().getPreferenceStore();
//        return prefStore.getBoolean("org.eclipse.jst.jsf.core."+DISABLE_ALTERATIVE_TYPES_KEY); //$NON-NLS-1$
    }
    
    private boolean hasProperty(final String key) {
    	 String res = System.getProperty(key);
         if (res == null) {
             //check env var also
             res = System.getenv(key);
         }
         return res != null;
    }
    /**
     * @return true if alternative type comparison (i.e. post-conversion) passes
     */
    private CompositeType maybeAddAlternativeTypes(
            final CompositeType expectedType, final CompositeType exprTypes,
            final Region2ElementAdapter elementAdapter,
            final Region2AttrAdapter attrAdapter)
    {
        final long curTime = System.nanoTime();
        
        //As of Helios, alternative type is disabled by default
        //and enabled by the ENABLE_ALTERNATIVE_TYPES_KEY system/env property
        if (disableAlternativeTypes())
        {
            return expectedType;
        }

        final IStructuredDocumentContext context = elementAdapter
                .getDocumentContext();
        final DTUIViewRoot viewRoot = _validationContext.getViewRootHandle().getCachedViewRoot();
        final IAdaptable serviceAdaptable = viewRoot.getServices();
        final XMLViewObjectMappingService mappingService = (XMLViewObjectMappingService) serviceAdaptable
                .getAdapter(XMLViewObjectMappingService.class);
        if (mappingService != null)
        {
            final ElementData elementData = XMLViewObjectMappingService
                    .createElementData(elementAdapter.getNamespace(),
                            elementAdapter.getLocalName(), context,
                            Collections.EMPTY_MAP);
            final ViewObject viewObject = mappingService
                    .findViewObject(elementData);
            // if the corresponding view object is a valueholder, then
            // we need to see if you think there a valid conversion
            // available
            if (viewObject instanceof ComponentInfo
                    && ((ComponentInfo) viewObject).getComponentTypeInfo() != null
                    && ((ComponentInfo) viewObject).getComponentTypeInfo()
                            .isInstanceOf(
                                    ComponentFactory.INTERFACE_VALUEHOLDER))
            {
                final ComponentInfo component = (ComponentInfo) viewObject;
                // get the original elementData
                final ElementData mappedElementData = mappingService
                        .findElementData(component);
                final String propName = mappedElementData
                        .getPropertyName(attrAdapter.getLocalName());
                if ("value".equals(propName)) //$NON-NLS-1$
                {
                    // final List converters =
                    // component.getDecorators(ComponentFactory.CONVERTER);

                    // (ConverterDecorator) it.next();
                    final CompositeType alternativeTypes = createCompositeType(
                            expectedType, exprTypes, component
                                    .getDecorators(ComponentFactory.CONVERTER));
                    if (DEBUG)
                    {
                        System.out.println(String.format(
                                "maybeAddAlternative took %d", Long.valueOf(System //$NON-NLS-1$
                                        .nanoTime()
                                            - curTime)));
                    }
                    return alternativeTypes;
                }
            }
        }
        if (DEBUG)
        {
            System.out.println(String.format("maybeAddAlternative took %d", Long //$NON-NLS-1$
                .valueOf(System.nanoTime() - curTime)));
        }
        // don't add anything by default
        return expectedType;
    }

    private CompositeType createCompositeType(final CompositeType initialTypes,
            final CompositeType testTypes, final List<ConverterDecorator> decorators)
    {
        // indicates unknown converter
        final Set<String> types = new HashSet(Arrays.asList(initialTypes
                .getSignatures()));
        // look for converters.  If there's one where we don't know the type,
        // simply copy over the testTypes to force validation to ignore, since
        // we have no  idea.
        for (final ConverterDecorator decorator : decorators)
        {
            if (decorator.getTypeInfo() != null)
            {
                final ConverterTypeInfo converterTypeInfo = decorator.getTypeInfo();
                if (converterTypeInfo.getForClass().length == 0)
                {
                    types.addAll(Arrays.asList(testTypes.getSignatures()));
                    break;
                }
                types.addAll(createSignatures(converterTypeInfo.getForClass()));
            }
        }
        types.addAll(getRegisteredConversionTypesByClass());
        return new CompositeType(types.toArray(new String[0])
                , initialTypes.getAssignmentTypeMask());
    }

    private Set<String>  getRegisteredConversionTypesByClass()
    {
        if (_conversionTypes == null)
        {
            _conversionTypes = new HashSet<String>();
            final IProject project = _validationContext.getFile().getProject();
            final IJSFAppConfigManager appConfig = JSFAppConfigManagerFactory.getJSFAppConfigManagerInstance(project);
            final List<ConverterType> converters = appConfig.getConverters();
            for (final ConverterType converterType : converters)
            {
                final ConverterForClassType forClassType = converterType.getConverterForClass();
                if (forClassType != null)
                {
                    final String forClass = forClassType.getTextContent();
                    if (forClass != null)
                    {
                        String signature = forClass.trim();
                        try
                        {
                            // arrays are a special case where the 
                            // [Ljava.lang.String; syntax is valid.
                            if (Signature.getArrayCount(signature)>0)
                            {
                                _conversionTypes.add(signature);
                            }
                        }
                        catch (final IllegalArgumentException e)
                        {
                            // ignore
                        }

                        try
                        {
                            signature = Signature.createTypeSignature(signature, true);
                            _conversionTypes.add(signature);
                        }
                        catch (final Exception e)
                        {
                            // ignore: JSFCorePlugin.log(IStatus.INFO, "Could not use registered converter for-class: "+forClass); //$NON-NLS-1$
                        }
                    }
                }
            }
        }
        return _conversionTypes;
    }

    private List<String> createSignatures(final String[] classNames)
    {
        final List<String> signatures = new ArrayList<String>();
        for (final String className : classNames)
        {
            try
            {
                String signature = Signature.createTypeSignature(className, true);
                signatures.add(signature);
            }
            catch (final Exception e)
            {
                JSFCorePlugin.log(e, "Trying to create signature"); //$NON-NLS-1$
            }
        }
        return signatures;
    }

    /**
     * Validates an attribute value in context using the JSF metadata processing
     * framework
     * 
     * @param context
     * @param region
     * @param uri
     * @param tagName
     * @param attrName
     * @param attributeVal
     * @param reporter
     * @param file
     */
    private void validateNonELAttributeValue(
            final IStructuredDocumentContext context,
            final Region2AttrAdapter attrAdapter)
    {
        final String attributeValue = attrAdapter.getValue();
        // else validate as static attribute value
        if (DEBUG)
        {
            System.out.println(addDebugSpacer(3) + "attrVal= " //$NON-NLS-1$
                    + (attributeValue != null ? attributeValue : "null")); //$NON-NLS-1$
        }

        final AttributeIdentifier attributeId = attrAdapter
        .getAttributeIdentifier();

        if (attributeId.getTagIdentifier() == null
                || attributeId.getTagIdentifier().getTagName() == null
                || attributeId.getName() == null)
        {
            return;
        }

        final List vv = MetaDataEnabledProcessingFactory.getInstance()
        .getAttributeValueRuntimeTypeFeatureProcessors(
                IValidValues.class, context, attributeId);
        if (!vv.isEmpty())
        {
            for (final Iterator it = vv.iterator(); it.hasNext();)
            {
                final IValidValues v = (IValidValues) it.next();
                if (!v.isValidValue(attributeValue.trim()))
                {
                    if (DEBUG)
                    {
                        System.out.println(addDebugSpacer(4) + "NOT VALID "); //$NON-NLS-1$
                    }

                    for (final Iterator msgs = v.getValidationMessages()
                            .iterator(); msgs.hasNext();)
                    {
                        final IValidationMessage msg = (IValidationMessage) msgs
                        .next();
                        reportValidationMessage(createValidationMessage(
                                context, attributeValue, msg.getSeverity(), msg
                                .getMessage(), _validationContext
                                .getFile()), context, attributeValue);
                    }
                }
                else if (DEBUG)
                {
                    System.out.println(addDebugSpacer(5) + "VALID "); //$NON-NLS-1$
                }
            }
        }
        else if (DEBUG)
        {
            System.out.println(addDebugSpacer(4) + "NO META DATA "); //$NON-NLS-1$
        }
    }

    private void reportValidationMessage(final Diagnostic problem,
            final IStructuredDocumentContext context,
            final String attributeValue)
    {
        final int start = context.getDocumentPosition() + 1;
        final int length = attributeValue.length();
        _validationContext.getReporter().report(problem, start, length);
    }

    private Diagnostic createValidationMessage(
            final IStructuredDocumentContext context,
            final String attributeValue, final int severity, final String msg,
            final IFile file)
    {
        // TODO: need factory
        final Diagnostic diagnostic = new BasicDiagnostic(severity, "", -1, //$NON-NLS-1$
                msg, null);
        return diagnostic;
    }

    private String addDebugSpacer(final int count)
    {
        final String TAB = "\t"; //$NON-NLS-1$
        final StringBuffer ret = new StringBuffer(""); //$NON-NLS-1$
        for (int i = 0; i <= count; i++)
        {
            ret.append(TAB);
        }
        return ret.toString();
    }

}
