public Response apply()

in java/com/google/gerrit/plugins/codeowners/restapi/CheckCodeOwner.java [149:347]


  public Response<CodeOwnerCheckInfo> apply(BranchResource branchResource)
      throws BadRequestException, AuthException, IOException, ConfigInvalidException,
          PermissionBackendException, ResourceNotFoundException {
    permissionBackend.currentUser().check(checkCodeOwnerCapability.getPermission());

    validateInput(branchResource);

    Path absolutePath = JgitPath.of(path).getAsAbsolutePath();
    List<String> messages = new ArrayList<>();
    List<Path> codeOwnerConfigFilePaths = new ArrayList<>();
    AtomicBoolean isCodeOwnershipAssignedToEmail = new AtomicBoolean(false);
    AtomicBoolean isCodeOwnershipAssignedToAllUsers = new AtomicBoolean(false);
    AtomicBoolean isDefaultCodeOwner = new AtomicBoolean(false);
    AtomicBoolean hasRevelantCodeOwnerDefinitions = new AtomicBoolean(false);
    AtomicBoolean parentCodeOwnersAreIgnored = new AtomicBoolean(false);
    Set<String> annotations = new HashSet<>();
    codeOwnerConfigHierarchy.visit(
        branchResource.getBranchKey(),
        ObjectId.fromString(branchResource.getRevision().get()),
        absolutePath,
        codeOwnerConfig -> {
          messages.add(
              String.format(
                  "checking code owner config file %s", codeOwnerConfig.key().format(codeOwners)));
          OptionalResultWithMessages<PathCodeOwnersResult> pathCodeOwnersResult =
              pathCodeOwnersFactory
                  .createWithoutCache(codeOwnerConfig, absolutePath)
                  .resolveCodeOwnerConfig();
          messages.addAll(pathCodeOwnersResult.messages());
          pathCodeOwnersResult
              .get()
              .unresolvedImports()
              .forEach(
                  unresolvedImport ->
                      messages.add(unresolvedImportFormatter.format(unresolvedImport)));
          Optional<CodeOwnerReference> codeOwnerReference =
              pathCodeOwnersResult.get().getPathCodeOwners().stream()
                  .filter(cor -> cor.email().equals(email))
                  .findAny();
          if (codeOwnerReference.isPresent()
              && !CodeOwnerResolver.ALL_USERS_WILDCARD.equals(email)) {
            isCodeOwnershipAssignedToEmail.set(true);

            if (RefNames.isConfigRef(codeOwnerConfig.key().ref())) {
              messages.add(
                  String.format(
                      "found email %s as a code owner in the default code owner config", email));
              isDefaultCodeOwner.set(true);
            } else {
              Path codeOwnerConfigFilePath = codeOwners.getFilePath(codeOwnerConfig.key());
              messages.add(
                  String.format(
                      "found email %s as a code owner in %s", email, codeOwnerConfigFilePath));
              codeOwnerConfigFilePaths.add(codeOwnerConfigFilePath);
            }

            ImmutableSet<String> localAnnotations =
                pathCodeOwnersResult.get().getAnnotationsFor(email);
            if (!localAnnotations.isEmpty()) {
              messages.add(
                  String.format("email %s is annotated with %s", email, sort(localAnnotations)));
              annotations.addAll(localAnnotations);
            }
          }

          if (pathCodeOwnersResult.get().getPathCodeOwners().stream()
              .anyMatch(cor -> cor.email().equals(CodeOwnerResolver.ALL_USERS_WILDCARD))) {
            isCodeOwnershipAssignedToAllUsers.set(true);

            if (RefNames.isConfigRef(codeOwnerConfig.key().ref())) {
              messages.add(
                  String.format(
                      "found the all users wildcard ('%s') as a code owner in the default code"
                          + " owner config which makes %s a code owner",
                      CodeOwnerResolver.ALL_USERS_WILDCARD, email));
              isDefaultCodeOwner.set(true);
            } else {
              Path codeOwnerConfigFilePath = codeOwners.getFilePath(codeOwnerConfig.key());
              messages.add(
                  String.format(
                      "found the all users wildcard ('%s') as a code owner in %s which makes %s a"
                          + " code owner",
                      CodeOwnerResolver.ALL_USERS_WILDCARD, codeOwnerConfigFilePath, email));
              if (!codeOwnerConfigFilePaths.contains(codeOwnerConfigFilePath)) {
                codeOwnerConfigFilePaths.add(codeOwnerConfigFilePath);
              }
            }

            ImmutableSet<String> localAnnotations =
                pathCodeOwnersResult.get().getAnnotationsFor(CodeOwnerResolver.ALL_USERS_WILDCARD);
            if (!localAnnotations.isEmpty()) {
              messages.add(
                  String.format(
                      "found annotations for the all users wildcard ('%s') which apply to %s: %s",
                      CodeOwnerResolver.ALL_USERS_WILDCARD, email, sort(localAnnotations)));
              annotations.addAll(localAnnotations);
            }
          }

          if (codeOwnerResolverProvider
              .get()
              .resolvePathCodeOwners(codeOwnerConfig, absolutePath)
              .hasRevelantCodeOwnerDefinitions()) {
            hasRevelantCodeOwnerDefinitions.set(true);
          }

          if (pathCodeOwnersResult.get().ignoreParentCodeOwners()) {
            messages.add("parent code owners are ignored");
            parentCodeOwnersAreIgnored.set(true);
          }

          return !pathCodeOwnersResult.get().ignoreParentCodeOwners();
        });

    boolean isGlobalCodeOwner = false;

    if (isGlobalCodeOwner(branchResource.getNameKey(), email)) {
      isGlobalCodeOwner = true;
      messages.add(String.format("found email %s as global code owner", email));
      isCodeOwnershipAssignedToEmail.set(true);
    }

    if (isGlobalCodeOwner(branchResource.getNameKey(), CodeOwnerResolver.ALL_USERS_WILDCARD)) {
      isGlobalCodeOwner = true;
      messages.add(
          String.format(
              "found email %s as global code owner", CodeOwnerResolver.ALL_USERS_WILDCARD));
      isCodeOwnershipAssignedToAllUsers.set(true);
    }

    boolean isResolvable;
    Boolean canReadRef = null;
    Boolean canSeeChange = null;
    Boolean canApproveChange = null;
    if (email.equals(CodeOwnerResolver.ALL_USERS_WILDCARD)) {
      isResolvable = true;
    } else {
      OptionalResultWithMessages<CodeOwner> isResolvableResult = isResolvable();
      isResolvable = isResolvableResult.isPresent();
      messages.addAll(isResolvableResult.messages());

      if (isResolvable) {
        PermissionBackend.WithUser withUser =
            permissionBackend.absentUser(isResolvableResult.get().accountId());
        canReadRef = withUser.ref(branchResource.getBranchKey()).test(RefPermission.READ);

        if (changeNotes != null) {
          PermissionBackend.ForChange forChange = withUser.change(changeNotes);
          canSeeChange = forChange.test(ChangePermission.READ);
          RequiredApproval requiredApproval =
              codeOwnersPluginConfiguration
                  .getProjectConfig(branchResource.getNameKey())
                  .getRequiredApproval();
          canApproveChange =
              forChange.test(
                  new LabelPermission.WithValue(
                      requiredApproval.labelType(), requiredApproval.value()));
        }
      }
    }

    ImmutableSet<String> unsupportedAnnotations =
        annotations.stream()
            .filter(annotation -> !CodeOwnerAnnotations.isSupported(annotation))
            .collect(toImmutableSet());
    if (!unsupportedAnnotations.isEmpty()) {
      messages.add(
          String.format(
              "dropping unsupported annotations for %s: %s", email, sort(unsupportedAnnotations)));
      annotations.removeAll(unsupportedAnnotations);
    }

    boolean isFallbackCodeOwner =
        !isCodeOwnershipAssignedToEmail.get()
            && !isCodeOwnershipAssignedToAllUsers.get()
            && !hasRevelantCodeOwnerDefinitions.get()
            && !parentCodeOwnersAreIgnored.get()
            && isFallbackCodeOwner(branchResource.getNameKey());

    CodeOwnerCheckInfo codeOwnerCheckInfo = new CodeOwnerCheckInfo();
    codeOwnerCheckInfo.isCodeOwner =
        (isCodeOwnershipAssignedToEmail.get()
                || isCodeOwnershipAssignedToAllUsers.get()
                || isFallbackCodeOwner)
            && isResolvable;
    codeOwnerCheckInfo.isResolvable = isResolvable;
    codeOwnerCheckInfo.canReadRef = canReadRef;
    codeOwnerCheckInfo.canSeeChange = canSeeChange;
    codeOwnerCheckInfo.canApproveChange = canApproveChange;
    codeOwnerCheckInfo.codeOwnerConfigFilePaths =
        codeOwnerConfigFilePaths.stream().map(Path::toString).collect(toList());
    codeOwnerCheckInfo.isFallbackCodeOwner = isFallbackCodeOwner && isResolvable;
    codeOwnerCheckInfo.isDefaultCodeOwner = isDefaultCodeOwner.get();
    codeOwnerCheckInfo.isGlobalCodeOwner = isGlobalCodeOwner;
    codeOwnerCheckInfo.isOwnedByAllUsers = isCodeOwnershipAssignedToAllUsers.get();
    codeOwnerCheckInfo.annotations = sort(annotations);
    codeOwnerCheckInfo.debugLogs = messages;
    return Response.ok(codeOwnerCheckInfo);
  }