Package org.obeonetwork.dsl.sysml.design.services

Source Code of org.obeonetwork.dsl.sysml.design.services.SysMLServices

/*******************************************************************************
* Copyright (c) 2009, 2011, 2012 Obeo.
* 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:
*     Obeo - initial API and implementation
*******************************************************************************/
package org.obeonetwork.dsl.sysml.design.services;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.sysml.blocks.Block;
import org.eclipse.papyrus.sysml.blocks.Dimension;
import org.eclipse.papyrus.sysml.blocks.Unit;
import org.eclipse.papyrus.sysml.blocks.ValueType;
import org.eclipse.papyrus.sysml.constraints.ConstraintBlock;
import org.eclipse.papyrus.sysml.constraints.ConstraintProperty;
import org.eclipse.papyrus.sysml.portandflows.FlowDirection;
import org.eclipse.papyrus.sysml.portandflows.FlowPort;
import org.eclipse.papyrus.sysml.requirements.DeriveReqt;
import org.eclipse.papyrus.sysml.requirements.Requirement;
import org.eclipse.papyrus.sysml.requirements.Satisfy;
import org.eclipse.papyrus.sysml.requirements.TestCase;
import org.eclipse.papyrus.sysml.requirements.Verify;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DEdge;
import org.eclipse.sirius.diagram.DNodeContainer;
import org.eclipse.sirius.diagram.DNodeList;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.diagram.business.internal.metamodel.spec.DSemanticDiagramSpec;
import org.eclipse.sirius.diagram.description.DiagramDescription;
import org.eclipse.sirius.diagram.description.Layer;
import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.uml2.uml.Abstraction;
import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.Actor;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.BehavioredClassifier;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Collaboration;
import org.eclipse.uml2.uml.DataType;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.PrimitiveType;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.StateMachine;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UseCase;
import org.eclipse.uml2.uml.profile.standard.Refine;
import org.obeonetwork.dsl.sysml.design.Activator;
import org.obeonetwork.dsl.uml2.design.services.EcoreServices;
import org.obeonetwork.dsl.uml2.design.services.UIServices;
import org.obeonetwork.dsl.uml2.design.services.UMLServices;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;

/**
* Utility services for SysML.
*
* @author Axel Richard <a href="mailto:axel.richard@obeo.fr">axel.richard@obeo.fr</a>
* @author Melanie Bats <a href="mailto:melanie.bats@obeo.fr">melanie.bats@obeo.fr</a>
*/
public class SysMLServices {

  /**
   * Sysml requirement stereotype.
   */
  private static final String SYSML_REQUIREMENT = "SysML::Requirements::Requirement";

  /**
   * Sysml testcase stereotype.
   */
  private static final String SYSML_TESTCASE = "SysML::Requirements::TestCase";

  /**
   * Sysml block stereotype.
   */
  private static final String SYSML_BLOCK = "SysML::Blocks::Block";

  /**
   * Check if a profile is applied on a package based on its qualified name.
   *
   * @param currentPackage
   *            Package
   * @param profileQualifiedName
   *            Profile qualified name
   * @return True if profile is laready applied otherwised false
   */
  private static Boolean isProfileApplied(Package currentPackage, String profileQualifiedName) {
    final EList<Profile> allProfiles = currentPackage.getAllAppliedProfiles();
    final Iterator<Profile> it = allProfiles.iterator();
    while (it.hasNext()) {
      Profile cur = it.next();
      if (profileQualifiedName.equalsIgnoreCase(cur.getQualifiedName()))
        return true;
    }
    return false;
  }

  /**
   * Apply each profiles to the given Package. The first parameter is the package. The second is the profile
   * to apply. In case of error when the profile is applied, a message is logged in the activator logger. In
   * case of multiple application of the profile, a message is logged in the activator logger.
   *
   * @param p
   *            : the given Package
   * @param profileQualifiedName
   *            : the profile qualified name you want to apply.
   */
  private void applySysMLProfile(Package p, String profileQualifiedName) {
    if (isProfileApplied(p, profileQualifiedName))
      return;
    Profile parentProfile = null;
    if (profileQualifiedName.startsWith("SysML")) {
      parentProfile = Activator.getSysMLProfile();
    } else if (profileQualifiedName.startsWith("Standard")) {
      parentProfile = Activator.getStandardProfile();
    }

    Package profilePackage = parentProfile;

    final String[] profiles = profileQualifiedName.split(":{2}");
    // search the profile in the package hierarchy
    for (int index = 1; index < profiles.length - 1; index++) {
      profilePackage = profilePackage.getNestedPackage(profiles[index]);
    }

    Profile profile = (Profile)profilePackage;

    if (profileQualifiedName.startsWith("SysML")) {
      profile = (Profile)profilePackage.getNestedPackage(profiles[profiles.length - 1]);
    }

    if (profile == null) {
      final String message = "Can't apply the profile " + profileQualifiedName + " on "
          + p.getQualifiedName();
      Activator.log(Status.WARNING, message, null);
    } else {
      p.applyProfile(profile);
    }
  }

