Package org.eclipse.jst.jsf.validation.internal.strategy

Source Code of org.eclipse.jst.jsf.validation.internal.strategy.ContainmentValidatingStrategy

/*******************************************************************************
* 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.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.jst.jsf.common.dom.DOMAdapter;
import org.eclipse.jst.jsf.common.dom.TagIdentifier;
import org.eclipse.jst.jsf.common.internal.JSPUtil;
import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.query.ITaglibDomainMetaDataModelContext;
import org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper;
import org.eclipse.jst.jsf.common.sets.AxiomaticSet;
import org.eclipse.jst.jsf.common.sets.ConcreteAxiomaticSet;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.region.Region2ElementAdapter;
import org.eclipse.jst.jsf.core.internal.tld.IJSFConstants;
import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory;
import org.eclipse.jst.jsf.core.set.constraint.MemberConstraint;
import org.eclipse.jst.jsf.core.set.mapping.ElementToTagIdentifierMapping;
import org.eclipse.jst.jsf.core.tagmatcher.EvaluationException;
import org.eclipse.jst.jsf.core.tagmatcher.InvalidExpressionException;
import org.eclipse.jst.jsf.core.tagmatcher.XPathMatchingAlgorithm;
import org.eclipse.jst.jsf.validation.internal.AbstractXMLViewValidationStrategy;
import org.eclipse.jst.jsf.validation.internal.JSFValidationContext;
import org.eclipse.jst.jsf.validation.internal.constraints.ContainsTagConstraint;
import org.eclipse.jst.jsf.validation.internal.constraints.TagId;
import org.eclipse.jst.jsf.validation.internal.constraints.TagSet;
import org.w3c.dom.Node;

/**
* @author cbateman
*
*/
public class ContainmentValidatingStrategy extends
        AbstractXMLViewValidationStrategy
{
    /**
     * identifier
     */
    public final static String                         ID =
        "org.eclipse.jst.jsf.validation.strategy.ElementValidatingStrategy"; //$NON-NLS-1$
    private final static String                        DISPLAY_NAME =
        Messages.ContainmentValidatingStrategy_DisplayName;
    private final static ElementToTagIdentifierMapping elem2TagIdMapper =
        new ElementToTagIdentifierMapping();
   
    private static final  String  ENABLE_CONTAINMENT_VALIDATION_KEY  = "jsfCoreEnableContainmentValidation"; //$NON-NLS-1$
   
    private int                                        _containmentValidationCount;  // = 0;
    private final JSFValidationContext                 _jsfValidationContext;
    private boolean                    _enabled;           

    /**
     * @param jsfValidationContext
     */
    public ContainmentValidatingStrategy(
            final JSFValidationContext jsfValidationContext)
    {
        super(ID, DISPLAY_NAME);
        _jsfValidationContext = jsfValidationContext;
        _enabled = isEnabled();
    }

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

    @Override
    public void validate(DOMAdapter domAdapter)
    {
        if (_enabled
            && domAdapter instanceof Region2ElementAdapter)
        {
            final Region2ElementAdapter elementAdapter =
                (Region2ElementAdapter) domAdapter;
            validateContainment(elementAdapter, _jsfValidationContext);
        }
    }

    /**
     * @return true if the containment validation strategy is enabled
     */
    public static boolean isEnabled() {
     String res = System.getProperty(ENABLE_CONTAINMENT_VALIDATION_KEY);
     if (res == null) {
         //check env var also
         res = System.getenv(ENABLE_CONTAINMENT_VALIDATION_KEY);
     }
     return res != null;   
  }
   
    private void validateContainment(
            final Region2ElementAdapter elementAdapter,
            final JSFValidationContext jsfValidationContext)
    {
        // don't validate JSP fragments since the necessary containment may
        // existing
        // in the JSP files that include them
        // also only validate the first instance of containment violation in a
        // file
        if (JSPUtil.isJSPFragment(jsfValidationContext.getFile())
                || _containmentValidationCount > 0)
        {
            return;
        }

        final IStructuredDocumentContext context = elementAdapter
                .getDocumentContext();
        final IDOMContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE
                .getDOMContextResolver(context);
        final Node node = resolver.getNode();

        final String uri = elementAdapter.getNamespace();
        final String tagName = elementAdapter.getLocalName();
        // final Element node = elementAdapter.

        final ITaglibDomainMetaDataModelContext modelContext = TaglibDomainMetaDataQueryHelper
                .createMetaDataModelContext(jsfValidationContext.getFile()
                        .getProject(), uri);
        final Entity entity = TaglibDomainMetaDataQueryHelper.getEntity(
                modelContext, tagName);
        if (entity != null)
        {
            final Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(
                    entity, "containment-constraint"); //$NON-NLS-1$

            if (trait != null)
            {
                final ContainsTagConstraint tagConstraint = (ContainsTagConstraint) trait
                        .getValue();

                final String algorithm = tagConstraint.getSetGenerator()
                        .getAlgorithm();

                // TODO: need generalized factory mechanism for registering and
                // constructing algorithms.
                if (!"xpath".equals(algorithm)) //$NON-NLS-1$
                {
                    return;
                }

                final String expr = tagConstraint.getSetGenerator()
                        .getExpression();

                // TODO: optimize on the expression and cache for reuse
                final XPathMatchingAlgorithm xpathAlg = new XPathMatchingAlgorithm(
                        expr);

                AxiomaticSet set = null;

                try
                {
                    set = xpathAlg.evaluate(node);
                    // map dom nodes to tag identifiers
                    set = elem2TagIdMapper.map(set);
                }
                catch (final InvalidExpressionException e)
                {
                    JSFCorePlugin.log(e, "Problem with expression: " + expr //$NON-NLS-1$
                            + " on node " + node); //$NON-NLS-1$
                    return;
                }
                catch (final EvaluationException e)
                {
                    JSFCorePlugin.log(e, "Problem evaluating expression: " //$NON-NLS-1$
                            + expr + " on node " + node); //$NON-NLS-1$
                    return;
                }

                final TagSet constraintData = tagConstraint.getSatisfiesSet();
                final AxiomaticSet constraintSet = new ConcreteAxiomaticSet();
                for (final Iterator it = constraintData.getTags().iterator(); it
                        .hasNext();)
                {
                    final TagId tagId = (TagId) it.next();
                    constraintSet.add(TagIdentifierFactory.createJSPTagWrapper(
                            tagId.getUri(), tagId.getName()));
                }
                final MemberConstraint memberConstraint = new MemberConstraint(
                        constraintSet);
                final Diagnostic diag = memberConstraint.isSatisfied(set);

                if (diag.getSeverity() != Diagnostic.OK)
                {
                    _containmentValidationCount++; // found a violation

                    final List data = diag.getData();

                    for (final Iterator it = data.iterator(); it.hasNext();)
                    {
                        final TagIdentifier missingParent = (TagIdentifier) it
                                .next();

                        reportContainmentProblem(context, node, missingParent);
                    }
                }
            }
        }
    }

    private void reportContainmentProblem(
            final IStructuredDocumentContext context,
            final Node node,
            final TagIdentifier missingParent)
    {

      Diagnostic diagnostic = null;
      if (missingParent.equals(IJSFConstants.TAG_IDENTIFIER_VIEW)) {
        diagnostic = DiagnosticFactory.create_CONTAINMENT_ERROR_MISSING_VIEW(node.getNodeName());
      }
      else if (missingParent.equals(IJSFConstants.TAG_IDENTIFIER_FORM)) {
        diagnostic = DiagnosticFactory.create_CONTAINMENT_ERROR_MISSING_FORM(node.getNodeName());
      }
      else {
        diagnostic = DiagnosticFactory.create_CONTAINMENT_ERROR_MISSING_ANCESTOR(node.getNodeName(), missingParent);
      }

        // add one so that the start offset is at the node name, rather
        // than the opening brace.
        final int start = context.getDocumentPosition()+1;
        final int length = node.getNodeName().length();

       _jsfValidationContext.getReporter().report(diagnostic, start, length);
    }
   
}
TOP

Related Classes of org.eclipse.jst.jsf.validation.internal.strategy.ContainmentValidatingStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.