summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnits/unit/LoadingException.java
blob: 7b3d708a8eb50490246772c3d69b997b75a3b869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
 * Copyright (C) 2024, 2025 Adrien Hopkins
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package sevenUnits.unit;

import java.nio.file.Path;
import java.util.Optional;

/**
 * An exception that occurred when loading a file. This wrapper class adds more
 * info about the error.
 * 
 * @author Adrien Hopkins
 * @since 2024-08-22
 * @since v1.0.0
 */
public final class LoadingException extends RuntimeException {
	/** The type of file that was being loaded. */
	public static enum FileType {
		@SuppressWarnings("javadoc") UNIT, @SuppressWarnings("javadoc") DIMENSION
	}

	private static final long serialVersionUID = -8167971828216907607L;

	private final long lineNumber;
	private final String line;
	private final Optional<Path> file;

	private final FileType fileType;

	private final RuntimeException problem;

	/**
	 * Create a LoadingException from some information, without a file.
	 * 
	 * @param lineNumber line number error happened on
	 * @param line       text of invalid line
	 * @param fileType   type of file
	 * @param problem    problem, as an Exception
	 */
	public LoadingException(long lineNumber, String line, FileType fileType,
			RuntimeException problem) {
		super(problem);
		this.lineNumber = lineNumber;
		this.line = line;
		this.file = Optional.empty();
		this.fileType = fileType;
		this.problem = problem;
	}

	/**
	 * Create a LoadingException from some information, with a file.
	 * 
	 * @param lineNumber line number error happened on
	 * @param line       text of invalid line
	 * @param file       file error happened on
	 * @param fileType   type of file
	 * @param problem    problem, as an Exception
	 */
	public LoadingException(long lineNumber, String line, Path file,
			FileType fileType, RuntimeException problem) {
		super(problem);
		this.lineNumber = lineNumber;
		this.line = line;
		this.file = Optional.of(file);
		this.fileType = fileType;
		this.problem = problem;
	}

	/**
	 * @return the file this error happened in, if there is one
	 */
	public Optional<Path> file() {
		return this.file;
	}

	/**
	 * @return type of file that this error happened in
	 */
	public FileType fileType() {
		return this.fileType;
	}

	@Override
	public String getMessage() {
		return this.file
				.map(f -> String.format(
						"Error parsing line %d of %s file '%s' (\"%s\"): %s",
						this.lineNumber, this.fileType.toString().toLowerCase(), f,
						this.line, this.problem))
				.orElse(String.format(
						"Error parsing line %d of %s stream (\"%s\"): %s",
						this.lineNumber, this.fileType.toString().toLowerCase(),
						this.line, this.problem));
	}

	/**
	 * @return text of line that caused this error
	 */
	public String line() {
		return this.line;
	}

	/**
	 * @return number of line that caused this error
	 */
	public long lineNumber() {
		return this.lineNumber;
	}

	/**
	 * @return the error, as an exception
	 */
	public RuntimeException problem() {
		return this.problem;
	}
}