ComponentValidator.java :  » UML » model-analysis-framework » de » uniAugsburg » MAF » dfa » jwt » analysis » token » macros » validation » Java Open Source

Java Open Source » UML » model analysis framework 
model analysis framework » de » uniAugsburg » MAF » dfa » jwt » analysis » token » macros » validation » ComponentValidator.java
package de.uniAugsburg.MAF.dfa.jwt.analysis.token.macros.validation;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;

import de.uniAugsburg.MAF.core.util.model.EMFDynamicUtils;
import de.uniAugsburg.MAF.dfa.jwt.metamodel.JWTConstants;
import de.uniAugsburg.MAF.dfa.jwt.metamodel.tokenflow.Component;
import de.uniAugsburg.MAF.dfa.jwt.metamodel.tokenflow.componentType;
import de.uniAugsburg.MAF.dfa.jwt.metamodel.tokenflow.validationClassification;
import de.uniAugsburg.MAF.dfa.jwt.metamodel.tokenflow.validationResult;


public class ComponentValidator
{

  /**
   * Recursively validates a component according to IBM's fast heuristics
   * algorithm.
   */
  public void validateComponent(Component component)
  {
    // RECURSIVE: validate subcomponents and check their type
    boolean unsoundChild = false;
    boolean unknownChild = false;
    for (Component subComponent : component.getSubComponents())
    {
      // recursively validate subcomponent
      validateComponent(subComponent);

      // store child type info
      if (subComponent.getValidResult().equals(validationResult.UNSOUND))
        unsoundChild = true;
      else if (subComponent.getValidResult().equals(validationResult.UNKNOWN))
        unknownChild = true;
    }

    // classify component type
    classifyComponent(component);

    // determine result status of component
    // a) child overwrites local status
    if (unsoundChild)
      component.setValidResult(validationResult.UNSOUND);
    else if (unknownChild)
      component.setValidResult(validationResult.UNKNOWN);
    else
    {
      // b) set local status according to classification result
      if (component.getValidClassification().equals(
          validationClassification.COMPLEXUNSOUNDDEADLOCK)
          || component.getValidClassification().equals(
              validationClassification.COMPLEXUNSOUNDLACKOFSYNC))
        component.setValidResult(validationResult.UNSOUND);
      else if (component.getValidClassification().equals(
          validationClassification.COMPLEXUNKNOWN))
        component.setValidResult(validationResult.UNKNOWN);
      else
        component.setValidResult(validationResult.SOUND);
    }

    System.out.println(component.toString());
  }


