Package pt.webdetails.cdf.dd.model.meta

Source Code of pt.webdetails.cdf.dd.model.meta.ComponentType$Builder

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

package pt.webdetails.cdf.dd.model.meta;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import pt.webdetails.cdf.dd.model.core.KnownThingKind;
import pt.webdetails.cdf.dd.model.meta.validation.ComponentTypeDuplicatePropertyError;
import pt.webdetails.cdf.dd.model.meta.validation.DuplicatePropertyTypeError;
import pt.webdetails.cdf.dd.model.core.validation.ValidationException;
import pt.webdetails.cdf.dd.model.meta.validation.ComponentTypeDuplicateResourceError;
import pt.webdetails.cpf.packager.origin.PathOrigin;

/**
* A type of component.
*
* @author dcleao
*/
public abstract class ComponentType extends MetaObject
{
  private static final Log _logger = LogFactory.getLog(ComponentType.class);
 
  private final Map<String, PropertyTypeUsage> _propertyUsagesByLowerAlias;
  private final Map<String, PropertyTypeUsage> _propertyUsagesByLowerName;
 
  private final List<String> _legacyNames;
 
  private final List<String> _definitionNames;
  private final Map<String, List<PropertyTypeUsage>> _propertyDefinitionsByLowerName;
 
  private final String implementationPath;
  private final Map<String, Resource> _resourcesByKey;
 
  private PathOrigin origin;
 
  protected ComponentType(Builder builder, final IPropertyTypeSource propSource) throws ValidationException
  {
    super(builder);
   
    if(propSource == null) { throw new IllegalArgumentException("propSource"); }
   
    if(builder.getPropertyUsageCount() > 0)
    {
      // Local property definitions dictionary
      final Map<String, PropertyType> propertyTypesByLowerName = new LinkedHashMap<String, PropertyType>();
     
      if(builder._propertyTypes != null) {
        // Build local properties dictionary
        for(PropertyType.Builder propBuilder : builder._propertyTypes)
        {

          PropertyType prop;
          try
          {
            prop = propBuilder.build(this);
          }
          catch(ValidationException ex)
          {
            // Ignore PropertyType, log warning and continue.
            _logger.warn(ex.getError());
            continue;
          }

          String key = prop.getName().toLowerCase();
          if(propertyTypesByLowerName.containsKey(key))
          {
            // Ignore PropertyType, log warning and continue.
            _logger.warn(new DuplicatePropertyTypeError(prop));
            continue;
          }
         
          propertyTypesByLowerName.put(key, prop);
        }
      }

      // USAGES
      final IPropertyTypeSource propSourceLocal = new IPropertyTypeSource() {
        public PropertyType getProperty(String name)
        {
          // Test existence locally first
          String key = name != null ? name.toLowerCase() : "";
          PropertyType prop = propertyTypesByLowerName.get(key);

          // Only then ask the model for a public property, if there's no local definition.
          return prop != null ? prop : propSource.getProperty(name);
        }
      };

      this._propertyUsagesByLowerAlias = new LinkedHashMap<String, PropertyTypeUsage>();
      this._propertyUsagesByLowerName  = new HashMap<String, PropertyTypeUsage>();
      this._propertyDefinitionsByLowerName  = new HashMap<String, List<PropertyTypeUsage>>();
      this._definitionNames = new ArrayList<String>();
     
      for(PropertyTypeUsage.Builder propUsageBuilder : builder._propertyUsages)
      {

        PropertyTypeUsage propUsage;
        try
        {
          propUsage = propUsageBuilder.build(this, propSourceLocal);
        }
        catch(ValidationException ex)
        {
           // Ignore PropertyTypeUsage, log warning and continue.
            _logger.warn(ex.getError());
            continue;
        }
       
        String aliasKey = propUsage.getAlias().toLowerCase();
        if(this._propertyUsagesByLowerAlias.containsKey(aliasKey))
        {
          // Ignore PropertyTypeUsage, log warning and continue.
          _logger.warn(new ComponentTypeDuplicatePropertyError(
                  this.getLabel(),
                  propUsage.getAlias()));
          continue;
        }

        this._propertyUsagesByLowerAlias.put(aliasKey, propUsage);

        // Replaces any previous entries
        String nameKey = propUsage.getProperty().getName().toLowerCase();
        this._propertyUsagesByLowerName.put(nameKey, propUsage);
       
        // -----
       
        String definitionName = propUsage.getDefinitionName();
        String definitionKey = definitionName.toLowerCase();
        List<PropertyTypeUsage> props = this._propertyDefinitionsByLowerName.get(definitionKey);
        if(props == null)
        {
          props = new ArrayList<PropertyTypeUsage>();
          this._propertyDefinitionsByLowerName.put(definitionKey, props);
          this._definitionNames.add(definitionName);
        }
       
        props.add(propUsage);
      }
    } //if(builder.getPropertyUsageCount() > 0)
    else {
      this._propertyUsagesByLowerAlias = null;
      this._propertyUsagesByLowerName = null;
      this._propertyDefinitionsByLowerName = null;
      this._definitionNames = null;
    }
   
    if(builder.getLegacyNameCount() > 0)
    {
      // Don't add duplicates
      Set<String> legacyNameSet = new HashSet<String>();
      List<String> legacyNames = new ArrayList<String>();
      for(String legacyName : builder.getLegacyNames())
      {
        // Not bothering to warn...
        if(!legacyNameSet.contains(legacyName))
        {
          legacyNameSet.add(legacyName);
          legacyNames.add(legacyName);
        }
      }
     
      this._legacyNames = legacyNames.size() > 0 ? legacyNames : null;
    }
    else
    {
      this._legacyNames = null;
    }
   
    // IMPLEMENTATION
    // TODO: is implementationPath required?
    this.implementationPath = StringUtils.defaultIfEmpty(builder.getImplementationPath(), "");
   
    if(builder.getResourceCount() > 0)
    {
      this._resourcesByKey = new LinkedHashMap<String, Resource>();

      for(Resource.Builder resBuilder : builder._resources)
      {
        Resource resource = resBuilder.build();
        String key = resource.getKey();
        if(this._resourcesByKey.containsKey(key))
        {
          // Ignore Resource, log warning and continue.
          _logger.warn(new ComponentTypeDuplicateResourceError(
              this.getLabel(),
              resource.getType(),
              resource.getName()));
          continue;
        }

        this._resourcesByKey.put(key, resource);
      }
    } else {
      this._resourcesByKey = null;
    }
    this.origin = builder.origin;
  }