  /**
   * Create the Associated Stereotype with the given element.
   *
   * @param e
   *            : the given element for which you want to apply the stereotype.
   * @param profileQualifiedName
   *            : the qualified name of the stereotype's profile you want to apply (ex. : SysML::Blocks for
   *            a Block).
   * @param stereotypeName
   *            : the name of the stereotype you want to apply.
   */
  public void createAssociatedStereotype(Element e, String profileQualifiedName, String stereotypeName) {

    applySysMLProfile(e.getModel(), profileQualifiedName);

    final Element element = e;
    final String stereotypeQualifiedName = profileQualifiedName + "::" + stereotypeName;

    final Stereotype stereotype = element.getApplicableStereotype(stereotypeQualifiedName);
    final EList<Stereotype> appliedStereotypes = element.getAppliedStereotypes();

    if (stereotype == null) {
      final String message = "Can't apply the setereotype " + stereotypeQualifiedName + " on "
          + element.toString();
      Activator.log(Status.WARNING, message, null);
    } else if (appliedStereotypes != null && appliedStereotypes.contains(stereotype)) {
      final String message = "The stereotype " + stereotype.getQualifiedName()
          + " is already applied on " + element.toString();
      Activator.log(Status.INFO, message, null);
    } else {
      element.applyStereotype(stereotype);
    }
  }

  /**
   * Delete the Associated Stereotype with the given element.
   *
   * @param e
   *            : the given element for which you want to delete the stereotype.
   * @param steQualified
   *            : the qualified name of the stereotype you want to delete (ex. : SysML::Blocks::Block).
   */
  public void deleteAssociatedStereotype(Element e, String steQualified) {
    final Element element = e;

    if (element != null && steQualified != null) {
      final Stereotype stereotype = element.getAppliedStereotype(steQualified);
      if (stereotype != null) {
        element.unapplyStereotype(stereotype);
      }
    } else {
      final String message = "Can't delete the stereotype application because the element or the stereotypeName keys are not correct";
      Activator.log(Status.INFO, message, null);
    }
  }

  /**
   * Determines if the given element is an instance of the type.
   *
   * @param e
   *            : the given Element.
   * @param type
   *            : the type passed as a String.
   * @return true if the given element is an instance of the type, false otherwise.
   */
  public boolean isInstanceOf(Element e, String type) {
    if (e.eClass().getName().equalsIgnoreCase(type)) {
      return true;
    }
    return false;

  }

  /**
   * Set the dimension feature for the given PrimitiveType stereotyped with a ValueType.
   *
   * @param pt
   *            : the given Element (a PrimitiveType stereotyped with a ValueType).
   * @param is
   *            : the new Dimension (an InstanceSpecification stereotyped with a Dimension).
   */
  public void setDimensionForPrimitiveType(Element pt, InstanceSpecification is) {
    if (is != null && pt != null) {
      final Stereotype valueType = pt.getAppliedStereotype("SysML::Blocks::ValueType");
      final Dimension newDimension = (Dimension)is.getStereotypeApplication(is
          .getAppliedStereotype("SysML::Blocks::Dimension"));
      pt.setValue(valueType, "dimension", newDimension);
    }
  }

  /**
   * Set the unit feature for the given PrimitiveType stereotyped with a ValueType.
   *
   * @param pt
   *            : the given Element (a PrimitiveType stereotyped with a ValueType).
   * @param is
   *            : the new Unit (an InstanceSpecification stereotyped with a Unit).
   */
  public void setUnitForPrimitiveType(Element pt, InstanceSpecification is) {
    if (is != null && pt != null) {
      final Stereotype valueType = pt.getAppliedStereotype("SysML::Blocks::ValueType");
      final Unit newUnit = (Unit)is.getStereotypeApplication(is
          .getAppliedStereotype("SysML::Blocks::Unit"));
      pt.setValue(valueType, "unit", newUnit);
    }
  }

  /**
   * Set the id feature for the given Class stereotyped with a Requirement.
   *
   * @param r
   *            : the given Element (a Class stereotyped with a Requirement).
   * @param id
   *            : the new id (a string).
   */
  public void setIdForRequirement(Element r, String id) {
    if (r != null && id != null) {
      final Stereotype requirement = r.getAppliedStereotype(SYSML_REQUIREMENT);
      r.setValue(requirement, "id", id);
    }
  }

  /**
   * Set the text feature for the given Class stereotyped with a Requirement.
   *
   * @param r
   *            : the given Element (a Class stereotyped with a Requirement).
   * @param text
   *            : the new text (a string).
   */
  public void setTextForRequirement(Element r, String text) {
    if (r != null && text != null) {
      final Stereotype requirement = r.getAppliedStereotype(SYSML_REQUIREMENT);
      r.setValue(requirement, "text", text);
    }
  }

  /**
   * Returns the root container; it may be this object itself.
   *
   * @param eObject
   *            the object to get the root container for.
   * @return the root container.
   */
  public EObject getRootContainer(EObject eObject) {
    return EcoreUtil.getRootContainer(eObject);
  }

  /**
   * Check if the given layer is activated.
   *
   * @param object
   *            the semantic diagram
   * @param layerID
   *            the given layer represented by his ID.
   * @return true if the given layer is activated, false otherwise.
   */
  public boolean isLayerActivated(EObject object, String layerID) {
    if (object instanceof DSemanticDiagram) {
      final DSemanticDiagram d = (DSemanticDiagram)object;
      for (Layer layer : d.getActivatedLayers()) {
        if (layerID.equals(layer.getName())) {
          return true;
        }
      }
    }
    return false;
  }

  /**
   * Get UML String type.
   *
   * @param object
   *            the object for which to find the corresponding String type
   * @return the found String element or null
   */
  public Type getUmlStringType(EObject object) {
    return EcoreServices.INSTANCE.findTypeByName(object, "String");
  }

  /**
   * Update stereotype of element if needed.
   *
   * @param element
   *            the given Element.
   * @return th element updated.
   */
  public Element updateStereotype(Element element) {
    if (element instanceof Property) {
      final Type type = ((Property)element).getType();
      if (type != null) {
        final Collection<EObject> elementStereotypes = element.getStereotypeApplications();
        final Collection<EObject> typeStereotypes = type.getStereotypeApplications();
        for (EObject typeStereotype : typeStereotypes) {
          if (typeStereotype instanceof ConstraintBlock) {
            if (elementStereotypes == null || elementStereotypes.isEmpty()) {
              createAssociatedStereotype(element, "SysML::Constraints", "ConstraintProperty");
              break;
            } else {
              for (EObject elementStereotype : elementStereotypes) {
                if (!(elementStereotype instanceof ConstraintProperty)) {
                  createAssociatedStereotype(element, "SysML::Constraints",
                      "ConstraintProperty");
                  break;
                }
              }
            }
          } else if (typeStereotype instanceof Block) {
            for (EObject elementStereotype : elementStereotypes) {
              if (elementStereotype instanceof ConstraintProperty) {
                deleteAssociatedStereotype(element, "SysML::Constraints::ConstraintProperty");
                break;
              }
            }
          }
        }
      }
    }
    return element;
  }

  /**
   * Delete the requirement and his stereotype.
   *
   * @param e
   *            the Requirement to delete.
   */
  public void deleteRequirement(NamedElement e) {
    deleteAssociatedStereotype(e, SYSML_REQUIREMENT);
    final EObject root = getRootContainer(e);
    for (final Iterator<EObject> iterator = root.eAllContents(); iterator.hasNext();) {
      final EObject object = iterator.next();
      if (object instanceof Abstraction) {
        final Element supplier = ((Abstraction)object).getSupplier(e.getName());
        if (supplier != null) {
          Stereotype s = ((Abstraction)object).getAppliedStereotype("SysML::Requirements::Satisfy");
          if (s != null) {
            deleteAssociatedStereotype((Abstraction)object, "SysML::Requirements::Satisfy");
          } else {
            s = ((Abstraction)object).getAppliedStereotype("SysML::Requirements::DeriveReqt");
            if (s != null) {
              deleteAssociatedStereotype((Abstraction)object, "SysML::Requirements::DeriveReqt");
            } else {
              s = ((Abstraction)object).getAppliedStereotype("Standard::Refine");
              if (s != null) {
                deleteAssociatedStereotype((Abstraction)object, "Standard::Refine");
              } else {
                s = ((Abstraction)object).getAppliedStereotype("SysML::Requirements::Verify");
                if (s != null) {
                  deleteAssociatedStereotype((Abstraction)object,
                      "SysML::Requirements::Verify");
                }
              }
            }
          }
          EcoreUtil.delete(object);
        }
      }
    }
    EcoreUtil.delete(e);
  }

  /**
   * Get all the valid elements for a requirement diagram.
   *
   * @param cur
   *            Current semantic element
   * @return List of elements visible on a requirement diagram
   */
  public List<EObject> getValidsForRequirementDiagram(Element cur, DDiagram diagram) {

    final boolean isVerifyLayerActive = isVerifyLayerActive(diagram);
    final boolean isSatisfyLayerActive = isSatisfyLayerActive(diagram);
    final boolean isRefineLayerActive = isRefineLayerActive(diagram);

    Predicate<EObject> validForClassDiagram = new Predicate<EObject>() {

      public boolean apply(EObject input) {
        return input instanceof Package
            || ("Class".equals(input.eClass().getName()) && ((Class)input)
                .getAppliedStereotype(SYSML_REQUIREMENT) != null)
            || (isVerifyLayerActive && ((input instanceof Class && isTestClass((Class)input)) || (input instanceof Operation && ((Operation)input)
                .getAppliedStereotype(SYSML_TESTCASE) != null)))
            || (isSatisfyLayerActive && ((input instanceof Class && ((Class)input)
                .getAppliedStereotype(SYSML_BLOCK) != null)))
            || (isRefineLayerActive && (input instanceof Behavior || input instanceof BehavioredClassifier));
      }

      private boolean isTestClass(Class input) {
        for (Operation operation : input.getAllOperations()) {
          if (operation.getAppliedStereotype(SYSML_TESTCASE) != null)
            return true;
        }
        return false;
      }
    };
    return allValidSessionElements(cur, validForClassDiagram);
  }

  private boolean isVerifyLayerActive(DDiagram diagram) {
    return isLayerActive(diagram, "Verify");
  }

  private boolean isSatisfyLayerActive(DDiagram diagram) {
    return isLayerActive(diagram, "Satisfy");
  }

  private boolean isRefineLayerActive(DDiagram diagram) {
    return isLayerActive(diagram, "Refine");
  }

  private boolean isLayerActive(DDiagram diagram, String layerName) {
    for (Layer layer : diagram.getActivatedLayers()) {
      if (layerName.equals(layer.getName()))
        return true;
    }
    return false;
  }

  /**
   * Get all the valid elements for a block definition diagram.
   *
   * @param cur
   *            Current semantic element
   * @return List of elements visible on a block definition diagram
   */
  public List<EObject> getValidsForBlockDefinitionDiagram(EObject cur) {
    Predicate<EObject> validForDiagram = new Predicate<EObject>() {

      public boolean apply(EObject input) {

        return "Model".equals(input.eClass().getName())
            || "Package".equals(input.eClass().getName())
            || input instanceof Interface
            || (input instanceof InstanceSpecification && hasStereotype(
                (InstanceSpecification)input, "Unit"))
            || (input instanceof InstanceSpecification && hasStereotype(
                (InstanceSpecification)input, "Dimension")) || input instanceof DataType
            || input instanceof Actor
            || (input instanceof Class && hasStereotype((Class)input, "Block"))
            || (input instanceof Class && hasStereotype((Class)input, "ConstraintBlock"));
      }
    };
    return allValidSessionElements(cur, validForDiagram);
  }