  /**
   * Determines the type of a component.
   */
  public static void classifyComponent(Component component)
  {
    // get all child nodes
    Set<EObject> childNodes = new HashSet<EObject>(component.getTrivialNodes());
    childNodes.addAll(component.getSccInputPorts());
    childNodes.addAll(component.getSccOutputPorts());

    // collect information from child nodes
    Set<EObject> decisionNodes = new HashSet<EObject>();
    Set<EObject> mergeNodes = new HashSet<EObject>();
    Set<EObject> forkNodes = new HashSet<EObject>();
    Set<EObject> joinNodes = new HashSet<EObject>();
    for (EObject childNode : childNodes)
      if (childNode.eClass().getName().equals(JWTConstants.EC_DECISIONNODE))
        decisionNodes.add(childNode);
      else if (childNode.eClass().getName().equals(JWTConstants.EC_MERGENODE))
        mergeNodes.add(childNode);
      else if (childNode.eClass().getName().equals(JWTConstants.EC_JOINNODE))
        joinNodes.add(childNode);
      else if (childNode.eClass().getName().equals(JWTConstants.EC_FORKNODE))
        forkNodes.add(childNode);

    // contains cycle
    boolean containsSCC = false;
    for (Component subComponent : component.getSubComponents())
      if (componentType.SCC.equals(subComponent.getType()))
      {
        containsSCC = true;
        break;
      }

    // input/output node information
    EObject inEdge = component.getInputEdges().get(0);
    EObject outEdge = component.getOutputEdges().get(0);
    boolean entryIsIncomingOfDecision = decisionNodes.size() == 1
        && EMFDynamicUtils.getEReferenceValues(decisionNodes.iterator().next(), "in")
            .contains(inEdge);
    boolean exitIsOutgoingOfMerge = mergeNodes.size() == 1
        && EMFDynamicUtils.getEReferenceValues(mergeNodes.iterator().next(), "out")
            .contains(outEdge);
    boolean entryIsIncomingOfMerge = mergeNodes.size() == 1
        && EMFDynamicUtils.getEReferenceValues(mergeNodes.iterator().next(), "in")
            .contains(inEdge);
    boolean exitIsOutgoingOfDecision = decisionNodes.size() == 1
        && EMFDynamicUtils.getEReferenceValues(decisionNodes.iterator().next(), "out")
            .contains(outEdge);
    boolean entryIsIncomingOfFork = forkNodes.size() == 1
        && EMFDynamicUtils.getEReferenceValues(forkNodes.iterator().next(), "in").contains(
            inEdge);
    boolean exitIsOutgoingOfJoin = joinNodes.size() == 1
        && EMFDynamicUtils.getEReferenceValues(joinNodes.iterator().next(), "out")
            .contains(outEdge);

    // apply heuristics

    // well-structured
    if (decisionNodes.size() == 0 && mergeNodes.size() == 0 && forkNodes.size() == 0
        && joinNodes.size() == 0)
      component.setValidClassification(validationClassification.WELLSTRUCTUREDSEQUENCE);
    else if (decisionNodes.size() == 1 && mergeNodes.size() == 1 && forkNodes.size() == 0
        && joinNodes.size() == 0 && entryIsIncomingOfDecision && exitIsOutgoingOfMerge)
      component
          .setValidClassification(validationClassification.WELLSTRUCTUREDSEQUENTIALBRANCHING);
    else if (decisionNodes.size() == 1 && mergeNodes.size() == 1 && forkNodes.size() == 0
        && joinNodes.size() == 0 && entryIsIncomingOfMerge && exitIsOutgoingOfDecision)
      component.setValidClassification(validationClassification.WELLSTRUCTUREDCYCLE);
    else if (decisionNodes.size() == 0 && mergeNodes.size() == 0 && forkNodes.size() == 1
        && joinNodes.size() == 1 && entryIsIncomingOfFork && exitIsOutgoingOfJoin)
      component
          .setValidClassification(validationClassification.WELLSTRUCTUREDCONCURRENTBRANCHING);
    else
    {
      // not well-structured
      if (decisionNodes.size() == 0 && mergeNodes.size() == 0 && !containsSCC)
        component.setValidClassification(validationClassification.UNSTRUCTUREDCONCURRENT);
      else if (forkNodes.size() == 0 && joinNodes.size() == 0)
        component.setValidClassification(validationClassification.UNSTRUCTUREDSEQUENTIAL);
      else
      {
        // complex
        // at least one decision, but no merges
        boolean case1a = !containsSCC && decisionNodes.size() > 0 && mergeNodes.size() == 0;
        // at least one merge, but no decisions
        boolean case1b = !containsSCC && mergeNodes.size() > 0 && decisionNodes.size() == 0;
        // at least one fork, but no joins
        boolean case2a = !containsSCC && forkNodes.size() > 0 && joinNodes.size() == 0;
        // at least one join, but no forks
        boolean case2b = !containsSCC && joinNodes.size() > 0 && forkNodes.size() == 0;
        boolean case3a = containsSCC && decisionNodes.size() == 0 && mergeNodes.size() == 0;
        boolean case3b = containsSCC && decisionNodes.size() > 0 && mergeNodes.size() == 0;
        boolean case3c = containsSCC && decisionNodes.size() == 0 && mergeNodes.size() > 0;

        if (case1a || case2b || case3a || case3b)
          component
              .setValidClassification(validationClassification.COMPLEXUNSOUNDDEADLOCK);
        else if (case1b || case2a || case3c)
          component
              .setValidClassification(validationClassification.COMPLEXUNSOUNDLACKOFSYNC);
        else
          component.setValidClassification(validationClassification.COMPLEXUNKNOWN);
      }
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.