Package org.springframework.ide.eclipse.beans.core.internal.model.validation

Source Code of org.springframework.ide.eclipse.beans.core.internal.model.validation.BeansValidationContext$AttributeDescriptor

/*******************************************************************************
* Copyright (c) 2007, 2011 Spring IDE Developers
* 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:
*     Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.core.internal.model.validation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.ide.eclipse.beans.core.DefaultBeanDefinitionRegistry;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansConfigSet;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansModelUtils;
import org.springframework.ide.eclipse.beans.core.internal.model.validation.rules.ValidationRuleUtils;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfig;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfigSet;
import org.springframework.ide.eclipse.beans.core.model.IBeansImport;
import org.springframework.ide.eclipse.beans.core.model.validation.IBeansValidationContext;
import org.springframework.ide.eclipse.beans.core.namespaces.ToolAnnotationUtils;
import org.springframework.ide.eclipse.beans.core.namespaces.ToolAnnotationUtils.ToolAnnotationData;
import org.springframework.ide.eclipse.core.java.IProjectClassLoaderSupport;
import org.springframework.ide.eclipse.core.java.JdtUtils;
import org.springframework.ide.eclipse.core.model.IResourceModelElement;
import org.springframework.ide.eclipse.core.model.validation.AbstractValidationContext;
import org.springframework.ide.eclipse.core.model.validation.IValidationProblemMarker;
import org.springframework.ide.eclipse.core.model.validation.IValidationRule;
import org.springframework.ide.eclipse.core.model.validation.ValidationProblem;
import org.springframework.ide.eclipse.core.model.validation.ValidationProblemAttribute;
import org.springframework.ide.eclipse.core.type.asm.CachingClassReaderFactory;
import org.springframework.ide.eclipse.core.type.asm.ClassReaderFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* Context that gets passed to an {@link IValidationRule}, encapsulating all relevant information used during
* validation.
* @author Torsten Juergeleit
* @author Christian Dupuis
* @since 2.0
*/
public class BeansValidationContext extends AbstractValidationContext implements IBeansValidationContext {

  private static final char KEY_SEPARATOR_CHAR = '/';

  private Map<String, Set<BeanDefinition>> beanLookupCache;

  private ClassReaderFactory classReaderFactory;

  private BeanDefinitionRegistry completeRegistry;

  private BeanDefinitionRegistry incompleteRegistry;

  private IProjectClassLoaderSupport projectClassLoaderSupport;

  private final Map<AttributeDescriptor, List<ToolAnnotationData>> toolAnnotationLookupCache;

  public BeansValidationContext(IBeansConfig config, IResourceModelElement contextElement) {
    super(config, contextElement);

    this.incompleteRegistry = createRegistry(config, contextElement, false);
    this.completeRegistry = createRegistry(config, contextElement, true);

    this.beanLookupCache = new HashMap<String, Set<BeanDefinition>>();
    this.toolAnnotationLookupCache = new HashMap<AttributeDescriptor, List<ToolAnnotationData>>();
  }

  /**
   * {@inheritDoc}
   */
  public synchronized ClassReaderFactory getClassReaderFactory() {
    if (this.classReaderFactory == null) {
      this.classReaderFactory = new CachingClassReaderFactory(JdtUtils.getClassLoader(getRootElement()
          .getElementResource().getProject(), null));
    }
    return this.classReaderFactory;
  }

  /**
   * {@inheritDoc}
   */
  public BeanDefinitionRegistry getCompleteRegistry() {
    return completeRegistry;
  }

  /**
   * {@inheritDoc}
   */
  public BeanDefinitionRegistry getIncompleteRegistry() {
    return incompleteRegistry;
  }

  /**
   * {@inheritDoc}
   */
  public synchronized IProjectClassLoaderSupport getProjectClassLoaderSupport() {
    if (this.projectClassLoaderSupport == null) {
      this.projectClassLoaderSupport = JdtUtils.getProjectClassLoaderSupport(getRootElementProject(), null);
    }
    return this.projectClassLoaderSupport;
  }

  /**
   * {@inheritDoc}
   */
  public Set<BeanDefinition> getRegisteredBeanDefinition(String beanName, String beanClass) {
    Assert.notNull(beanName);
    Assert.notNull(beanClass);

    String key = beanClass + KEY_SEPARATOR_CHAR + beanName;
    if (beanLookupCache.containsKey(key)) {
      return beanLookupCache.get(key);
    }
    Set<BeanDefinition> bds = ValidationRuleUtils.getBeanDefinitions(beanName, beanClass, this);
    // as we don't use a Hashtable we can insert null values
    beanLookupCache.put(key, bds);
    return bds;
  }

  /**
   * {@inheritDoc}
   */
  public IProject getRootElementProject() {
    return (getRootElement().getElementResource() != null ? getRootElement().getElementResource().getProject()
        : null);
  }

  /**
   * {@inheritDoc}
   */
  public IResource getRootElementResource() {
    return getRootElement().getElementResource();
  }

