All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apiaddicts.apitools.dosonarapi.api.IssueLocation Maven / Gradle / Ivy

/*
 * doSonarAPI: SonarQube OpenAPI Plugin
 * Copyright (C) 2021-2022 Apiaddicts
 * contacta AT apiaddicts DOT org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.apiaddicts.apitools.dosonarapi.api;

import com.sonar.sslr.api.Token;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apiaddicts.apitools.dosonarapi.sslr.yaml.grammar.JsonNode;

public abstract class IssueLocation {

  public static final int UNDEFINED_OFFSET = -1;

  public static final int UNDEFINED_LINE = 0;
  public static final String EMPTY_POINTER = "";

  private String message;

  private IssueLocation(@Nullable String message) {
    this.message = message;
  }

  public static IssueLocation atFileLevel(@Nullable String message) {
    return new FileLevelIssueLocation(message);
  }

  public static IssueLocation atLineLevel(@Nullable String message, int lineNumber) {
    return new LineLevelIssueLocation(message, lineNumber);
  }

  public static IssueLocation preciseLocation(@Nullable String message, JsonNode startNode) {
    return new PreciseIssueLocation(startNode, message);
  }

  public static IssueLocation preciseLocation(JsonNode startNode, JsonNode endNode, @Nullable String message) {
    return new PreciseIssueLocation(startNode, endNode, message);
  }

  @CheckForNull
  public String message() {
    return message;
  }

  public abstract int startLine();

  public abstract int startLineOffset();

  public abstract int endLine();

  public abstract int endLineOffset();

  @Override
  public final boolean equals(Object o){
    if (o instanceof IssueLocation) {
      IssueLocation o1 = (IssueLocation) o;
      boolean equals =  o1.startLine() == this.startLine() &&
        o1.endLine() == this.endLine() &&
        o1.endLineOffset() == this.endLineOffset() &&
        o1.startLineOffset() == this.startLineOffset();
      if (this.message != null){
        equals &= this.message.equals(o1.message());
      }else{
        equals &= (o1.message() == null);
      }
      return equals;
    }
    return false;
  }

  @Override
  public final int hashCode(){
    int hashCode = startLine() + endLine() + startLineOffset() + endLineOffset();
    if (message != null){
           hashCode += message.hashCode();
    }
    return hashCode;
  }

  public String pointer() {
    return EMPTY_POINTER;
  }


  public static class TokenLocation {

    private final int startLine;
    private final int startLineOffset;
    private final int endLine;
    private final int endLineOffset;

    public TokenLocation(Token token) {
      this.startLine = token.getLine();
      this.startLineOffset = token.getColumn();
      String value = token.getOriginalValue();
      String[] lines = value.split("\r\n|\n|\r", -1);

      if (lines.length > 1) {
        endLine = token.getLine() + lines.length - 1;
        endLineOffset = lines[lines.length - 1].length();

      } else {
        this.endLine = this.startLine;
        this.endLineOffset = this.startLineOffset + token.getOriginalValue().length();
      }
    }

    public int startLine() {
      return startLine;
    }

    public int startLineOffset() {
      return startLineOffset;
    }

    public int endLine() {
      return endLine;
    }

    public int endLineOffset() {
      return endLineOffset;
    }

  }

  private static class PreciseIssueLocation extends IssueLocation {

    private final TokenLocation firstTokenLocation;
    private final TokenLocation lastTokenLocation;
    private final String pointer;

    public PreciseIssueLocation(JsonNode node, @Nullable String message) {
      super(message);
      this.firstTokenLocation = new TokenLocation(node.getToken());
      this.lastTokenLocation = new TokenLocation(node.getLastToken());
      this.pointer = node.getPointer()
          .replace("~1", "/")
          .replace("~0", "~")
          .replace("paths//", "paths/");
    }

    public PreciseIssueLocation(JsonNode startNode, JsonNode endNode, @Nullable String message) {
      super(message);
      this.firstTokenLocation = new TokenLocation(startNode.getToken());
      this.lastTokenLocation = new TokenLocation(endNode.getLastToken());
      this.pointer = startNode.getPointer();
    }

    @Override
    public int startLine() {
      return firstTokenLocation.startLine();
    }

    @Override
    public int startLineOffset() {
      return firstTokenLocation.startLineOffset();
    }

    @Override
    public int endLine() {
      return lastTokenLocation.endLine();
    }

    @Override
    public int endLineOffset() {
      return lastTokenLocation.endLineOffset();
    }

    @Override
    public String pointer() {
      return pointer;
    }
  }


  private static class LineLevelIssueLocation extends IssueLocation {

    private final int lineNumber;

    public LineLevelIssueLocation(@Nullable String message, int lineNumber) {
      super(message);
      this.lineNumber = lineNumber;
    }

    @Override
    public int startLine() {
      return lineNumber;
    }

    @Override
    public int startLineOffset() {
      return UNDEFINED_OFFSET;
    }

    @Override
    public int endLine() {
      return lineNumber;
    }

    @Override
    public int endLineOffset() {
      return UNDEFINED_OFFSET;
    }

  }

  private static class FileLevelIssueLocation extends IssueLocation {

    public FileLevelIssueLocation(@Nullable String message) {
      super(message);
    }

    @Override
    public int startLine() {
      return UNDEFINED_LINE;
    }

    @Override
    public int startLineOffset() {
      return UNDEFINED_OFFSET;
    }

    @Override
    public int endLine() {
      return UNDEFINED_LINE;
    }

    @Override
    public int endLineOffset() {
      return UNDEFINED_OFFSET;
    }

  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy