Package fr.imag.adele.apam.impl

Source Code of fr.imag.adele.apam.impl.ImplementationImpl$SystemRootImplementation

/**
* Copyright 2011-2012 Universite Joseph Fourier, LIG, ADELE team
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
package fr.imag.adele.apam.impl;

import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.imag.adele.apam.ApamManagers;
import fr.imag.adele.apam.CST;
import fr.imag.adele.apam.Component;
import fr.imag.adele.apam.Composite;
import fr.imag.adele.apam.CompositeType;
import fr.imag.adele.apam.Implementation;
import fr.imag.adele.apam.Instance;
import fr.imag.adele.apam.Specification;
import fr.imag.adele.apam.apform.ApformImplementation;
import fr.imag.adele.apam.apform.ApformInstance;
import fr.imag.adele.apam.declarations.ComponentKind;
import fr.imag.adele.apam.declarations.CompositeDeclaration;
import fr.imag.adele.apam.declarations.ImplementationDeclaration;
import fr.imag.adele.apam.declarations.references.components.ImplementationReference;
import fr.imag.adele.apam.declarations.references.resources.ResourceReference;
import fr.imag.adele.apam.util.Visible;

public class ImplementationImpl extends ComponentImpl implements Implementation {

  /**
   * This class represents the Apam root implementation.
   *
   * This is an APAM concept without mapping at the execution platform level,
   * we build an special apform object to represent it.
   *
   */
  private static class SystemRootImplementation extends BaseApformComponent<CompositeType, ImplementationDeclaration> implements ApformImplementation {

    public SystemRootImplementation(String name) {
      super(new CompositeDeclaration(name, null, new ImplementationReference<ImplementationDeclaration>("Root Main Implem")));
    }

    @Override
    public ApformInstance addDiscoveredInstance(Map<String, Object> configuration) throws InvalidConfiguration, UnsupportedOperationException {
      throw new UnsupportedOperationException("method not available in root type");
    }

    @Override
    public ApformInstance createInstance(Map<String, String> initialproperties) {
      throw new UnsupportedOperationException("method not available in root type");
    }

    @Override
    public boolean remLink(Component destInst, String depName) {
      throw new UnsupportedOperationException("method not available in root type");
    }

    @Override
    public void setApamComponent(Component apamComponent) {
      throw new UnsupportedOperationException("method not available in root type");
    }

    @Override
    public boolean setLink(Component destInst, String depName) {
      throw new UnsupportedOperationException("method not available in root type");
    }

    @Override
    public void setProperty(String attr, String value) {
      throw new UnsupportedOperationException("method not available in root type");
    }

  }

  private static Logger logger = LoggerFactory.getLogger(ImplementationImpl.class);

  private static final long serialVersionUID = 1L;

  // composite in which it is contained
  private Set<CompositeType> inComposites = Collections.newSetFromMap(new ConcurrentHashMap<CompositeType, Boolean>());

  // The specification this implementation implements
  protected Specification mySpec;

  // // all relationship use and their reverse
  // private Set<Implementation> uses = Collections.newSetFromMap(new
  // ConcurrentHashMap<Implementation, Boolean>());
  // private Set<Implementation> invUses = Collections.newSetFromMap(new
  // ConcurrentHashMap<Implementation, Boolean>());

  // the instances
  private Set<Instance> instances = Collections.newSetFromMap(new ConcurrentHashMap<Instance, Boolean>());

  /**
   * Builds a new Apam implementation to represent the specified platform
   * implementation in the Apam model.
   */
  protected ImplementationImpl(CompositeType composite, ApformImplementation apfImpl) throws InvalidConfiguration {
    super(apfImpl);

    ImplementationDeclaration declaration = apfImpl.getDeclaration();

    /*
     * Reference the declared provided specification
     */
    if (declaration.getSpecification() != null) {

      String specificationName = declaration.getSpecification().getName();
      Specification specification = CST.componentBroker.getSpec(specificationName);

      assert specification != null;
      mySpec = specification;

    }

    /*
     * If the implementation does not provides explicitly any specification,
     * we build a dummy specification to allow the resolution algorithm to
     * access the provided resources of this implementation
     */
    if (mySpec == null) {
      mySpec = CST.componentBroker.createSpec(declaration.getName() + "_spec", declaration.getProvidedResources(), (Map<String, String>) null);
    }

    /*
     * Reference the enclosing composite type
     */
    addInComposites(composite);

  }

  /**
   * This is an special constructor only used for the root type of the system
   */
  protected ImplementationImpl(String name) throws InvalidConfiguration {
    super(new SystemRootImplementation(name));
    mySpec = CST.componentBroker.createSpec(name + "_spec", new HashSet<ResourceReference>(), null);
  }

  public void addInComposites(CompositeType compo) {
    inComposites.add(compo);
  }

  // WARNING : no control ! Only called by instance registration.
  public void addInst(Instance instance) {
    assert instance != null && !instances.contains(instance);
    instances.add(instance);
  }

  /**
   * If this implementation can be instantiated in the specified composite
   */
  public boolean canBeInstantiatedIn(Composite composite) {
    return Visible.isVisibleIn(composite, this);
  }

  /**
   * From an implementation, create an instance. Creates both the apform and
   * APAM instances. Can be called from the API.
   *
   * Must check if source composite can instantiate this implementation.
   */
  @Override
  public Instance createInstance(Composite composite, Map<String, String> initialProperties) {

    if ((composite != null) && !this.canBeInstantiatedIn(composite)) {
      logger.error("cannot instantiate " + this + ". It is not visible from composite " + composite);
      return null;
    }

    if (composite == null) {
      composite = CompositeImpl.getRootAllComposites();
    }

    /*
     * Create and register the object in the APAM state model
     */
   
    Instance instance = null;
    try {
      instance = instantiate(composite, initialProperties);
      ((InstanceImpl) instance).register(initialProperties);
      setInstantiateFails(false);
      return instance;
    } catch (InvalidConfiguration configurationError) {

      /*
       * TODO this should be done in method register, we should try to have some form
       * of atomic registration that includes registration and addition in the broker
       */
      if (instance != null) {
        if (CST.componentBroker.getComponent(instance.getName()) != null) {
          /*
           * If creation failed after broker registration, undo registration
           */
          ((ComponentBrokerImpl) CST.componentBroker).disappearedComponent(instance);
        }
        else {
         
          /*
           * The instance was partially created, just undo registration
           */
          ((ComponentImpl)instance).unregister();
        }
      }
     
      logger.error("Error instantiating implementation " + this.getName() + ": exception registering instance in APAM " + configurationError.getMessage());
      //to avoid trying again when attempting a resolution.
      setInstantiateFails(true);
    }
    return null;
  }

  @Override
  public ApformImplementation getApformImpl() {
    return (ApformImplementation) getApformComponent();
  }

  @Override
  public Component getGroup() {
    return mySpec;
  }

  @Override
  public ImplementationDeclaration getImplDeclaration() {
    return (ImplementationDeclaration) getDeclaration();
  }

  @Override
  public Set<CompositeType> getInCompositeType() {
    return Collections.unmodifiableSet(inComposites);
  }

  /**
   * returns the first instance only.
   */
  @Override
  public Instance getInst() {
    if (instances.size() == 0) {
      return null;
    }
    return (Instance) instances.toArray()[0];
  }

  @Override
  public Instance getInst(String targetName) {
    if (targetName == null) {
      return null;
    }
    for (Instance inst : instances) {
      if (inst.getName().equals(targetName)) {
        return inst;
      }
    }
    return null;
  }

  @Override
  public Set<Instance> getInsts() {
    return Collections.unmodifiableSet(instances);
  }

  @Override
  public ComponentKind getKind() {
    return ComponentKind.IMPLEMENTATION;
  }

  @Override
  public Set<? extends Component> getMembers() {
    return Collections.unmodifiableSet(instances);
  }

  @Override
  public Specification getSpec() {
    return mySpec;
  }

  /**
   * Create a new instance from this implementation in Apam and in the
   * underlying execution platform.
   *
   * WARNING The created Apam instance is not automatically published in the
   * Apam state, nor added to the list of instances of this implementation.
   * This is actually done when the returned instance is registered by the
   * caller of this method.
   *
   * This method is not intended to be used as external API.
   */
  protected Instance instantiate(Composite composite, Map<String, String> initialProperties) throws InvalidConfiguration {

    if (!this.isInternalInstantiable()) {
      throw new InvalidConfiguration("Implementation " + this + " is not instantiable");
    }

    if (this.isSingleton() && !instances.isEmpty()) {
      throw new InvalidConfiguration("Implementation " + this + " is a singleton and an instance exists");
    }

    return reify(composite, getApformImpl().createInstance(initialProperties));
  }

  @Override
  public boolean isUsed() {
    return !inComposites.contains(CompositeTypeImpl.getRootCompositeType()) && inComposites.size() == 1;
  }

  @Override
  public void register(Map<String, String> initialProperties) throws InvalidConfiguration {

    /*
     * Opposite references from specification and enclosing composite type
     */
    ((SpecificationImpl) mySpec).addImpl(this);

    for (CompositeType inComposite : inComposites) {
      ((CompositeTypeImpl) inComposite).addImpl(this);
    }

    /*
     * Terminates the initialization, and computes properties
     */
    finishInitialize(initialProperties);

    /*
     * Add to broker
     */
    ((ComponentBrokerImpl) CST.componentBroker).add(this);

    /*
     * Bind to the underlying execution platform implementation
     */
    getApformImpl().setApamComponent(this);

    /*
     * Notify managers
     */
    ApamManagers.notifyAddedInApam(this);

  }

  /**
   * Reifies in Apam an instance of this implementation from the information
   * of the underlying platform.
   *
   * This method should be overridden to implement different reification
   * semantics for different subclasses of implementation.
   *
   * WARNING The reified Apam instance is not automatically published in the
   * Apam state, nor added to the list of instances of this implementation.
   * This is actually done when the returned instance is registered by the
   * caller of this method.
   *
   * This method is not intended to be used as external API.
   *
   */
  protected Instance reify(Composite composite, ApformInstance platformInstance) throws InvalidConfiguration {
    return new InstanceImpl(composite, platformInstance);
  }

  // relation uses control

  // @Override
  // public Set<Implementation> getUses() {
  // return Collections.unmodifiableSet(uses);
  // }
  //
  // @Override
  // public Set<Implementation> getInvUses() {
  // return Collections.unmodifiableSet(invUses);
  // }
  //
  // public void addUses(Implementation dest) {
  // if (uses.contains(dest))
  // return;
  // uses.add(dest);
  // ((ImplementationImpl) dest).addInvUses(this);
  // ((SpecificationImpl) getSpec()).addRequires(dest.getSpec());
  // }
  //
  // public void removeUses(Implementation dest) {
  // for (Instance inst : instances) {
  // for (Instance instDest : inst.getWireDests())
  // if (instDest.getImpl() == dest) {
  // return; // it exists another instance that uses that destination. Do
  // nothing.
  // }
  // }
  // uses.remove(dest);
  // ((ImplementationImpl) dest).removeInvUses(this);
  // ((SpecificationImpl) getSpec()).removeRequires(dest.getSpec());
  // }
  //
  // private void addInvUses(Implementation orig) {
  // invUses.add(orig);
  // }
  //
  // private void removeInvUses(Implementation orig) {
  // invUses.remove(orig);
  // }

  public void removeInComposites(CompositeType compo) {
    inComposites.remove(compo);
  }

  public void removeInst(Instance instance) {
    instances.remove(instance);
  }

  @Override
  public void unregister() {
    logger.debug("unregister implementation " + this);

    /*
     * Remove opposite references from specification and enclosing composite
     * types
     */
    ((SpecificationImpl) getSpec()).removeImpl(this);
    for (CompositeType inComposite : inComposites) {
      ((CompositeTypeImpl) inComposite).removeImpl(this);
    }

    /*
     * remove all existing instances
     */
    for (Instance inst : instances) {
      ((ComponentBrokerImpl)CST.componentBroker).disappearedComponent(inst);
    }

    // Do not remove inverse links, in case threads are still here.
  }
}
TOP

Related Classes of fr.imag.adele.apam.impl.ImplementationImpl$SystemRootImplementation

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.