From 8e613844ae19a4dea2089ac34c1f0ae650eaeae7 Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Sat, 13 Apr 2019 10:05:08 -0400 Subject: The dimension selector now loads dimensions from a file. The dimension selector does nothing, as its purpose is to filter a list which does not exist yet, but it does correctly load the options. --- src/org/unitConverter/UnitsDatabase.java | 265 +++++++++++++++++++++++-------- 1 file changed, 197 insertions(+), 68 deletions(-) (limited to 'src/org/unitConverter/UnitsDatabase.java') diff --git a/src/org/unitConverter/UnitsDatabase.java b/src/org/unitConverter/UnitsDatabase.java index 69b25d8..626f145 100755 --- a/src/org/unitConverter/UnitsDatabase.java +++ b/src/org/unitConverter/UnitsDatabase.java @@ -125,46 +125,6 @@ public final class UnitsDatabase { this.dimensions = new HashMap<>(); } - /** - * Adds all units from a file, using data from the database to parse them. - *

- * Each line in the file should consist of a name and an expression (parsed by getUnitFromExpression) separated by - * any number of tab characters. - *

- *

- * Allowed exceptions: - *

- * - * @param file - * file to read - * @throws IllegalArgumentException - * if the file cannot be parsed, found or read - * @throws NullPointerException - * if file is null - * @since 2019-01-13 - * @since v0.1.0 - */ - public void addAllFromFile(final File file) { - Objects.requireNonNull(file, "file must not be null."); - try (FileReader fileReader = new FileReader(file); BufferedReader reader = new BufferedReader(fileReader)) { - // while the reader has lines to read, read a line, then parse it, then add it - long lineCounter = 0; - while (reader.ready()) { - this.addFromLine(reader.readLine(), ++lineCounter); - } - } 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); - } - } - /** * Adds a unit dimension to the database. * @@ -182,7 +142,7 @@ public final class UnitsDatabase { } /** - * Adds to the list from a line in a unit file. + * Adds to the list from a line in a unit dimension file. * * @param line * line to look at @@ -190,12 +150,12 @@ public final class UnitsDatabase { * number of line, for error messages * @since 2019-04-10 */ - private void addFromLine(final String line, final long lineCounter) { + private void addDimensionFromLine(final String line, final long lineCounter) { // ignore lines that start with a # sign - they're comments if (line.isEmpty()) return; if (line.contains("#")) { - this.addFromLine(line.substring(0, line.indexOf("#")), lineCounter); + this.addDimensionFromLine(line.substring(0, line.indexOf("#")), lineCounter); return; } @@ -203,42 +163,32 @@ public final class UnitsDatabase { final String[] parts = line.split("\t"); if (parts.length < 2) throw new IllegalArgumentException(String.format( - "Lines must consist of a unit name and its definition, separated by tab(s) (line %d).", + "Lines must consist of a dimension name and its definition, separated by tab(s) (line %d).", lineCounter)); final String name = parts[0]; final String expression = parts[parts.length - 1]; if (name.endsWith(" ")) { - System.err.printf("Warning - line %d's unit name ends in a space", lineCounter); + System.err.printf("Warning - line %d's dimension name ends in a space", lineCounter); } - // if expression is "!", search for an existing unit + // if expression is "!", search for an existing dimension // if no unit found, throw an error if (expression.equals("!")) { - if (!this.containsUnitName(name)) - throw new IllegalArgumentException(String.format("! used but no unit found (line %d).", lineCounter)); + if (!this.containsDimensionName(name)) + throw new IllegalArgumentException( + String.format("! used but no dimension found (line %d).", lineCounter)); } else { - if (name.endsWith("-")) { - final UnitPrefix prefix; - try { - prefix = this.getPrefixFromExpression(expression); - } catch (final IllegalArgumentException e) { - System.err.printf("Parsing error on line %d:%n", lineCounter); - throw e; - } - this.addPrefix(name.substring(0, name.length() - 1), prefix); - } else { - // it's a unit, get the unit - final Unit unit; - try { - unit = this.getUnitFromExpression(expression); - } catch (final IllegalArgumentException e) { - System.err.printf("Parsing error on line %d:%n", lineCounter); - throw e; - } - - this.addUnit(name, unit); + // it's a unit, get the unit + final UnitDimension dimension; + try { + dimension = this.getDimensionFromExpression(expression); + } catch (final IllegalArgumentException e) { + System.err.printf("Parsing error on line %d:%n", lineCounter); + throw e; } + + this.addDimension(name, dimension); } } @@ -276,6 +226,67 @@ public final class UnitsDatabase { Objects.requireNonNull(unit, "unit must not be null.")); } + /** + * Adds to the list from a line in a unit file. + * + * @param line + * line to look at + * @param lineCounter + * number of line, for error messages + * @since 2019-04-10 + */ + private void addUnitOrPrefixFromLine(final String line, final long lineCounter) { + // ignore lines that start with a # sign - they're comments + if (line.isEmpty()) + return; + if (line.contains("#")) { + this.addUnitOrPrefixFromLine(line.substring(0, line.indexOf("#")), lineCounter); + return; + } + + // divide line into name and expression + final String[] parts = line.split("\t"); + if (parts.length < 2) + throw new IllegalArgumentException(String.format( + "Lines must consist of a unit name and its definition, separated by tab(s) (line %d).", + lineCounter)); + final String name = parts[0]; + final String expression = parts[parts.length - 1]; + + if (name.endsWith(" ")) { + System.err.printf("Warning - line %d's unit name ends in a space", lineCounter); + } + + // if expression is "!", search for an existing unit + // if no unit found, throw an error + if (expression.equals("!")) { + if (!this.containsUnitName(name)) + throw new IllegalArgumentException(String.format("! used but no unit found (line %d).", lineCounter)); + } else { + if (name.endsWith("-")) { + final UnitPrefix prefix; + try { + prefix = this.getPrefixFromExpression(expression); + } catch (final IllegalArgumentException e) { + System.err.printf("Parsing error on line %d:%n", lineCounter); + throw e; + } + this.addPrefix(name.substring(0, name.length() - 1), prefix); + } else { + // it's a unit, get the unit + final Unit unit; + try { + unit = this.getUnitFromExpression(expression); + } catch (final IllegalArgumentException e) { + System.err.printf("Parsing error on line %d:%n", lineCounter); + throw e; + } + + this.addUnit(name, unit); + } + } + } + /** * Tests if the database has a unit dimension with this name. * @@ -372,6 +383,44 @@ public final class UnitsDatabase { return this.dimensions.get(name); } + /** + * Uses the database's data to parse an expression into a unit dimension + *

+ * The expression is a series of any of the following: + *

+ * + * @param expression + * expression to parse + * @throws IllegalArgumentException + * if the expression cannot be parsed + * @throws NullPointerException + * if expression is null + * @since 2019-04-13 + */ + public UnitDimension getDimensionFromExpression(final String expression) { + Objects.requireNonNull(expression, "expression must not be null."); + + // attempt to get a dimension as an alias first + if (this.containsDimensionName(expression)) + return this.getDimension(expression); + + // force operators to have spaces + String modifiedExpression = expression; + modifiedExpression = modifiedExpression.replaceAll("\\*", " \\* "); + modifiedExpression = modifiedExpression.replaceAll("/", " / "); + modifiedExpression = modifiedExpression.replaceAll(" *\\^ *", "\\^"); + + // fix broken spaces + modifiedExpression = modifiedExpression.replaceAll(" +", " "); + + return this.unitDimensionParser.parseExpression(modifiedExpression); + } + /** * Gets a unit. If it is linear, cast it to a LinearUnit and return it. Otherwise, throw an * {@code IllegalArgumentException}. @@ -598,6 +647,86 @@ public final class UnitsDatabase { return this.unitExpressionParser.parseExpression(modifiedExpression); } + /** + * Adds all dimensions from a file, using data from the database to parse them. + *

+ * Each line in the file should consist of a name and an expression (parsed by getDimensionFromExpression) separated + * by any number of tab characters. + *

+ *

+ * Allowed exceptions: + *

+ * + * @param file + * file to read + * @throws IllegalArgumentException + * if the file cannot be parsed, found or read + * @throws NullPointerException + * if file is null + * @since 2019-01-13 + * @since v0.1.0 + */ + public void loadDimensionFile(final File file) { + Objects.requireNonNull(file, "file must not be null."); + try (FileReader fileReader = new FileReader(file); BufferedReader reader = new BufferedReader(fileReader)) { + // while the reader has lines to read, read a line, then parse it, then add it + long lineCounter = 0; + while (reader.ready()) { + this.addDimensionFromLine(reader.readLine(), ++lineCounter); + } + } 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); + } + } + + /** + * Adds all units from a file, using data from the database to parse them. + *

+ * Each line in the file should consist of a name and an expression (parsed by getUnitFromExpression) separated by + * any number of tab characters. + *

+ *

+ * Allowed exceptions: + *

+ * + * @param file + * file to read + * @throws IllegalArgumentException + * if the file cannot be parsed, found or read + * @throws NullPointerException + * if file is null + * @since 2019-01-13 + * @since v0.1.0 + */ + public void loadUnitsFile(final File file) { + Objects.requireNonNull(file, "file must not be null."); + try (FileReader fileReader = new FileReader(file); BufferedReader reader = new BufferedReader(fileReader)) { + // while the reader has lines to read, read a line, then parse it, then add it + long lineCounter = 0; + while (reader.ready()) { + this.addUnitOrPrefixFromLine(reader.readLine(), ++lineCounter); + } + } 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 an immutable set of all of the unit names in this database, ignoring prefixes * @since 2019-01-14 -- cgit v1.2.3