  /**
   * Get all the valid elements for an internal block diagram.
   *
   * @param cur
   *            Current semantic element
   * @return List of elements visible on an internal block diagram
   */
  public List<EObject> getValidsForInternalBlockDiagram(Class cur) {
    Predicate<EObject> validForDiagram = new Predicate<EObject>() {

      public boolean apply(EObject input) {
        return (!(input instanceof Port) && (input instanceof Property));
      }
    };
    return allValidAttributes(cur, validForDiagram);
  }

  /**
   * Get all the valid elements for an internal block diagram.
   *
   * @param cur
   *            Current semantic element
   * @return List of elements visible on an internal block diagram
   */
  public List<EObject> getValidsForParametricBlockDiagram(Class cur) {
    final boolean isValueBindingLayerActive = isValueBindingLayerActive(cur);
    Predicate<EObject> validForDiagram = new Predicate<EObject>() {

      public boolean apply(EObject input) {
        if (!isValueBindingLayerActive) {
          return !(input instanceof Port) && (input instanceof Property)
              && hasStereotype((Element)input, "ConstraintProperty");
        } else {
          return !(input instanceof Port) && (input instanceof Property);
        }
      }
    };
    return allValidAttributes(cur, validForDiagram);
  }

  private boolean isValueBindingLayerActive(EObject cur) {
    IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
        .getActiveEditor();

    if (editor instanceof DialectEditor) {
      DialectEditor dialectEditor = (DialectEditor)editor;
      DRepresentation representation = dialectEditor.getRepresentation();
      if (representation instanceof DDiagram) {
        DDiagram diagram = (DDiagram)representation;
        List<Layer> layers = diagram.getActivatedLayers();
        for (Layer layer : layers) {
          if ("PAR ValueBinding Layer".equals(layer.getName()))
            return true;
        }
      }
    }
    return false;
  }

  /**
   * Get all the valid elements for an internal block diagram.
   *
   * @param cur
   *            Current semantic element
   * @return List of elements visible on an internal block diagram
   */
  public List<EObject> getValidsForParametricBlockDiagramValueBindingFilter(Class cur) {
    Predicate<EObject> validForDiagram = new Predicate<EObject>() {

      public boolean apply(EObject input) {
        return !(input instanceof Port) && (input instanceof Property)
            && !hasStereotype((Element)input, "ConstraintProperty");
      }
    };
    return allValidAttributes(cur, validForDiagram);
  }

