예제 #1
0
  public FDifference compareMethods(
      FDifference diff, MethodDescription leftMethod, MethodDescription rightMethod) {
    FDifference signDiff =
        basis.compareValues(
            "signature",
            leftMethod.getSignature().toString(),
            rightMethod.getSignature().toString(),
            leftMethod);
    FDifference descrDiff =
        basis.compareDescriptions(
            leftMethod.getName(),
            leftMethod.getSignature().getDescription(),
            rightMethod.getSignature().getDescription(),
            leftMethod);

    if (signDiff != null || descrDiff != null) {
      if (diff == null && signDiff != null) {
        diff = new FDifference(FDKind.ChangedElement, FDRating.Conflict);
      } else if (diff == null) {
        diff = new FDifference(FDKind.ChangedElement, FDRating.Info);
      }

      diff.addDifference(signDiff);
      diff.addDifference(descrDiff);
    }

    return diff;
  }
예제 #2
0
  protected FDifference compareStepIds(
      String context, INamedElement left, INamedElement right, FDObject source) {

    FDifference diff = null;

    if (left != null && right != null) {
      if (left.getName() != null & right.getName() != null) {
        if (left.getName().startsWith("id") && right.getName().startsWith("id")) {
          logger.debug(
              "ignoring diff between generated IDs for steps {} and {}",
              left.getName(),
              right.getName());
        } else if (!left.getName().equals(right.getName())) {
          logger.info("different step IDs: left={} <> right={}", left, right);
          diff = new FDifference(FDKind.ChangedElement, FDRating.Warning);
          diff.setSource(source);
          diff.setDescription(
              "The "
                  + context
                  + " has changed from '"
                  + left.getName()
                  + "' in version "
                  + this.getLeftVersion()
                  + " to '"
                  + right.getName()
                  + "' in version "
                  + this.getRightVersion());
          logger.debug("compare step IDs diff:\n{}", diff);
        }
      }
    } else {
      logger.warn("comparing named elements with NULL arguments. left={}, right={}", left, right);
    }

    return diff;
  }
예제 #3
0
  public FDifference compareTypeDescriptions(
      CodingUnit leftCodingUnit, CodingUnit rightCodingUnit, FDObject source) {

    FDifference diff = null;
    TypeDescription leftType = proxy.getTypeDescription(leftCodingUnit.getTypeAPIPath());
    TypeDescription rightType = proxy.getTypeDescription(rightCodingUnit.getTypeAPIPath());

    if (leftType != null && rightType != null) {
      FDifference nameDiff =
          basis.compareNamedElements("type descriptions", leftType, rightType, source);
      FDifference descDiff = basis.compareDescriptions(leftType, rightType, source);
      FDifference fqtnDiff =
          basis.compareValues("FQTN", leftType.getFqtn(), rightType.getFqtn(), source);
      FDifference methDiff = this.compareMethodDescriptions(leftType, rightType, source);
      FDifference packDiff = this.comparePackageDescriptions(leftType, rightType, source);

      if (nameDiff != null
          || descDiff != null
          || fqtnDiff != null
          || methDiff != null
          || packDiff != null) {
        diff = new FDifference(FDKind.ChangedElement, FDRating.Warning);
        diff.setSource(leftCodingUnit);
        diff.setDescription(
            "The type description of '"
                + leftCodingUnit.getName()
                + "' has changed in version "
                + this.getRightVersion());

        diff.addDifference(nameDiff);
        diff.addDifference(descDiff);
        diff.addDifference(fqtnDiff);
        diff.addDifference(methDiff);
        diff.addDifference(packDiff);
      }
    }

    return diff;
  }
