예제 #1
0
  @Override
  public Set<ResourceReference> getProvidedResources() {
    Set<ResourceReference> provided = new HashSet<ResourceReference>();

    /*
     * add all provided resources declared at all levels of abstraction
     */
    Component ancestor = this;
    while (ancestor != null) {
      provided.addAll(ancestor.getDeclaration().getProvidedResources());
      ancestor = ancestor.getGroup();
    }

    return Collections.unmodifiableSet(provided);
  }
예제 #2
0
  /**
   * Tries to find the definition of attribute "attr" associated with component "component". Returns
   * null if the attribute is not explicitly defined
   *
   * @param component
   * @param attr
   * @return
   */
  public PropertyDefinition getAttrDefinition(String attr) {

    // PropertyDefinition definition =
    // getDeclaration().getPropertyDefinition(attr);
    // if (definition != null) {
    // return definition;
    // }

    PropertyDefinition definition = null;
    Component group = this; // .getGroup();
    while (group != null) {
      definition = group.getDeclaration().getPropertyDefinition(attr);
      if (definition != null) {
        return definition;
      }
      group = group.getGroup();
    }
    return null;
  }
예제 #3
0
  /**
   * Given a relation declared in this component, checks if the provided override relation matches
   * the relation declaration.
   *
   * <p>To be applied on a component C, the override must be such that : id matches the override id
   * source must be the name of C or of an ancestor of C. target must be the same type (resource of
   * component, and its name must match).
   */
  public boolean matchOverride(RelationDeclaration relation, RelationDeclaration override) {

    // Overrides are currently only valid for instance
    boolean match = (this instanceof Instance);
    if (!match) {
      return false;
    }

    // Check if override source matches this component or one of its
    // ancestors

    match = false;
    Component group = this;
    while (group != null && !match) {
      match = override.refines(group.getDeclaration().getReference(), relation);
      group = group.getGroup();
    }

    return match;
  }
예제 #4
0
  /**
   * To be called once the Apam entity is fully initialized.
   *
   * <p>Computes all its attributes, including inheritance. Checks if initial properties are
   * consistent with the declarations.
   *
   * <p>NOTE this method is also called when the owner changes, to force recalculation of
   * substitutions that depend on the current owner.
   */
  private void initializeProperties(Map<String, String> initialProperties) {

    Component group = getGroup();

    /*
     * Currently the instance declaration may include invalid properties.
     *
     * For declared instances this should not happen as the declaration is validated at build-time. For dynamically
     * created instances (using the APAM API or the apform API directly) this should be validated by this method.
     *
     * However, there are many properties added by the iPOJO apform layer that need to be ignored, so we simply
     * silently ignore all invalid properties.
     *
     * TODO We should be able to distinguish properties specified by the user that must be validated, from properties
     * used internally by the iPOJO apform.
     */
    Set<String> invalidDeclaredProperties = new HashSet<String>();
    for (String property : getDeclaration().getProperties().keySet()) {

      boolean isDefined =
          getDeclaration().isDefined(property)
              || (group != null && group.getPropertyDefinition(property) != null);

      if (!isDefined) {
        invalidDeclaredProperties.add(property);
      }

      if (group != null && group.getProperty(property) != null) {
        invalidDeclaredProperties.add(property);
      }
    }

    getDeclaration().getProperties().keySet().removeAll(invalidDeclaredProperties);

    /*
     * Merge initial and declared properties.
     *
     */
    Map<String, String> fullInitialProperties =
        new HashMap<String, String>(getDeclaration().getProperties());
    if (initialProperties != null) {
      fullInitialProperties.putAll(initialProperties);
      fullInitialProperties.remove("instance.name");
    }

    /*
     * NOTE  In the case of change owner, the initial properties include inherited values from the group,
     * we ignore them to avoid false error messages, they will be added later by the normal inheritance
     * mechanism
     *
     * TODO Distinguish the case of change owner from a real initialization
     */
    if (initialProperties != null && group != null) {
      for (Map.Entry<String, String> initialProperty : initialProperties.entrySet()) {
        if (group.getProperty(initialProperty.getKey()) != null
            && group.getProperty(initialProperty.getKey()).equals(initialProperty.getValue())) {
          fullInitialProperties.remove(initialProperty.getKey());
        }
      }
    }

    // start cleaning the properties (normally empty)
    clear();

    /*
     *  First add the valid attributes.
     */
    for (Map.Entry<String, String> initialProperty : fullInitialProperties.entrySet()) {

      PropertyDefinition def = validDef(initialProperty.getKey(), true);
      if (def != null) {
        Object val =
            Attribute.checkAttrType(
                initialProperty.getKey(), initialProperty.getValue(), def.getType());
        if (val != null) {
          put(initialProperty.getKey(), val);
        }
      }
    }

    /*
     *  then add those coming from its group, avoiding overloads.
     */
    if (group != null) {
      for (String attr : group.getAllProperties().keySet()) {
        if (get(attr) == null) {
          put(attr, ((ComponentImpl) group).get(attr));
        }
      }
    }

    /*
     * Add the default values specified in the group for properties not explicitly specified
     */
    if (group != null) {
      for (PropertyDefinition definition : group.getDeclaration().getPropertyDefinitions()) {
        if (definition.hasDefaultValue()
            && get(definition.getName()) == null
            && definition.getInjected() != InjectedPropertyPolicy.INTERNAL) {
          Object val =
              Attribute.checkAttrType(
                  definition.getName(), definition.getDefaultValue(), definition.getType());
          if (val != null) {
            put(definition.getName(), val);
          }
        }
      }
    }

    /*
     * Set the attribute for the final attributes
     */
    put(CST.SHARED, Boolean.toString(isShared()));
    put(CST.SINGLETON, Boolean.toString(isSingleton()));
    put(CST.INSTANTIABLE, Boolean.toString(isInstantiable()));

    /*
     * Finally add the specific attributes.
     * Should be the only place where instanceof is used.
     */
    put(CST.NAME, apform.getDeclaration().getName());
    if (this instanceof Specification) {
      put(CST.SPECNAME, apform.getDeclaration().getName());
    } else if (this instanceof Implementation) {
      put(CST.IMPLNAME, apform.getDeclaration().getName());
      if (this instanceof CompositeType) {
        put(CST.APAM_COMPOSITETYPE, CST.V_TRUE);
      }
    } else if (this instanceof Instance) {
      put(CST.INSTNAME, apform.getDeclaration().getName());
      if (this instanceof Composite) {

        Composite composite = (Composite) this;
        put(CST.APAM_COMPOSITE, CST.V_TRUE);
        if (composite.getMainInst() != null) {
          put(CST.APAM_MAIN_INSTANCE, composite.getMainInst().getName());
        }
      }
    }

    /*
     *  and propagate, to the platform and to members, in case the spec has been created after the implem
     */
    for (Map.Entry<String, Object> entry : this.entrySet()) {
      for (Component member : getMembers()) {
        ((ComponentImpl) member).propagate(entry.getKey(), entry.getValue());
      }
    }
  }
예제 #5
0
  /**
   * Provided a component, compute its effective relations definition, adding group constraint and
   * flags. It is supposed to be correct !! No failure expected
   *
   * <p>Does not add those dependencies defined "above". For relations refined locally, merge the
   * local definition with the group definition.
   *
   * <p>For instances only, add the relation definition overridden by the composite.
   *
   * <p>Remove those links that are not valid with the computed relation definition (for
   * changeOwner)
   */
  private void initializeRelations() {

    /*
     * First we need to compute the list of relations that must be locally
     * defined in this component. We consider locally defined relation
     * declarations and overridden inherited relations.
     */
    Set<RelationDeclaration> overrides = null;
    if (this instanceof Instance) {
      overrides =
          ((Instance) this)
              .getComposite()
              .getCompType()
              .getCompoDeclaration()
              .getOverridenDependencies();
    } else overrides = Collections.emptySet();

    Set<RelationDeclaration> localRelations = new HashSet<RelationDeclaration>();
    Set<String> processed = new HashSet<String>();

    Component group = this;
    while (group != null) {

      for (RelationDeclaration relationDeclaration : group.getDeclaration().getRelations()) {

        /*
         * Ignore relations already processed at a lower level
         */
        if (processed.contains(relationDeclaration.getIdentifier())) {
          continue;
        }

        /*
         * Check overridden relations
         */
        boolean matchOverride = false;
        for (RelationDeclaration override : overrides) {
          //					for (RelationDeclaration override : overrides != null ? overrides
          //							: Collections.<RelationDeclaration> emptySet()) {
          if (matchOverride(relationDeclaration, override)) {
            relationDeclaration = relationDeclaration.overriddenBy(override);
            matchOverride = true;
          }
        }

        /*
         * Process locally declared and inherited overridden relations
         */
        if (group == this || matchOverride) {
          localRelations.add(relationDeclaration);
          processed.add(relationDeclaration.getIdentifier());
        }
      }
      group = group.getGroup();
    }

    /*
     * Define all the local relations definition of this component
     */
    for (RelationDeclaration relationDeclaration : localRelations) {
      /*
       * Local declarations may be partial definitions, we need to compute
       * the complete declaration by refining the ancestor definition.
       */
      RelationDefinition base = this.getRelation(relationDeclaration.getIdentifier());
      relationDeclaration =
          (base == null)
              ? relationDeclaration
              : ((RelationDefinitionImpl) base).refinedBy(relationDeclaration);

      relDef.put(
          relationDeclaration.getIdentifier(), new RelationDefinitionImpl(relationDeclaration));
    }

    /*
     * If the component has links, remove those that are invalid (for changeOwner)
     * Also remove the link if it is a promotion, since we are no longer in the same composite
     */
    for (Link localLink : getLocalLinks()) {
      if (localLink.isPromotion() || !localLink.isValid()) localLink.remove();
    }

    for (Link incoming : getInvLinks()) {
      if (incoming.isPromotion() || !incoming.isValid()) incoming.remove();
    }
  }