  @Override
  public String getKind()
  {
    return KnownThingKind.ComponentType;
  }
 
  public final String getImplementationPath()
  {
    return this.implementationPath;
  }
 
  public PathOrigin getOrigin() {
    return this.origin;
  }
  // --------
  // PropertyTypeUsage
  public final PropertyTypeUsage getPropertyUsage(String alias)
  {
    PropertyTypeUsage propUsage = this.tryGetPropertyUsage(alias);
    if(propUsage == null)
    {
      throw new IllegalArgumentException("There is no property with alias '" + alias + "'.");
    }

    return propUsage;
  }

  public final PropertyTypeUsage getPropertyUsageByName(String name)
  {
    PropertyTypeUsage propUsage = this.tryGetPropertyUsageByName(name);
    if(propUsage == null)
    {
      throw new IllegalArgumentException("There is no property with name '" + name + "'.");
    }

    return propUsage;
  }

  public final PropertyTypeUsage tryGetPropertyUsage(String alias)
  {
    if(StringUtils.isEmpty(alias)) { throw new IllegalArgumentException("alias"); }

    return this._propertyUsagesByLowerAlias != null ?
            this._propertyUsagesByLowerAlias.get(alias.toLowerCase()) :
            null;
  }

  public final PropertyTypeUsage tryGetPropertyUsageByName(String name)
  {
    if(StringUtils.isEmpty(name)) { throw new IllegalArgumentException("name"); }

    return this._propertyUsagesByLowerName != null ?
            this._propertyUsagesByLowerName.get(name.toLowerCase()) :
            null;
  }

  public final Iterable<PropertyTypeUsage> getPropertyUsages()
  {
    return this._propertyUsagesByLowerAlias != null ?
           this._propertyUsagesByLowerAlias.values() :
           Collections.<PropertyTypeUsage> emptyList();
  }

  public final int getPropertyUsageCount()
  {
    return this._propertyUsagesByLowerAlias != null ? this._propertyUsagesByLowerAlias.size() : 0;
  }
 
  // --------
  // Property Definition
  public final Iterable<PropertyTypeUsage> getPropertiesByDefinition(String definitionName)
  {
    String key = StringUtils.defaultIfEmpty(definitionName, "").toLowerCase();
    return this._propertyDefinitionsByLowerName != null ?
           this._propertyDefinitionsByLowerName.get(key) :
           Collections.<PropertyTypeUsage> emptyList();
  }
 
  // Includes empty definition
  public final int getDefinitionCount()
  {
    return this._propertyDefinitionsByLowerName != null ?
           this._propertyDefinitionsByLowerName.size() :
           0;
  }
 
  // Hope keySet maintains order.
  public final Iterable<String> getDefinitionNames()
  {
    return this._definitionNames != null ?
           this._definitionNames :
           Collections.<String> emptyList();
  }
 
  // --------
  // Legacy Names
  public Iterable<String> getLegacyNames()
  {
    return this._legacyNames != null ?
           this._legacyNames :
           Collections.<String> emptyList();
  }

  public int getLegacyNameCount()
  {
    return this._legacyNames != null ? this._legacyNames.size() : 0;
  }
   