  /**
   * Check if an UML element has a stereotype defined as parameter.
   *
   * @param element
   *            UML element
   * @param stereotype
   *            Stereotype name to check
   * @return True if the UML element has the given stereotype
   */
  private boolean hasStereotype(Element element, String stereotypeName) {
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotypeName.equals(stereotype.eClass().getName()))
        return true;
    }
    return false;
  }

  /**
   * Get all valid elements in session.
   *
   * @param cur
   *            Current element
   * @param validForDiagram
   *            Predicate
   * @return List of valid elements
   */
  private List<EObject> allValidSessionElements(EObject cur, Predicate<EObject> validForDiagram) {
    Session found = SessionManager.INSTANCE.getSession(cur);
    List<EObject> result = Lists.newArrayList();
    if (found != null) {
      for (Resource res : found.getSemanticResources()) {
        Iterators.addAll(result, Iterators.filter(res.getAllContents(), validForDiagram));
      }
    }
    return result;
  }

  /**
   * Get all valid attributes of a class.
   *
   * @param cur
   *            Current element
   * @param validForDiagram
   *            Predicate
   * @return List of valid elements
   */
  private List<EObject> allValidAttributes(Class cur, Predicate<EObject> validForDiagram) {
    List<EObject> result = Lists.newArrayList();
    Iterators.addAll(result, Iterators.filter(cur.getAttributes().iterator(), validForDiagram));
    return result;
  }

  /**
   * Generic service used to process treatments on a reconnect The processing has to be defined by
   * overriding the corresponding caseXXX.
   *
   * @param context
   *            Element attached to the existing edge
   * @param edgeView
   *            Represents the graphical new edge
   * @param sourceView
   *            Represents the graphical element pointed by the edge before reconnecting
   * @param targetView
   *            Represents the graphical element pointed by the edge after reconnecting
   * @param source
   *            Represents the semantic element pointed by the edge before reconnecting
   * @param target
   *            Represents the semantic element pointed by the edge after reconnecting
   * @return the Element attached to the edge once it has been modified
   */
  public Element reconnectRequirement(Element context, DEdge edgeView, EdgeTarget sourceView,
      EdgeTarget targetView, Class source, Class target) {
    final SysMLReconnectSwitch reconnectService = new SysMLReconnectSwitch();

    // The edgeview represents the new graphical edge
    // with testing of its source and target nodes we can
    // know if the user reconnected the source or the target of the edge
    reconnectService.setReconnectingSource(edgeView.getSourceNode().equals(targetView));
    Class requirement = (Class)((DNodeList)edgeView.getTargetNode()).getTarget();

    reconnectService.setSubRequirement(requirement);
    reconnectService.setOldPointedClass(source);
    reconnectService.setNewPointedClass(target);
    return reconnectService.doSwitch(context);
  }

  /**
   * Set dimension.
   *
   * @param dataType
   *            Datatype
   * @param instanceSpecification
   *            Dimension
   */
  public void setDimension(Element dataType, InstanceSpecification instanceSpecification) {
    if (dataType.getStereotypeApplications() != null) {
      EObject stereotype = dataType.getStereotypeApplications().get(0);
      if (stereotype instanceof ValueType) {
        ValueType valueType = (ValueType)stereotype;
        if (instanceSpecification.getStereotypeApplications() != null) {
          stereotype = instanceSpecification.getStereotypeApplications().get(0);
          if (stereotype instanceof Dimension) {
            Dimension dimension = (Dimension)stereotype;
            valueType.setDimension(dimension);
          }
        }
      }
    }
  }

  /**
   * Set unit.
   *
   * @param dataType
   *            Datatype
   * @param instanceSpecification
   *            unit
   */
  public void setUnit(Element dataType, InstanceSpecification instanceSpecification) {
    if (dataType.getStereotypeApplications() != null) {
      EObject stereotype = dataType.getStereotypeApplications().get(0);
      if (stereotype instanceof ValueType) {
        ValueType valueType = (ValueType)stereotype;
        if (instanceSpecification.getStereotypeApplications() != null) {
          stereotype = instanceSpecification.getStereotypeApplications().get(0);
          if (stereotype instanceof Unit) {
            Unit unit = (Unit)stereotype;
            valueType.setUnit(unit);
          }
        }
      }
    }
  }

  /**
   * Checks if an element is a valid root of a block definition diagram.
   *
   * @param element
   *            Named element
   * @return True if element could be a root of a block definition diagram otherwise false
   */
  public boolean isValidBlockDefinitionDiagramRoot(NamedElement element) {
    // Replace the acceleo expression : [self.oclIsKindOf(uml::Package) or
    // self->filter(uml::Class).getStereotypeApplications()->filter(sysml::blocks::Block)->size() > 0/]
    if (element instanceof Package) {
      return true;
    } else if (element instanceof Class) {
      return isBlock((Class)element);
    }
    return false;
  }

  /**
   * Checks if an element is a valid root of an internal block diagram.
   *
   * @param element
   *            Named element
   * @return True if element could be a root of an internal block diagram otherwise false
   */
  public boolean isValidInternalBlockDiagramRoot(Class element) {
    // Replace the acceleo expression : [getStereotypeApplications()->filter(sysml::blocks::Block)->size()
    // > 0/]
    return isBlock(element);
  }

  /**
   * Checks if an element is a valid root of a parametric diagram.
   *
   * @param element
   *            Named element
   * @return True if element could be a root of a parametric diagram otherwise false
   */
  public boolean isValidParametricDiagramRoot(Class element) {
    // Replace the acceleo expression : [getStereotypeApplications()->filter(sysml::blocks::Block)->size()
    // > 0/]
    return isBlock(element);
  }

  /**
   * Checks if element has the stereotype block.
   *
   * @param element
   *            Named element
   * @return True if element is a block otherwise false
   */
  public boolean isBlock(Element element) {
    return isStereotype(element, Block.class);
  }

  /**
   * Get all non constraint blocks.
   *
   * @param container
   *            Container
   * @return All blocks.
   */
  public List<Class> getAllNonConstraintBlocks(EObject container) {
    SysMLServices service = new SysMLServices();
    // Replace expression :
    // [container.getRootContainer().eAllContents(uml::Package)->union(container.getRootContainer().eAllContents(uml::Class)->select(isBlock()))/]
    List<Class> blocks = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Class && (isBlock((Class)element) && !isConstraintBlock((Class)element))) {
        blocks.add(((Class)element));
      }
    }
    return blocks;
  }

  /**
   * Get all non constraint blocks.
   *
   * @param container
   *            Container
   * @return All blocks.
   */
  public List<Class> getAllConstraintBlocks(EObject container) {
    SysMLServices service = new SysMLServices();
    // Replace expression :
    // [container.getRootContainer().eAllContents(uml::Package)->union(container.getRootContainer().eAllContents(uml::Class)->select(isBlock()))/]
    List<Class> blocks = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Class && isConstraintBlock((Class)element)) {
        blocks.add(((Class)element));
      }
    }
    return blocks;
  }

  /**
   * Checks if element has the stereotype constraint block.
   *
   * @param element
   *            Named element
   * @return True if element is a constraint block otherwise false
   */
  public boolean isConstraintBlock(Classifier element) {
    return isStereotype(element, ConstraintBlock.class);
  }

  /**
   * Checks if element has the stereotype requirement.
   *
   * @param element
   *            Named element
   * @return True if element is a requirement otherwise false
   */
  public boolean isRequirement(Element element) {
    return isStereotype(element, Requirement.class);
  }

  public boolean isNotBlockOrRequirement(Element element) {
    return element instanceof Class && !isBlock((Class)element) && !isRequirement((Class)element)
        && !(element instanceof Activity) && !(element instanceof StateMachine);
  }

  /**
   * Get requirement.
   *
   * @param element
   *            Named element
   * @return True if element is a requirement otherwise false
   */
  public Requirement getRequirement(Class element) {
    // Replace acceleo expression :
    // [getStereotypeApplications()->filter(sysml::requirements::Requirement)->size() > 0/]
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotype instanceof Requirement) {
        return (Requirement)stereotype;
      }
    }
    return null;
  }

  /**
   * Get requirement id.
   *
   * @param element
   *            Requirement
   * @return Id
   */
  public String getRequirementId(Class element) {
    Requirement requirement = getRequirement(element);
    return requirement.getId();
  }

  /**
   * Get requirement text.
   *
   * @param element
   *            Requirement
   * @return Text
   */
  public String getRequirementText(Class element) {
    Requirement requirement = getRequirement(element);
    return requirement.getText();
  }

  /**
   * Set requirement id.
   *
   * @param element
   *            Requirement
   * @param newId
   *            Id
   */
  public void setRequirementId(Class element, String newId) {
    Requirement requirement = getRequirement(element);
    requirement.setId(newId);
  }

  /**
   * Set requirement text.
   *
   * @param element
   *            Requirement
   * @param newText
   *            Text
   */
  public void setRequirementText(Class element, String newText) {
    Requirement requirement = getRequirement(element);
    requirement.setText(newText);
  }

  /**
   * Checks if element has the stereotype value type.
   *
   * @param element
   *            Named element
   * @return True if element is a value type otherwise false
   */
  public boolean isValueType(NamedElement element) {
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotype instanceof ValueType) {
        return true;
      }
    }
    return false;
  }

  /**
   * Get value type.
   *
   * @param element
   *            Element
   * @return Value type
   */
  public EObject getValueType(Element element) {
    // Replace acceleo expression :
    // getStereotypeApplications()->filter(sysml::blocks::ValueType)->select(not(base_DataType->filter(uml::PrimitiveType)->isEmpty()))
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotype instanceof ValueType) {
        return stereotype;
      }
    }
    return null;
  }

  /**
   * Checks if element has the stereotype dimension.
   *
   * @param element
   *            Named element
   * @return True if element is a dimension otherwise false
   */
  public boolean isDimension(InstanceSpecification element) {
    return isStereotype(element, Dimension.class);
  }

  /**
   * Checks if element has the stereotype unit.
   *
   * @param element
   *            Named element
   * @return True if element is a unit otherwise false
   */
  public boolean isUnit(InstanceSpecification element) {
    // Replace acceleo expression:
    // [self.getStereotypeApplications()->filter(sysml::blocks::Unit)->size() > 0/]
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotype instanceof Unit) {
        return true;
      }
    }
    return false;
  }

  /**
   * Checks if element is a valid property.
   *
   * @param element
   *            Named element
   * @return True if element is a valid property otherwise false
   */
  public boolean isValidProperty(Property element, DSemanticDiagram diagram) {
    // Replace acceleo expression: [if diagram.isLayerActivated('BDD Parametric Layer') = false then
    // getStereotypeApplications()->filter(sysml::constraints::ConstraintProperty)->size() = 0 and
    // not(oclIsKindOf(uml::Port)) else not(oclIsKindOf(uml::Port)) endif/]
    SysMLServices service = new SysMLServices();

    if (!service.isLayerActivated(diagram, "BDD Parametric Layer")) {
      if (element.getStereotypeApplications().size() == 0 && !(element instanceof Port)) {
        return true;
      }
      for (EObject stereotype : element.getStereotypeApplications()) {
        if (!(stereotype instanceof ConstraintProperty) && !(element instanceof Port)) {
          return true;
        }
      }
    } else {
      if (!(element instanceof Port)) {
        return true;
      }
    }

    return false;
  }

  /**
   * Get requirements defined in a package.
   *
   * @param pkg
   *            Package
   * @return Requirements
   */
  public List<Object> getRequirements(Package pkg) {
    return getRequirements(pkg.getPackagedElements().toArray());
  }

  /**
   * Get requirement defined under a requirement.
   *
   * @param class_
   *            Requirement
   * @return Sub requirements
   */
  public List<Object> getRequirements(Classifier class_) {
    return getRequirements(class_.eContents().toArray());
  }

  /**
   * Get requirements.
   *
   * @param elements
   *            Possible requirements
   * @return Requirements
   */
  private List<Object> getRequirements(Object[] elements) {
    // Replace acceleo expression:
    // self->union(self.getStereotypeApplications()->filter(sysml::requirements::Requirement))
    List<Object> requirements = Lists.newArrayList();
    for (Object element : elements) {
      if (element instanceof Class && isRequirement((Class)element)) {
        requirements.add(element);
      }
    }
    return requirements;
  }

  /**
   * Checks if element has the stereotype flow port.
   *
   * @param element
   *            Named element
   * @return True if element is a flow port otherwise false
   */
  public boolean isFlowPort(Element element) {
    return isStereotype(element, FlowPort.class);
  }

  /**
   * Checks if element has the stereotype port.
   *
   * @param element
   *            Named element
   * @return True if element is a port otherwise false
   */
  public boolean isPort(NamedElement element) {
    return element instanceof Port && !isFlowPort(element);
  }

  /**
   * Check if element has the SysML stereotype given in parameters.
   *
   * @param element
   *            Element to check
   * @param sysmlStereotype
   *            stereotype
   * @return True if the elements has the stereotype otherwise false
   */
  @SuppressWarnings("rawtypes")
  private boolean isStereotype(Element element, java.lang.Class sysmlStereotype) {
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (sysmlStereotype.isInstance(stereotype)) {
        return true;
      }
    }
    return false;
  }

  /**
   * Get the flow port.
   *
   * @param element
   *            Named element
   * @return Flow port
   */
  public FlowPort getFlowPort(NamedElement element) {
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotype instanceof FlowPort) {
        return (FlowPort)stereotype;
      }
    }
    return null;
  }

  public boolean isOutFlowPort(NamedElement element) {
    FlowPort port = getFlowPort(element);
    return port.getDirection().equals(FlowDirection.OUT);
  }

  public boolean isInFlowPort(NamedElement element) {
    FlowPort port = getFlowPort(element);
    return port.getDirection().equals(FlowDirection.IN);
  }

  /**
   * Checks if element has the stereotype constraint property.
   *
   * @param element
   *            Named element
   * @return True if element is a constraint property otherwise false
   */
  public boolean isConstraintProperty(NamedElement element) {
    return isStereotype(element, ConstraintProperty.class);
  }

  /**
   * Checks if element has the stereotype test case.
   *
   * @param element
   *            Named element
   * @return True if element is a test case otherwise false
   */
  public boolean isTestCase(NamedElement element) {
    for (EObject stereotype : element.getStereotypeApplications()) {
      if (stereotype instanceof TestCase) {
        return true;
      }
    }
    return false;
  }

  /**
   * Checks if element has the stereotype derive requirement.
   *
   * @param element
   *            Named element
   * @return True if element is a derive requirement otherwise false
   */
  public boolean isDeriveReqt(NamedElement element) {
    return isStereotype(element, DeriveReqt.class);
  }

  /**
   * Checks if element has the stereotype refine.
   *
   * @param element
   *            Named element
   * @return True if element is a refine otherwise false
   */
  public boolean isRefine(NamedElement element) {
    return isStereotype(element, Refine.class);
  }

  /**
   * Checks if element has the stereotype satisfy.
   *
   * @param element
   *            Named element
   * @return True if element is a satisfy otherwise false
   */
  public boolean isSatisfy(NamedElement element) {
    return isStereotype(element, Satisfy.class);
  }

  /**
   * Checks if element has the stereotype verify.
   *
   * @param element
   *            Named element
   * @return True if element is a verify otherwise false
   */
  public boolean isVerify(NamedElement element) {
    return isStereotype(element, Verify.class);
  }

  /**
   * Get all blocks.
   *
   * @param container
   *            Container
   * @return All blocks.
   */
  public List<Class> getAllBlocks(Element container) {
    SysMLServices service = new SysMLServices();
    // Replace expression :
    // [container.getRootContainer().eAllContents(uml::Package)->union(container.getRootContainer().eAllContents(uml::Class)->select(isBlock()))/]
    List<Class> blocks = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Class && isBlock((Class)element)) {
        blocks.add(((Class)element));
      }
    }
    return blocks;
  }

  /**
   * Get all actors.
   *
   * @param element
   *            element
   * @return All actors.
   */
  public List<Element> getAllActorsAndContainers(Element element) {
    List<Element> results = Lists.newArrayList();
    UMLServices service = new UMLServices();

    List<Package> models = service.getAllAvailableRootPackages(element);
    results.addAll(models);
    for (Package pkg : models) {
      for (Iterator<EObject> iterator = pkg.eAllContents(); iterator.hasNext();) {
        EObject iter = iterator.next();
        if (iter instanceof Actor || iter instanceof Package) {
          results.add((Element)iter);
        }
      }
    }

    return results;
  }

  /**
   * Get all value types.
   *
   * @param container
   *            Container
   * @return All value types.
   */
  public List<ValueType> getAllValueTypes(EObject container) {
    List<ValueType> valuetypes = Lists.newArrayList();
    for (Iterator<EObject> iterator = getRootContainer(container).eAllContents(); iterator.hasNext();) {
      EObject element = iterator.next();
      if (element instanceof ValueType && isValueType((NamedElement)element)) {
        valuetypes.add(((ValueType)element));
      }
    }
    return valuetypes;
  }

  /**
   * Get all test cases.
   *
   * @param container
   *            Container
   * @return All test cases.
   */
  public List<Operation> getAllTestCases(Element container) {
    List<Operation> testcases = Lists.newArrayList();
    for (Iterator<EObject> iterator = getRootContainer(container).eAllContents(); iterator.hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Operation && isTestCase((Operation)element)) {
        testcases.add(((Operation)element));
      }
    }
    return testcases;
  }

  /**
   * Get all behaviors.
   *
   * @param container
   *            Container
   * @return All behaviors.
   */
  public List<Element> getAllBehaviors(Element container) {
    List<Element> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = getRootContainer(container).eAllContents(); iterator.hasNext();) {
      EObject element = iterator.next();
      if (element instanceof StateMachine || element instanceof Activity || element instanceof UseCase
          || element instanceof Collaboration) {
        results.add((Element)element);
      }
    }
    return results;
  }

  /**
   * Get all dimensions.
   *
   * @param container
   *            Package
   * @return All dimensions.
   */
  public List<InstanceSpecification> getAllDimensions(Element valueType) {
    List<InstanceSpecification> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = valueType.getModel().eAllContents(); iterator.hasNext();) {
      EObject element = iterator.next();
      if (element instanceof InstanceSpecification && isDimension((InstanceSpecification)element)) {
        results.add(((InstanceSpecification)element));
      }
    }
    return results;
  }

  /**
   * Get dimension.
   *
   * @param container
   *            Package
   * @return Dimension.
   */
  public Dimension getDimension(Element valueType) {
    for (EObject stereotype : valueType.getStereotypeApplications()) {
      if (stereotype instanceof ValueType) {
        return ((ValueType)stereotype).getDimension();
      }
    }
    return null;
  }

  /**
   * Get dimension name.
   *
   * @param dimension
   *            Dimension
   * @return Name
   */
  public String getName(Dimension dimension) {
    return dimension.getBase_InstanceSpecification().getName();
  }

  /**
   * Get unit.
   *
   * @param container
   *            Package
   * @return Unit.
   */
  public Unit getUnit(Element valueType) {
    for (EObject stereotype : valueType.getStereotypeApplications()) {
      if (stereotype instanceof ValueType) {
        return ((ValueType)stereotype).getUnit();
      }
    }
    return null;
  }

  /**
   * Get unit name.
   *
   * @param unit
   *            Unit
   * @return Name
   */
  public String getName(Unit unit) {
    return unit.getBase_InstanceSpecification().getName();
  }

  /**
   * Get all units.
   *
   * @param container
   *            Package
   * @return All units.
   */
  public List<InstanceSpecification> getAllUnits(Element valueType) {
    List<InstanceSpecification> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = valueType.getModel().eAllContents(); iterator.hasNext();) {
      EObject element = iterator.next();
      if (element instanceof InstanceSpecification && isUnit((InstanceSpecification)element)) {
        results.add(((InstanceSpecification)element));
      }
    }
    return results;
  }

  /**
   * Get all derive requirements.
   *
   * @param container
   *            Package
   * @return All derive requirements.
   */
  public List<NamedElement> getAllDeriveReqts(Package container) {
    SysMLServices service = new SysMLServices();
    List<NamedElement> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Abstraction && isDeriveReqt((NamedElement)element)) {
        results.add(((NamedElement)element));
      }
    }
    return results;
  }

  /**
   * Get all refine requirements.
   *
   * @param container
   *            Package
   * @return All refine requirements.
   */
  public List<NamedElement> getAllRefine(Package container) {
    SysMLServices service = new SysMLServices();
    List<NamedElement> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Abstraction && isRefine((NamedElement)element)) {
        results.add(((NamedElement)element));
      }
    }
    return results;
  }

  /**
   * Get all satisfy requirements.
   *
   * @param container
   *            Package
   * @return All satisfy requirements.
   */
  public List<NamedElement> getAllSatisfyReqts(Package container) {
    SysMLServices service = new SysMLServices();
    List<NamedElement> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Abstraction && isSatisfy((NamedElement)element)) {
        results.add(((NamedElement)element));
      }
    }
    return results;
  }

  /**
   * Get all verify requirements.
   *
   * @param container
   *            Package
   * @return All verify requirements.
   */
  public List<NamedElement> getAllVerifyReqts(Package container) {
    SysMLServices service = new SysMLServices();
    List<NamedElement> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Abstraction && isVerify((NamedElement)element)) {
        results.add(((NamedElement)element));
      }
    }
    return results;
  }

  /**
   * Get port types.
   *
   * @param container
   *            Container
   * @return Port types
   */
  public List<Classifier> q(EObject container) {
    SysMLServices service = new SysMLServices();
    List<Classifier> results = Lists.newArrayList();
    for (Iterator<EObject> iterator = service.getRootContainer(container).eAllContents(); iterator
        .hasNext();) {
      EObject element = iterator.next();
      if (element instanceof Classifier
          && !isConstraintBlock((Classifier)element)
          && (isBlock((Classifier)element) || element instanceof PrimitiveType
              || element instanceof DataType || element instanceof Interface)) {
        results.add(((Classifier)element));
      }
    }
    return results;
  }

  public void unsetDimension(EObject valueType) {
    ((ValueType)((Element)valueType).getStereotypeApplications()).setDimension(null);
  }

  public List<EObject> getValidsForSysmlDiagram(final Element element,
      final DSemanticDecorator containerView) {
    // Get representation
    DRepresentation representation = null;
    if (containerView instanceof DRepresentation) {
      representation = (DRepresentation)containerView;
    } else if (containerView instanceof DDiagramElement) {
      representation = ((DDiagramElement)containerView).getParentDiagram();
    }
    List<EObject> results = null;
    if (representation instanceof DSemanticDiagramSpec) {
      DiagramDescription description = ((DSemanticDiagramSpec)representation).getDescription();

      if ("Block Definition Diagram".equals(description.getName())) {
        results = getValidsForBlockDefinitionDiagram(element);
      } else if ("Internal Block Diagram".equals(description.getName())) {
        results = getValidsForInternalBlockDiagram((Class)element);
      } else if ("Parametric Diagram".equals(description.getName())) {
        results = getValidsForParametricBlockDiagram((Class)element);
      } else if ("Requirement Diagram".equals(description.getName())) {
        results = getValidsForRequirementDiagram(element, (DDiagram)representation);
      }
    }

    return results;
  }

  public boolean isValidAttributesContainer(EObject container, EObject containerView) {
    // [container.oclAsType(ecore::EObject).existValidElementsForContainerView(containerView.oclAsType(ecore::EObject))/]
    UIServices service = new UIServices();
    return service.existValidElementsForContainerView(container, containerView)
        && !(containerView instanceof DDiagram);
  }

  /**
   * Get satisfied requirements.
   *
   * @param element
   *            Block
   * @return Requirements satisfied by the given block
   */
  public List<Class> getSatisfiedRequirements(Class element) {
    List<Class> results = Lists.newArrayList();
    Collection<Setting> xRefs = SessionManager.INSTANCE.getSession(element).getSemanticCrossReferencer()
        .getInverseReferences(element);
    for (Setting xRef : xRefs) {
      EObject eObject = xRef.getEObject();
      if (eObject instanceof Abstraction) {
        for (Element supplier : ((Abstraction)eObject).getSuppliers()) {
          if (supplier instanceof Class) {
            for (EObject stereotype : supplier.getStereotypeApplications()) {
              if (stereotype instanceof Requirement) {
                results.add((Class)supplier);
              }
            }
          }
        }
      }
    }
    return results;
  }

  /**
   * Get the parent view of an element. This method is used by the add related elements function to retrieve
   * the parent view.
   *
   * @param element
   *            element
   * @return Parent view
   */
  public DNodeContainer getParentView(Element element) {
    Session session = SessionManager.INSTANCE.getSession(element);
    Collection<Setting> refs = session.getSemanticCrossReferencer().getInverseReferences(
        element.eContainer());
    for (Setting setting : refs) {
      if (setting.getEObject() instanceof DNodeContainer) {
        return (DNodeContainer)setting.getEObject();
      }
    }
    return null;
  }
}
TOP

Related Classes of org.obeonetwork.dsl.sysml.design.services.SysMLServices

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.