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

Source Code of org.springframework.ide.eclipse.beans.core.internal.model.BeansConfigSet

/*******************************************************************************
* Copyright (c) 2004, 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;

import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.ui.IPersistableElement;
import org.springframework.ide.eclipse.beans.core.model.IBean;
import org.springframework.ide.eclipse.beans.core.model.IBeanAlias;
import org.springframework.ide.eclipse.beans.core.model.IBeansComponent;
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.IBeansModelElementTypes;
import org.springframework.ide.eclipse.beans.core.model.IBeansProject;
import org.springframework.ide.eclipse.core.model.AbstractResourceModelElement;
import org.springframework.ide.eclipse.core.model.IModelElement;

/**
* This class defines a Spring beans config set (a list of beans config names).
* @author Torsten Juergeleit
* @author Dave Watkins
* @author Christian Dupuis
*/
public class BeansConfigSet extends AbstractResourceModelElement implements IBeansConfigSet {

  private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

  private final Lock r = rwl.readLock();

  private final Lock w = rwl.writeLock();

  protected Set<String> configNames;

  private volatile boolean allowAliasOverriding;

  private volatile boolean allowBeanDefinitionOverriding;

  private volatile boolean isIncomplete;

  private volatile Map<String, IBeanAlias> aliasesMap;

  private volatile boolean isAliasesMapPopulated = false;

  private volatile Set<IBeansComponent> components;

  private volatile boolean isComponentsPopulated = false;

  private volatile Map<String, IBean> beansMap;

  private volatile boolean isBeansMapPopulated = false;

  private volatile Map<String, Set<IBean>> beanClassesMap;

  private volatile boolean isBeanClassesMapPopulated = false;

  private volatile Type type;

  private volatile Set<String> profiles;

  public BeansConfigSet(IBeansProject project, String name, Type type) {
    this(project, name, new LinkedHashSet<String>(), type);
  }

  public BeansConfigSet(IBeansProject project, String name, Set<String> configNames, Type type) {
    super(project, name);
    this.configNames = new LinkedHashSet<String>(configNames);
    allowAliasOverriding = true;
    allowBeanDefinitionOverriding = true;
    this.type = type;
    this.profiles = new LinkedHashSet<String>();
  }

  /**
   * Sets internal maps with <code>IBean</code>s and bean classes to <code>null</code>.
   */
  public void reset() {
    try {
      w.lock();
      aliasesMap = null;
      isAliasesMapPopulated = false;
      components = null;
      isComponentsPopulated = false;
      beansMap = null;
      isBeansMapPopulated = false;
      beanClassesMap = null;
      isBeanClassesMapPopulated = false;
    }
    finally {
      w.unlock();
    }
  }

  public int getElementType() {
    return IBeansModelElementTypes.CONFIG_SET_TYPE;
  }

  @Override
  public IModelElement[] getElementChildren() {
    Set<IBeansConfig> children = getConfigs();
    return children.toArray(new IModelElement[children.size()]);
  }

  public IResource getElementResource() {
    return ((IBeansProject) getElementParent()).getProject();
  }

  public boolean isElementArchived() {
    return false;
  }

  public void setAllowAliasOverriding(boolean allowAliasOverriding) {
    this.allowAliasOverriding = allowAliasOverriding;
    reset();
  }

  public boolean isAllowAliasOverriding() {
    return allowAliasOverriding;
  }

