McpResult.java
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* (C) Copyright 2009-2024, Arnaud Roques
*
* Project Info: https://plantuml.com
*
* If you like this project or if you find it useful, you can support us at:
*
* https://plantuml.com/patreon (only 1$ per month!)
* https://plantuml.com/paypal
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML 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 General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
*
* Original Author: Arnaud Roques
*
*
*/
package net.sourceforge.plantuml.mcp;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.plantuml.ErrorUml;
import net.sourceforge.plantuml.TitledDiagram;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.error.PSystemError;
import net.sourceforge.plantuml.warning.Warning;
public class McpResult {
private boolean ok;
private String diagramType;
private int lineCount;
private final List<String> warnings = new ArrayList<>();
private int errorLineNumber = -1;
private String errorLine = "";
private String errorMessage = "";
private String errorContext = "";
private String svg;
private McpResult() {
}
public McpResult(final Diagram diagram) {
this.lineCount = diagram.getSource().getTotalLineCount();
if (diagram instanceof PSystemError) {
this.ok = false;
final PSystemError error = (PSystemError) diagram;
final ErrorUml firstError = error.getFirstError();
if (firstError != null) {
// getPosition() is 0-based; the public contract exposes a 1-based line.
this.errorLineNumber = firstError.getPosition() + 1;
this.errorLine = firstError.getLine().getString() == null ? "" : firstError.getLine().getString();
this.errorMessage = firstError.getError();
}
} else {
this.ok = true;
this.diagramType = diagram.getClass().getSimpleName();
}
if (diagram instanceof TitledDiagram) {
final TitledDiagram titledDiagram = (TitledDiagram) diagram;
for (Warning w : titledDiagram.getWarnings())
this.warnings.add(w.asSingleLine());
}
}
public McpResult(Diagram diagram, String svg) {
this(diagram);
this.svg = svg;
}
/**
* Builds a result for a diagram that parsed correctly but failed to render. The
* structured counters from {@code diagram} are kept, but the result is marked
* as not OK and carries the rendering error message.
*
* @param diagram the parsed (non-error) diagram
* @param message the rendering error message
* @return a not-OK result describing the rendering failure
*/
public static McpResult renderError(Diagram diagram, String message) {
final McpResult result = new McpResult(diagram);
result.ok = false;
result.errorMessage = message;
return result;
}
public static McpResult badInput() {
final McpResult result = new McpResult();
result.errorMessage = "Expected exactly one diagram in the source";
return result;
}
public static McpResult noAtStart() {
final McpResult result = new McpResult();
result.errorMessage = "The input must start with a @start... directive (for example @startuml)";
return result;
}
/**
* @return {@code true} if the source parsed without error
*/
public boolean isOk() {
return ok;
}
/**
* @return the detected diagram type when OK (e.g. "SequenceDiagram"), or
* {@code null} when not applicable
*/
public String getDiagramType() {
return diagramType;
}
/**
* @return the number of source lines of the checked diagram
*/
public int getLineCount() {
return lineCount;
}
/**
* @return the non-fatal warnings, never {@code null} (possibly empty)
*/
public List<String> getWarnings() {
return warnings;
}
/**
* @return the 1-based line of the error, or -1 when {@link #isOk()} is
* {@code true}
*/
public int getErrorLineNumber() {
return errorLineNumber;
}
/**
* @return the error message, or {@code null} when {@link #isOk()} is
* {@code true}
*/
public String getErrorMessage() {
return errorMessage;
}
public String getErrorLine() {
return errorLine;
}
/**
* @return the offending source line, or {@code null} when not available
*/
public String getErrorContext() {
return errorContext;
}
public String getSvg() {
return svg;
}
}