예제 #4
0
  private FDifference compareMethodDescriptions(
      TypeDescription leftType, TypeDescription rightType, FDObject source) {
    FDifference diff = null;

    if (leftType.getMethods() != null) {
      if (rightType.getMethods() != null) {
        FDifference subDiff =
            compareMethodLists(leftType.getMethods(), rightType.getMethods(), leftType);
        if (subDiff != null) {
          if (diff == null) {
            diff = new FDifference(FDKind.ChangedElement, subDiff.getRating());
          }
          diff.addDifference(subDiff);
        }
      } else {
        // Deleted methods
        FDifference delDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
        delDiff.setSource(leftType);
        delDiff.setDescription(
            leftType.getMethods().size()
                + " were removed from type '"
                + leftType.getFqtn()
                + "' in version "
                + this.getRightVersion());
        if (diff == null) {
          diff = new FDifference(FDKind.ChangedElement, FDRating.Conflict);
        }
        diff.addDifference(delDiff);
      }
    } else if (rightType.getMethods() != null) {
      // New methods
      FDifference addDiff = new FDifference(FDKind.CreatedElement, FDRating.Warning);
      addDiff.setSource(rightType);
      addDiff.setDescription(
          "The type '"
              + rightType.getFqtn()
              + "' has "
              + rightType.getMethods().size()
              + " new methods in version "
              + this.getRightVersion());
      if (diff == null) {
        diff = new FDifference(FDKind.ChangedElement, FDRating.Conflict);
      }
      diff.addDifference(addDiff);
    }

    if (diff != null) {
      diff.setSource(leftType);
      diff.setDescription(
          "The type description of '"
              + leftType.getFqtn()
              + "' has changed in version "
              + this.getRightVersion());
    }
    return diff;
  }
예제 #5
0
  private FDifference comparePackageDescriptions(
      TypeDescription leftType, TypeDescription rightType, FDObject source) {

    FDifference nameDiff = null;
    FDifference descDiff = null;
    FDifference deleDiff = null;
    FDifference creaDiff = null;

    if (leftType.getPackage() != null) {
      if (rightType.getPackage() != null) {
        nameDiff =
            basis.compareNamedElements(
                "package description",
                leftType.getPackage(),
                rightType.getPackage(),
                leftType.getPackage());
        descDiff =
            basis.compareDescriptions(
                leftType.getPackage(), rightType.getPackage(), leftType.getPackage());
      } else {
        // Deleted package
        deleDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
        deleDiff.setSource(leftType.getPackage());
        deleDiff.setDescription(
            "The package '"
                + leftType.getPackage().getName()
                + "' of type '"
                + leftType.getFqtn()
                + "' was removed in version "
                + this.getRightVersion());
      }
    } else if (rightType.getPackage() != null) {
      // Created package
      creaDiff = new FDifference(FDKind.CreatedElement, FDRating.Conflict);
      creaDiff.setSource(rightType.getPackage());
      creaDiff.setDescription(
          "The package '"
              + rightType.getPackage().getName()
              + "' was added to the type '"
              + leftType.getFqtn()
              + "' in version "
              + this.getRightVersion());
    }

    FDifference diff = null;
    if (nameDiff != null || descDiff != null || deleDiff != null || creaDiff != null) {
      diff = new FDifference(FDKind.ChangedElement, FDRating.Conflict);
      diff.setSource(leftType.getPackage());
      diff.setDescription(
          "The package description has changed in version " + this.getRightVersion());
      diff.addDifference(nameDiff);
      diff.addDifference(descDiff);
      diff.addDifference(deleDiff);
      diff.addDifference(creaDiff);
    }
    return diff;
  }
예제 #6
0
  private FDifference compareMethodLists(
      List<MethodDescription> leftMethods, List<MethodDescription> rightMethods, FDObject source) {
    FDifference diff = null;

    for (MethodDescription leftMethod : leftMethods) {
      MethodDescription rightMethod =
          (MethodDescription) basis.getFromList(rightMethods, leftMethod);
      if (rightMethod != null) {
        diff = compareMethods(diff, leftMethod, rightMethod);
      } else {
        // Deleted method
        FDifference delDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
        delDiff.setSource(leftMethod);
        delDiff.setDescription(
            "The method with signature '"
                + leftMethod.getSignature().toString()
                + "' was removed in version "
                + this.getRightVersion());
        if (diff == null) {
          diff = new FDifference(FDKind.ChangedElement, FDRating.Conflict);
        }
        diff.addDifference(delDiff);
      }
    }

    for (MethodDescription rightMethod : rightMethods) {
      MethodDescription leftMethod =
          (MethodDescription) basis.getFromList(leftMethods, rightMethod);
      if (leftMethod == null) {
        // New method
        FDifference addDiff = new FDifference(FDKind.CreatedElement, FDRating.Warning);
        addDiff.setSource(rightMethod);
        addDiff.setDescription(
            "The method with signature '"
                + rightMethod.getSignature().toString()
                + "' was added in version "
                + this.getRightVersion());
        if (diff == null) {
          diff = new FDifference(FDKind.ChangedElement, FDRating.Conflict);
        }
        diff.addDifference(addDiff);
      }
    }

    if (diff != null) {
      diff.setSource(source);
      diff.setDescription("Method signatures have changed in version " + this.getRightVersion());
    }
    return diff;
  }
