summaryrefslogtreecommitdiff
path: root/src/main/java/sevenUnits/unit
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/sevenUnits/unit')
-rw-r--r--src/main/java/sevenUnits/unit/LoadingException.java96
-rw-r--r--src/main/java/sevenUnits/unit/UnitDatabase.java138
2 files changed, 165 insertions, 69 deletions
diff --git a/src/main/java/sevenUnits/unit/LoadingException.java b/src/main/java/sevenUnits/unit/LoadingException.java
new file mode 100644
index 0000000..9376ed7
--- /dev/null
+++ b/src/main/java/sevenUnits/unit/LoadingException.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2024 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
+ */
+public final class LoadingException extends RuntimeException {
+ public static enum FileType {
+ UNIT, 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;
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public Optional<Path> file() {
+ return this.file;
+ }
+
+ 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));
+ }
+
+ public String line() {
+ return this.line;
+ }
+
+ public long lineNumber() {
+ return this.lineNumber;
+ }
+
+ public RuntimeException problem() {
+ return this.problem;
+ }
+}
diff --git a/src/main/java/sevenUnits/unit/UnitDatabase.java b/src/main/java/sevenUnits/unit/UnitDatabase.java
index 514b27d..dc81aca 100644
--- a/src/main/java/sevenUnits/unit/UnitDatabase.java
+++ b/src/main/java/sevenUnits/unit/UnitDatabase.java
@@ -1364,16 +1364,7 @@ public final class UnitDatabase {
throw new IllegalArgumentException(String.format(
"! used but no dimension found (line %d).", lineCounter));
} else {
- // it's a unit, get the unit
- final ObjectProduct<BaseDimension> dimension;
- try {
- dimension = this.getDimensionFromExpression(expression);
- } catch (final IllegalArgumentException | NoSuchElementException e) {
- System.err.printf("Parsing error on line %d:%n", lineCounter);
- throw e;
- }
-
- this.addDimension(name, dimension);
+ this.addDimension(name, this.getDimensionFromExpression(expression));
}
}
@@ -1454,56 +1445,15 @@ public final class UnitDatabase {
.format("! used but no unit found (line %d).", lineCounter));
} else {
if (name.endsWith("-")) {
- final UnitPrefix prefix;
- try {
- prefix = this.getPrefixFromExpression(expression);
- } catch (final IllegalArgumentException
- | NoSuchElementException e) {
- System.err.printf("Parsing error on line %d:%n", lineCounter);
- throw e;
- }
final String prefixName = name.substring(0, name.length() - 1);
- this.addPrefix(prefixName, prefix);
+ this.addPrefix(prefixName,
+ this.getPrefixFromExpression(expression));
} else if (expression.contains(";")) {
// it's a multi-unit
- final String[] parts = expression.split(";");
- final List<LinearUnit> units = new ArrayList<>(parts.length);
- for (final String unitName : parts) {
- final Unit unit;
- try {
- unit = this.getUnitFromExpression(unitName.trim());
- } catch (final NoSuchElementException e) {
- System.err.printf("Parsing error on line %d:%n", lineCounter);
- throw e;
- }
-
- if (unit instanceof LinearUnit) {
- units.add((LinearUnit) unit);
- } else {
- System.err.printf("Parsing error on line %d:%n", lineCounter);
- throw new IllegalArgumentException(String.format(
- "Unit '%s' is in a unit-set expression, but is not linear.",
- unitName));
- }
- }
-
- try {
- this.addUnitSet(name, units);
- } catch (final IllegalArgumentException e) {
- System.err.printf("Parsing error on line %d:%n", lineCounter);
- throw e;
- }
+ this.addUnitSet(name, this.getUnitSetFromExpression(expression));
} else {
// it's a unit, get the unit
- final Unit unit;
- try {
- unit = this.getUnitFromExpression(expression);
- } catch (final IllegalArgumentException
- | NoSuchElementException e) {
- System.err.printf("Parsing error on line %d:%n", lineCounter);
- throw e;
- }
- this.addUnit(name, unit);
+ this.addUnit(name, this.getUnitFromExpression(expression));
}
}
}
@@ -1951,6 +1901,27 @@ public final class UnitDatabase {
}
/**
+ * Parses a semicolon-separated expression to get the unit set being used.
+ *
+ * @since 2024-08-22
+ */
+ private List<LinearUnit> getUnitSetFromExpression(String expression) {
+ final String[] parts = expression.split(";");
+ final List<LinearUnit> units = new ArrayList<>(parts.length);
+ for (final String unitName : parts) {
+ final Unit unit = this.getUnitFromExpression(unitName.trim());
+
+ if (unit instanceof LinearUnit) {
+ units.add((LinearUnit) unit);
+ } else
+ throw new IllegalArgumentException(String.format(
+ "Unit '%s' is in a unit-set expression, but is not linear.",
+ unitName));
+ }
+ return units;
+ }
+
+ /**
* Adds all dimensions from a file, using data from the database to parse
* them.
* <p>
@@ -1970,24 +1941,30 @@ public final class UnitDatabase {
* </ul>
*
* @param file file to read
- * @throws IllegalArgumentException if the file cannot be parsed, found or
- * read
- * @throws NullPointerException if file is null
+ * @throws NullPointerException if file is null
+ * @returns list of errors that happened when loading file
* @since 2019-01-13
* @since v0.1.0
*/
- public void loadDimensionFile(final Path file) {
+ public List<LoadingException> loadDimensionFile(final Path file) {
Objects.requireNonNull(file, "file must not be null.");
+ final List<LoadingException> errors = new ArrayList<>();
try {
long lineCounter = 0;
for (final String line : Files.readAllLines(file)) {
- this.addDimensionFromLine(line, ++lineCounter);
+ try {
+ this.addDimensionFromLine(line, ++lineCounter);
+ } catch (IllegalArgumentException | NoSuchElementException e) {
+ errors.add(new LoadingException(lineCounter, line, file,
+ LoadingException.FileType.DIMENSION, e));
+ }
}
} catch (final FileNotFoundException e) {
throw new IllegalArgumentException("Could not find file " + file, e);
} catch (final IOException e) {
throw new IllegalArgumentException("Could not read file " + file, e);
}
+ return errors;
}
/**
@@ -1997,13 +1974,22 @@ public final class UnitDatabase {
* @param stream stream to load from
* @since 2021-03-27
*/
- public void loadDimensionsFromStream(final InputStream stream) {
+ public List<LoadingException> loadDimensionsFromStream(
+ final InputStream stream) {
+ final List<LoadingException> errors = new ArrayList<>();
try (final Scanner scanner = new Scanner(stream)) {
long lineCounter = 0;
while (scanner.hasNextLine()) {
- this.addDimensionFromLine(scanner.nextLine(), ++lineCounter);
+ final String line = scanner.nextLine();
+ try {
+ this.addDimensionFromLine(line, ++lineCounter);
+ } catch (IllegalArgumentException | NoSuchElementException e) {
+ errors.add(new LoadingException(lineCounter, line,
+ LoadingException.FileType.DIMENSION, e));
+ }
}
}
+ return errors;
}
/**
@@ -2025,24 +2011,30 @@ public final class UnitDatabase {
* </ul>
*
* @param file file to read
- * @throws IllegalArgumentException if the file cannot be parsed, found or
- * read
- * @throws NullPointerException if file is null
+ * @throws NullPointerException if file is null
+ * @returns list of errors that happened when loading file
* @since 2019-01-13
* @since v0.1.0
*/
- public void loadUnitsFile(final Path file) {
+ public List<LoadingException> loadUnitsFile(final Path file) {
Objects.requireNonNull(file, "file must not be null.");
+ final List<LoadingException> errors = new ArrayList<>();
try {
long lineCounter = 0;
for (final String line : Files.readAllLines(file)) {
- this.addUnitOrPrefixFromLine(line, ++lineCounter);
+ try {
+ this.addUnitOrPrefixFromLine(line, ++lineCounter);
+ } catch (IllegalArgumentException | NoSuchElementException e) {
+ errors.add(new LoadingException(lineCounter, line, file,
+ LoadingException.FileType.UNIT, e));
+ }
}
} catch (final FileNotFoundException e) {
throw new IllegalArgumentException("Could not find file " + file, e);
} catch (final IOException e) {
throw new IllegalArgumentException("Could not read file " + file, e);
}
+ return errors;
}
/**
@@ -2052,13 +2044,21 @@ public final class UnitDatabase {
* @param stream stream to load from
* @since 2021-03-27
*/
- public void loadUnitsFromStream(InputStream stream) {
+ public List<LoadingException> loadUnitsFromStream(InputStream stream) {
+ final List<LoadingException> errors = new ArrayList<>();
try (final Scanner scanner = new Scanner(stream)) {
long lineCounter = 0;
while (scanner.hasNextLine()) {
- this.addUnitOrPrefixFromLine(scanner.nextLine(), ++lineCounter);
+ final String line = scanner.nextLine();
+ try {
+ this.addUnitOrPrefixFromLine(line, ++lineCounter);
+ } catch (IllegalArgumentException | NoSuchElementException e) {
+ errors.add(new LoadingException(lineCounter, line,
+ LoadingException.FileType.UNIT, e));
+ }
}
}
+ return errors;
}
/**