  public synchronized List<ToolAnnotationData> getToolAnnotation(Node n, String attributeName) {
    AttributeDescriptor descriptor = AttributeDescriptor.create(n, attributeName);
    if (toolAnnotationLookupCache.containsKey(descriptor)) {
      return toolAnnotationLookupCache.get(descriptor);
    }

    // Search for tool annotations
    List<ToolAnnotationData> annotationDatas = new ArrayList<ToolAnnotationData>();
    List<Element> appInfoElements = ToolAnnotationUtils.getApplicationInformationElements(n, attributeName);
    for (Element elem : appInfoElements) {
      NodeList children = elem.getChildNodes();
      for (int j = 0; j < children.getLength(); j++) {
        Node annotation = children.item(j);
        if (annotation.getNodeType() == Node.ELEMENT_NODE
            && ToolAnnotationUtils.ANNOTATION_ELEMENT.equals(annotation.getLocalName())
            && ToolAnnotationUtils.TOOL_NAMESPACE_URI.equals(annotation.getNamespaceURI())) {
          ToolAnnotationData annotationData = ToolAnnotationUtils.getToolAnnotationData(annotation);
          if (annotationData != null) {
            annotationDatas.add(annotationData);
          }
        }
      }
    }

    // Add to internal cache
    toolAnnotationLookupCache.put(descriptor, annotationDatas);

    // / Return found annoatations
    return annotationDatas;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isBeanRegistered(String beanName, String beanClass) {
    Set<BeanDefinition> bds = getRegisteredBeanDefinition(beanName, beanClass);
    return bds != null && bds.size() > 0;
  }

  private BeanDefinitionRegistry createRegistry(IBeansConfig config, IResourceModelElement contextElement,
      boolean fillCompletely) {
    DefaultBeanDefinitionRegistry registry = new DefaultBeanDefinitionRegistry();
    if (contextElement instanceof BeansConfigSet) {
      IBeansConfigSet configSet = (IBeansConfigSet) contextElement;
      if (fillCompletely) {
        registry.setAllowAliasOverriding(true);
        registry.setAllowBeanDefinitionOverriding(true);
      }
      else {
        registry.setAllowAliasOverriding(configSet.isAllowAliasOverriding());
        registry.setAllowBeanDefinitionOverriding(configSet.isAllowBeanDefinitionOverriding());
      }
      for (IBeansConfig csConfig : configSet.getConfigs()) {
        if (!fillCompletely && config.equals(csConfig)) {
          break;
        }
        BeansModelUtils.register(configSet, csConfig, registry);
      }
    }
    else if (contextElement instanceof IBeansConfig && !config.equals(contextElement)) {
      registry.setAllowAliasOverriding(true);
      registry.setAllowBeanDefinitionOverriding(true);
      if (fillCompletely) {
        BeansModelUtils.register(null, (IBeansConfig) contextElement, registry);
      }
    }
    else {
      registry.setAllowAliasOverriding(false);
      registry.setAllowBeanDefinitionOverriding(false);
      if (fillCompletely) {
        BeansModelUtils.register(null, config, registry);
      }
    }
    return registry;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected Set<ValidationProblem> createProblems(IResourceModelElement element, String problemId, int severity,
      String message, ValidationProblemAttribute... attributes) {

    Set<ValidationProblem> problems = super.createProblems(element, problemId, severity, message, attributes);
    IResource resource = element.getElementResource();

    // Check if error or warning on imported resource exists
    if (!resource.equals(getRootElementResource())) {
      IBeansImport beansImport = BeansModelUtils.getParentOfClass(element, IBeansImport.class);

      while (beansImport != null) {
        if (severity == IValidationProblemMarker.SEVERITY_ERROR) {
          problems.add(createProblem(beansImport, "", IValidationProblemMarker.SEVERITY_ERROR,
              "Validation error occured in imported configuration file '"
                  + element.getElementResource().getProjectRelativePath().toString() + "'"));
        }
        else if (severity == IValidationProblemMarker.SEVERITY_WARNING) {
          problems.add(createProblem(beansImport, "", IValidationProblemMarker.SEVERITY_WARNING,
              "Validation warning occured in imported configuration file '"
                  + element.getElementResource().getProjectRelativePath().toString() + "'"));
        }
        beansImport = BeansModelUtils.getParentOfClass(beansImport, IBeansImport.class);
      }
    }

    return problems;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected StringBuilder decorateErrorMessage(StringBuilder builder) {
    IResourceModelElement context = getContextElement();
    if (context != null && context.getElementResource() != null) {
      String projectName = context.getElementResource().getProject().getName();
     
      // Only decorate the context if the context element is a config set as otherwise the context
      // should be clear from the marker/problems view -> it is the file being displayed
      if (context instanceof IBeansConfigSet) {
        builder.append(String.format(" [config set: %s/%s]", projectName, context.getElementName()));
      }
    }
    return builder;
  }

  static class AttributeDescriptor {

    private final String attributeName;

    private final String localName;

    private final String namespaceUri;

    private AttributeDescriptor(String namespaceUri, String localName, String attributeName) {
      this.namespaceUri = namespaceUri;
      this.localName = localName;
      this.attributeName = attributeName;
    }

    @Override
    public boolean equals(Object obj) {
      if (!(obj instanceof AttributeDescriptor)) {
        return false;
      }
      AttributeDescriptor other = (AttributeDescriptor) obj;
      if (!ObjectUtils.nullSafeEquals(namespaceUri, other.namespaceUri)) {
        return false;
      }
      if (!ObjectUtils.nullSafeEquals(localName, other.localName)) {
        return false;
      }
      return ObjectUtils.nullSafeEquals(attributeName, attributeName);
    }

    @Override
    public int hashCode() {
      int hashCode = 7;
      hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(namespaceUri);
      hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(localName);
      hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(attributeName);
      return hashCode;
    }

    public static AttributeDescriptor create(Node n, String attributeName) {
      return new AttributeDescriptor(n.getNamespaceURI(), n.getLocalName(), attributeName);
    }

  }

}
TOP

Related Classes of org.springframework.ide.eclipse.beans.core.internal.model.validation.BeansValidationContext$AttributeDescriptor

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.