  // --------
  // Resources

  public Resource getResource(Resource.Type type, String name)
  {
    if(type == null) { throw new IllegalArgumentException("type"); }
    if(StringUtils.isEmpty(name)) { throw new IllegalArgumentException("name"); }

    String key = Resource.buildKey(type, name);

    Resource resource = this._resourcesByKey != null ?
            this._resourcesByKey.get(key) :
            null;
    if(resource == null)
    {
      throw new IllegalArgumentException("There is no resource with name '" + name + "' and type '" + type + "'.");
    }

    return resource;
  }

  public Iterable<Resource> getResources()
  {
    return this._resourcesByKey != null ?
           this._resourcesByKey.values() :
           Collections.<Resource> emptyList();
  }

  public int getResourceCount()
  {
    return this._resourcesByKey != null ? this._resourcesByKey.size() : 0;
  }
 
  /**
   * Class to create and modify ComponentType instances.
   */
  public static abstract class Builder extends MetaObject.Builder
  {
    private List<PropertyTypeUsage.Builder> _propertyUsages = new ArrayList<PropertyTypeUsage.Builder>();
    private List<PropertyType.Builder> _propertyTypes;
   
    private List<String> _legacyNames;
   
    private String _implementationPath;
    private List<Resource.Builder> _resources;
    private PathOrigin origin;
   
    public Builder()
    {
      super();
      _propertyUsages.add(new PropertyTypeUsage.Builder().setName("name"));
    }
   
    public void setOrigin(PathOrigin pathOrigin) {
      this.origin = pathOrigin;
    }
   
    public String getImplementationPath()
    {
      return this._implementationPath;
    }

    public Builder setImplementationPath(String implementationPath)
    {
      this._implementationPath = implementationPath;
      return this;
    }

    // --------
    // PropertyTypeUsage
    public Builder useProperty(PropertyTypeUsage.Builder prop)
    {
      assert prop != null;

      this._propertyUsages.add(prop);

      return this;
    }

    public Builder useProperty(String alias, String name)
    {
      return this.useProperty(new PropertyTypeUsage.Builder()
                  .setAlias(alias)
                  .setName(name));
    }
   
    public Builder useProperty(String alias, String name, String definitionName)
    {
      return this.useProperty(new PropertyTypeUsage.Builder()
                  .setAlias(alias)
                  .setName(name)
                  .setDefinitionName(definitionName));
    }

    public Iterable<PropertyTypeUsage.Builder> getPropertyUsages()
    {
      return this._propertyUsages != null ?
             this._propertyUsages :
             Collections.<PropertyTypeUsage.Builder> emptyList();
    }

    public int getPropertyUsageCount()
    {
      return this._propertyUsages != null ? this._propertyUsages.size() : 0;
    }

    public Builder addProperty(PropertyType.Builder prop)
    {
      if(prop == null) { throw new IllegalArgumentException("prop"); }

      if(this._propertyTypes == null)
      {
        this._propertyTypes = new ArrayList<PropertyType.Builder>();
      }

      this._propertyTypes.add(prop);

      return this;
    }

    public Iterable<PropertyType.Builder> getProperties()
    {
      return this._propertyTypes != null ?
             this._propertyTypes :
             Collections.<PropertyType.Builder> emptyList();
    }

    public int getPropertyCount()
    {
      return this._propertyTypes != null ? this._propertyTypes.size() : 0;
    }
   
    // --------
    // Legacy Names
    public Builder addLegacyName(String legacyName)
    {
      if(StringUtils.isEmpty(legacyName)) { throw new IllegalArgumentException("legacyName"); }

      if(this._legacyNames == null)
      {
        this._legacyNames = new ArrayList<String>();
      }

      this._legacyNames.add(legacyName);

      return this;
    }

    public Iterable<String> getLegacyNames()
    {
      return this._legacyNames != null ?
             this._legacyNames :
             Collections.<String> emptyList();
    }

    public int getLegacyNameCount()
    {
      return this._legacyNames != null ? this._legacyNames.size() : 0;
    }

    // --------
    // Resources
    public Builder addResource(Resource.Builder res)
    {
      assert res != null;

      res.setOrigin(origin);
      if(this._resources == null)
      {
        this._resources = new ArrayList<Resource.Builder>();
      }

      this._resources.add(res);

      return this;
    }

    public Iterable<Resource.Builder> getResources()
    {
      return this._resources != null ?
             this._resources :
             Collections.<Resource.Builder> emptyList();
    }

    public int getResourceCount()
    {
      return this._resources != null ? this._resources.size() : 0;
    }
   
    public abstract ComponentType build(IPropertyTypeSource propSource)
            throws ValidationException;
  }
}
TOP

Related Classes of pt.webdetails.cdf.dd.model.meta.ComponentType$Builder

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.