예제 #7
0
  public FDifference compareProcesses(Process leftProcess, Process rightProcess) {
    if (logger.isDebugEnabled()) {
      logger.debug(
          "compareProcesses() " + leftProcess.getName() + " with " + rightProcess.getName());
    }
    FDifference processDiff = null;
    if (leftProcess != null && rightProcess != null) {
      if (leftProcess.getSteps() != null && rightProcess.getSteps() != null) {
        // Find start step on the left
        StartStep leftStartStep = null;
        for (Step step : leftProcess.getSteps()) {
          if (step instanceof StartStep) {
            leftStartStep = (StartStep) step;
            break;
          }
        }

        // Find start step on the right
        StartStep rightStartStep = null;
        for (Step step : rightProcess.getSteps()) {
          if (step instanceof StartStep) {
            rightStartStep = (StartStep) step;
            break;
          }
        }

        if (leftStartStep != null && rightStartStep != null) {
          FDifference nameDiff =
              this.compareStepIds("start step name", leftStartStep, rightStartStep, leftProcess);

          processDiff = new FDifference(FDKind.ChangedElement, FDRating.Warning);
          processDiff.addDifference(nameDiff);
          processDiff.setDescription(
              "The process '"
                  + leftProcess.getName()
                  + "' describing the behavior has changed in version "
                  + this.getRightVersion());
          // start a simple bi-simulation
          this.bisimulate(leftStartStep.getNextStep(), rightStartStep.getNextStep(), processDiff);

          if (processDiff.getSubDiffs().isEmpty()) {
            // There were no underlying diffs found so this one is obsolete
            processDiff = null;
          }

        } else if (leftStartStep != null) {
          // right start step not found
          processDiff = new FDifference(FDKind.DeletedElement, FDRating.Warning);
          processDiff.setDescription(
              "The process's start step was deleted in version " + this.getRightVersion());
        } else if (rightStartStep != null) {
          // left start step not found
          processDiff = new FDifference(FDKind.CreatedElement, FDRating.Warning);
          processDiff.setDescription(
              "The process's start step was added in version " + this.getRightVersion());
        }
      } else {
        processDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
        processDiff.setSource(leftProcess);
        processDiff.setDescription("Either the left or the right process has no steps in it.");
      }

    } else {
      logger.error("Could not read process files - no compare possible!");
    }

    if (processDiff != null) {
      processDiff.setSource(leftProcess);
    }
    return processDiff;
  }
