private ParsedTimeCondition getTimeCondition()

in rest-api/src/jetbrains/buildServer/server/rest/data/TimeCondition.java [157:246]


  private ParsedTimeCondition getTimeCondition(@NotNull final String timeLocatorText, @Nullable final ValueExtractor<BuildPromotion, Date> buildValueExtractor) {
    @NotNull TimeWithPrecision limitingDate;

    boolean buildIsSupported = buildValueExtractor != null;
    final Locator timeLocator = buildIsSupported ?
                                new Locator(timeLocatorText, DATE, BUILD, CONDITION, INCLUDE_INITIAL, Locator.LOCATOR_SINGLE_VALUE_UNUSED_NAME) :
                                new Locator(timeLocatorText, DATE, CONDITION, INCLUDE_INITIAL, Locator.LOCATOR_SINGLE_VALUE_UNUSED_NAME);
    timeLocator.addHiddenDimensions(SHIFT);
    timeLocator.processHelpRequest();
    final String time = timeLocator.getSingleValue();
    if (time != null) {
      limitingDate = TimeWithPrecision.parse(time, myTimeService);
    } else {
      final String shift = timeLocator.getSingleDimensionValue(SHIFT);
      final String dateDimension = timeLocator.getSingleDimensionValue(DATE);
      if (dateDimension != null) {
        limitingDate = TimeWithPrecision.parse(dateDimension, myTimeService);
      } else {
        if (buildIsSupported) {
          String build = timeLocator.getSingleDimensionValue(BUILD);
          if (build != null) {
            Date timeFromBuild = buildValueExtractor.get(getBuildPromotionFinder().getItem(build));
            if (timeFromBuild == null) {
              throw new BadRequestException("Cannot determine time from build found by locator '" + build + "'");
            }
            limitingDate = new TimeWithPrecision(timeFromBuild, false);
          } else if (shift != null) {
            limitingDate = new TimeWithPrecision(new Date(myTimeService.now()), false);
          } else {
            throw new BadRequestException("Invalid locator: should contain '" + DATE + "' or '" + BUILD + "' dimensions or be relative time offset starting with '-'.");
          }
        } else {
          throw new BadRequestException("Invalid locator: should contain '" + DATE + "' dimension or be relative time offset starting with '-'.");
        }
      }

      if (shift != null) {
        if (shift.startsWith("-")) {
          limitingDate = new TimeWithPrecision(new Date(limitingDate.getTime().getTime() - TimeWithPrecision.getMsFromRelativeTime(shift.substring("-".length()))),
                                               limitingDate.isSecondsPrecision());
        } else if (shift.startsWith("+")) {
          limitingDate = new TimeWithPrecision(new Date(limitingDate.getTime().getTime() + TimeWithPrecision.getMsFromRelativeTime(shift.substring("+".length()))),
                                               limitingDate.isSecondsPrecision());
        } else {
          throw new BadRequestException("Wrong value '" + shift + "' for '" + SHIFT + "' dimension: should start with '+' or '-'.");
        }
      }
    }

    final String conditionText = timeLocator.getSingleDimensionValue(CONDITION);
    if (Locator.HELP_DIMENSION.equals(conditionText)) {
      throw new BadRequestException("Supported names are: " + Arrays.toString(getAllConditions()));
    }
    final String conditionName = conditionText == null ? DATE_CONDITION_AFTER : conditionText; //todo: should it be "equal" instead???
    final Condition<Date> definedCondition = getCondition(conditionName);
    if (definedCondition == null) {
      throw new BadRequestException("Invalid condition name '" + conditionName + "'. Supported names are: " + Arrays.toString(getAllConditions()));
    }

    Boolean includeInitial = timeLocator.getSingleDimensionValueAsBoolean(INCLUDE_INITIAL, false);
    if (includeInitial == null) {
      includeInitial = false;
    }

    timeLocator.checkLocatorFullyProcessed();

    Condition<Date> resultingCondition;
    if (!includeInitial) {
      resultingCondition = definedCondition;
    } else {
      resultingCondition = (refDate, tryDate) -> {
        final boolean nestedResult = definedCondition.matches(refDate, tryDate);
        return refDate == null ? nestedResult : nestedResult || refDate.equals(tryDate);
      };
    }

    if (limitingDate.isSecondsPrecision()) {
      final Condition<Date> currentCondition = resultingCondition;
      resultingCondition = (refDate, tryDate) -> {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tryDate);
        calendar.set(Calendar.MILLISECOND, 0);

        return currentCondition.matches(refDate, calendar.getTime());
      };
    }

    @Nullable TimeWithPrecision limitingSinceDate = DATE_CONDITION_AFTER.equals(conditionName) || DATE_CONDITION_EQUALS.equals(conditionName) ? limitingDate : null;
    return new ParsedTimeCondition(limitingSinceDate, limitingDate, resultingCondition);
  }