  public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
    this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
    reset();
  }

  public boolean isAllowBeanDefinitionOverriding() {
    return allowBeanDefinitionOverriding;
  }

  public void setIncomplete(boolean isIncomplete) {
    this.isIncomplete = isIncomplete;
  }

  public boolean isIncomplete() {
    return isIncomplete;
  }

  public void addConfig(String configName) {
    if (configName.length() > 0 && !getConfigNames().contains(configName)) {
      try {
        w.lock();
        configNames.add(configName);
      }
      finally {
        w.unlock();
      }
      reset();
    }
  }

  public boolean hasConfig(String configName) {
    return getConfigNames().contains(configName);
  }

  public boolean hasConfig(IFile file) {
    if (file == null) return false;
   
    if (file.getProject().equals(((IBeansProject) getElementParent()).getProject())) {
      return getConfigNames().contains(file.getProjectRelativePath().toString());
    }
    return getConfigNames().contains(file.getFullPath().toString());
  }

  public void removeConfig(String configName) {
    try {
      w.lock();
      configNames.remove(configName);
    }
    finally {
      w.unlock();
    }
    reset();
  }

  public void removeAllConfigs() {
    try {
      w.lock();
      configNames.clear();
    }
    finally {
      w.unlock();
    }
    reset();
  }

  public Set<IBeansConfig> getConfigs() {
    Set<IBeansConfig> configs = new LinkedHashSet<IBeansConfig>();
    for (String configName : getConfigNames()) {
      IBeansConfig config = BeansModelUtils.getConfig(configName, this);
      if (config != null) {
        configs.add(config);
      }
    }
    return configs;
  }

  public Set<String> getConfigNames() {
    try {
      r.lock();
      return new LinkedHashSet<String>(configNames);
    }
    finally {
      r.unlock();
    }
  }

  public boolean hasAlias(String name) {
    return getAliasesMap().containsKey(name);
  }

  public IBeanAlias getAlias(String name) {
    return getAliasesMap().get(name);
  }

  public Set<IBeanAlias> getAliases() {
    return new LinkedHashSet<IBeanAlias>(getAliasesMap().values());
  }

  public Set<IBeansComponent> getComponents() {
    return new LinkedHashSet<IBeansComponent>(getComponentsList());
  }

  public boolean hasBean(String name) {
    return getBeansMap().containsKey(name);
  }

  public IBean getBean(String name) {
    return getBeansMap().get(name);
  }

  public Set<IBean> getBeans() {
    return new LinkedHashSet<IBean>(getBeansMap().values());
  }

  public boolean isBeanClass(String className) {
    return getBeanClassesMap().containsKey(className);
  }

  public Set<String> getBeanClasses() {
    return new LinkedHashSet<String>(getBeanClassesMap().keySet());
  }

  public Set<IBean> getBeans(String className) {
    if (isBeanClass(className)) {
      return new LinkedHashSet<IBean>(getBeanClassesMap().get(className));
    }
    return new HashSet<IBean>();
  }

  // TODO CD IDE-1079 commented out to prevent deadlocks
  /*
   * @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof
   * BeansConfigSet)) { return false; } try { r.lock(); BeansConfigSet that = (BeansConfigSet) other; if
   * (!ObjectUtils.nullSafeEquals(this.configNames, that.configNames)) return false; if
   * (!ObjectUtils.nullSafeEquals(this.allowAliasOverriding, that.allowAliasOverriding)) return false; if
   * (!ObjectUtils.nullSafeEquals(this.allowBeanDefinitionOverriding, that.allowBeanDefinitionOverriding)) return
   * false; if (!ObjectUtils.nullSafeEquals(this.isIncomplete, that.isIncomplete)) return false; return
   * super.equals(other); } finally { r.unlock(); } }
   */

  // TODO CD IDE-1079 commented out to prevent deadlocks
  /*
   * @Override public int hashCode() { try { r.lock(); int hashCode = ObjectUtils.nullSafeHashCode(configNames);
   * hashCode = getElementType() * hashCode + ObjectUtils.nullSafeHashCode(allowAliasOverriding); hashCode =
   * getElementType() * hashCode + ObjectUtils.nullSafeHashCode(allowBeanDefinitionOverriding); hashCode =
   * getElementType() * hashCode + ObjectUtils.nullSafeHashCode(isIncomplete); return getElementType() * hashCode +
   * super.hashCode(); } finally { r.unlock(); } }
   */

  @Override
  public String toString() {
    try {
      r.lock();
      return getElementName() + ": " + configNames.toString();
    }
    finally {
      r.unlock();
    }
  }

  /**
   * Returns lazily initialized map with all beans defined in this config set.
   */
  private Map<String, IBeanAlias> getAliasesMap() {
    if (!this.isAliasesMapPopulated) {
      try {
        w.lock();
        if (this.isAliasesMapPopulated) {
          return aliasesMap;
        }
        aliasesMap = new LinkedHashMap<String, IBeanAlias>();
        for (String configName : configNames) {
          IBeansConfig config = BeansModelUtils.getConfig(configName, this);
          if (config != null) {
            for (IBeanAlias alias : config.getAliases()) {
              if (allowAliasOverriding || !aliasesMap.containsKey(alias.getElementName())) {
                aliasesMap.put(alias.getElementName(), alias);
              }
            }
          }
        }
      }
      finally {
        this.isAliasesMapPopulated = true;
        w.unlock();
      }
    }
    try {
      r.lock();
      return aliasesMap;
    }
    finally {
      r.unlock();
    }
  }

  /**
   * Returns lazily initialized list with all components defined in this config set.
   */
  private Set<IBeansComponent> getComponentsList() {
    if (!this.isComponentsPopulated) {
      try {
        w.lock();
        if (this.isComponentsPopulated) {
          return components;
        }
        components = new LinkedHashSet<IBeansComponent>();
        for (String configName : configNames) {
          IBeansConfig config = BeansModelUtils.getConfig(configName, this);
          if (config != null) {
            for (IBeansComponent component : config.getComponents()) {
              components.add(component);
            }
          }
        }
      }
      finally {
        this.isComponentsPopulated = true;
        w.unlock();
      }
    }
    try {
      r.lock();
      return components;
    }
    finally {
      r.unlock();
    }
  }

  /**
   * Returns lazily initialized map with all beans defined in this config set.
   */
  private Map<String, IBean> getBeansMap() {
    if (!this.isBeansMapPopulated) {
      try {
        w.lock();
        if (this.isBeansMapPopulated) {
          return beansMap;
        }
        beansMap = new LinkedHashMap<String, IBean>();
        for (String configName : configNames) {
          IBeansConfig config = BeansModelUtils.getConfig(configName, this);
          if (config != null) {
            for (IBean bean : config.getBeans()) {
              if (allowBeanDefinitionOverriding || !beansMap.containsKey(bean.getElementName())) {
                beansMap.put(bean.getElementName(), bean);
              }
            }
          }
        }
      }
      finally {
        this.isBeansMapPopulated = true;
        w.unlock();
      }
    }
    try {
      r.lock();
      return beansMap;
    }
    finally {
      r.unlock();
    }
  }

  /**
   * Returns lazily initialized map with all bean classes used in this config set.
   */
  private Map<String, Set<IBean>> getBeanClassesMap() {
    if (!this.isBeanClassesMapPopulated) {
      try {
        w.lock();
        if (this.isBeanClassesMapPopulated) {
          return beanClassesMap;
        }
        beanClassesMap = new LinkedHashMap<String, Set<IBean>>();
        for (IBean bean : getBeansMap().values()) {
          addBeanClassToMap(bean);
          for (IBean innerBean : BeansModelUtils.getInnerBeans(bean)) {
            addBeanClassToMap(innerBean);
          }
        }
      }
      finally {
        this.isBeanClassesMapPopulated = true;
        w.unlock();
      }
    }
    try {
      r.lock();
      return beanClassesMap;
    }
    finally {
      r.unlock();
    }
  }

  private void addBeanClassToMap(IBean bean) {

    // Get name of bean class - strip name of any inner class
    String className = bean.getClassName();
    if (className != null) {
      int pos = className.indexOf('$');
      if (pos > 0) {
        className = className.substring(0, pos);
      }

      // Maintain a list of bean names within every entry in the
      // bean class map
      Set<IBean> beanClassBeans = beanClassesMap.get(className);
      if (beanClassBeans == null) {
        beanClassBeans = new LinkedHashSet<IBean>();
        beanClassesMap.put(className, beanClassBeans);
      }
      beanClassBeans.add(bean);
    }
  }

  @SuppressWarnings("rawtypes")
  @Override
  public Object getAdapter(Class adapter) {
    if (adapter == IPersistableElement.class) {
      return new BeansModelElementToPersistableElementAdapter(this);
    }
    else if (adapter == IProject.class) {
      if (getElementParent() instanceof IBeansProject) {
        return ((IBeansProject) getElementParent()).getProject();
      }
    }
    return super.getAdapter(adapter);
  }

  public Type getType() {
    return type;
  }

  public boolean isExternal() {
    return false;
  }

  public Set<String> getProfiles() {
    return this.profiles;
  }

  public void setProfiles(Set<String> profiles) {
    this.profiles = profiles;
  }

  public void addProfile(String profile) {
    this.profiles.add(profile);
  }

  public boolean hasProfiles() {
    return this.profiles != null && this.profiles.size() > 0;
  }
}
TOP

Related Classes of org.springframework.ide.eclipse.beans.core.internal.model.BeansConfigSet

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.