예제 #8
0
  private void bisimulate(Step leftStep, Step rightStep, FDifference parentDiff) {
    if (logger.isDebugEnabled()) {
      logger.debug("bisimulate() " + leftStep.getName() + " <-> " + rightStep.getName());
    }

    FDifference stepDiff = null;

    Step nextLeftStep = null;
    Step nextRightStep = null;

    if (leftStep != null && rightStep != null) {

      // Handle end steps
      if (leftStep instanceof EndStep) {
        if (!(rightStep instanceof EndStep)) {
          // left process ends but right process proceeds
          stepDiff = new FDifference(FDKind.CreatedElement, FDRating.Conflict);
          stepDiff.setSource(leftStep);
          stepDiff.setDescription(
              "The left process ends with "
                  + leftStep.getPrevStep().getType()
                  + " '"
                  + leftStep.getPrevStep().getName()
                  + "' but there are unmatched process steps in the right process left - starting from "
                  + rightStep.getType()
                  + " '"
                  + rightStep.getName()
                  + "'.");
        }
      } else if (rightStep instanceof EndStep) {
        // the right process ends but the left process proceeds
        stepDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
        stepDiff.setSource(leftStep);
        stepDiff.setDescription(
            "The right process ends with "
                + rightStep.getPrevStep().getType()
                + " '"
                + rightStep.getPrevStep().getName()
                + "' but there are unmatched process steps in the left process left - starting from "
                + leftStep.getType()
                + " '"
                + leftStep.getName()
                + "'.");
      } else if (match(leftStep, rightStep)) {
        // matching steps

        if (leftStep instanceof SubProcess) {
          // the right step is implicitly of type SubProcess because we had matching steps
          SubProcess leftSubProcess = (SubProcess) leftStep;
          SubProcess rightSubProcess = (SubProcess) rightStep;

          stepDiff =
              this.compareProcesses(
                  leftSubProcess.getSubProcess(), rightSubProcess.getSubProcess());
        } else if (leftStep instanceof HotSpotGroupCall) {
          HotSpotGroupCall leftHsgc = (HotSpotGroupCall) leftStep;
          HotSpotGroupCall rightHsgc = (HotSpotGroupCall) rightStep;
          stepDiff =
              basis.compareSets(
                  "hot spot group calls",
                  leftHsgc.getHotSpotGroups(),
                  rightHsgc.getHotSpotGroups(),
                  leftHsgc);
          if (stepDiff != null) {
            stepDiff.setDescription(
                "The hot spot group calls of step '"
                    + leftHsgc.getName()
                    + "' were changed in version "
                    + this.getRightVersion());
          }
        }

        // We had matching steps - go one step further on both sides
        nextLeftStep = leftStep.getNextStep();
        nextRightStep = rightStep.getNextStep();
      } else {
        // No match - see if there was something added or deleted on the right
        if (findMatch(leftStep, rightStep.getNextStep())) {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "bisimulate() left step '"
                    + leftStep.getName()
                    + "' found later on the right. So the right step "
                    + rightStep.getName()
                    + " was added.");
          }
          // There are new elements on the right side until the left step comes
          stepDiff = new FDifference(FDKind.CreatedElement, FDRating.Conflict);
          stepDiff.setSource(rightStep);
          stepDiff.setDescription(
              "The "
                  + rightStep.getType()
                  + " '"
                  + rightStep.getName()
                  + "' was added in version "
                  + this.getRightVersion());

          // Go one step further on right
          nextLeftStep = leftStep;
          nextRightStep = rightStep.getNextStep();
        } else {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "bisimulate() left step '"
                    + leftStep.getName()
                    + "' not found on right. So this step was removed.");
          }
          // The left step was removed because there is no match on the right side
          stepDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
          stepDiff.setSource(leftStep);
          stepDiff.setDescription(
              "The "
                  + leftStep.getType()
                  + " '"
                  + leftStep.getName()
                  + "' was removed in version "
                  + this.getRightVersion());

          // Go one step further on left
          nextLeftStep = leftStep.getNextStep();
          nextRightStep = rightStep;
        }
      }

    } else if (leftStep != null) {
      // No right step
      stepDiff = new FDifference(FDKind.DeletedElement, FDRating.Conflict);
      stepDiff.setSource(leftStep);
      stepDiff.setDescription(
          "The right process ends in the middle of the process but the left process proceeds with "
              + leftStep.getType()
              + " "
              + leftStep.getName());
    } else if (rightStep != null) {
      // No left step
      stepDiff = new FDifference(FDKind.CreatedElement, FDRating.Conflict);
      stepDiff.setSource(leftStep);
      stepDiff.setDescription(
          "The left process ends in the middle of the process but the right process proceeds with "
              + rightStep.getType()
              + " "
              + rightStep.getName());
    }

    parentDiff.addDifference(stepDiff);

    // Compare the next steps
    if (nextLeftStep != null && nextRightStep != null) {
      bisimulate(nextLeftStep, nextRightStep, parentDiff);
    }
  }