/** * Copyright (C) 2022 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 . */ package sevenUnitsGUI; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import sevenUnits.unit.LinearUnit; import sevenUnits.unit.Metric; import sevenUnits.unit.UnitPrefix; /** * A search rule that applies a certain set of prefixes to a unit. It always * includes the original unit in the output map. * * @since 2022-07-06 */ public final class PrefixSearchRule implements Function, Map> { /** * A rule that does not add any prefixed versions of units. */ public static final PrefixSearchRule NO_PREFIXES = getUniversalRule( Set.of()); /** * A rule that gives every unit a common set of prefixes. */ public static final PrefixSearchRule COMMON_PREFIXES = getCoherentOnlyRule( Set.of(Metric.MILLI, Metric.KILO)); /** * A rule that gives every unit all metric prefixes. */ public static final PrefixSearchRule ALL_METRIC_PREFIXES = getCoherentOnlyRule( Metric.ALL_PREFIXES); /** * Gets a rule that applies the provided prefixes to coherent units only (as * defined by {@link LinearUnit#isCoherent}), except the kilogram * (specifically, units named "kilogram"). * * @param prefixes prefixes to apply * @return prefix rule * @since 2022-07-06 */ public static final PrefixSearchRule getCoherentOnlyRule( Set prefixes) { return new PrefixSearchRule(prefixes, u -> u.isCoherent() && !u.getName().equals("kilogram")); } /** * Gets a rule that applies the provided prefixes to all units. * * @param prefixes prefixes to apply * @return prefix rule * @since 2022-07-06 */ public static final PrefixSearchRule getUniversalRule( Set prefixes) { return new PrefixSearchRule(prefixes, u -> true); } /** * The set of prefixes that will be applied to the unit. */ private final Set prefixes; /** * Determines which units are given prefixes. */ private final Predicate allowUnit; /** * @param prefixes * @param metricOnly * @since 2022-07-06 */ public PrefixSearchRule(Set prefixes, Predicate allowUnit) { this.prefixes = Collections.unmodifiableSet(new HashSet<>(prefixes)); this.allowUnit = allowUnit; } @Override public Map apply(Entry t) { final Map outputUnits = new HashMap<>(); final String originalName = t.getKey(); final LinearUnit originalUnit = t.getValue(); outputUnits.put(originalName, originalUnit); if (this.allowUnit.test(originalUnit)) { for (final UnitPrefix prefix : this.prefixes) { outputUnits.put(prefix.getName() + originalName, originalUnit.withPrefix(prefix)); } } return outputUnits; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof PrefixSearchRule)) return false; final PrefixSearchRule other = (PrefixSearchRule) obj; if (this.allowUnit == null) { if (other.allowUnit != null) return false; } else if (!this.allowUnit.equals(other.allowUnit)) return false; if (this.prefixes == null) { if (other.prefixes != null) return false; } else if (!this.prefixes.equals(other.prefixes)) return false; return true; } /** * @return the allowUnit * @since 2022-07-06 */ public Predicate getAllowUnit() { return this.allowUnit; } /** * @return the prefixes that are applied by this rule * @since 2022-07-06 */ public Set getPrefixes() { return this.prefixes; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (this.allowUnit == null ? 0 : this.allowUnit.hashCode()); result = prime * result + (this.prefixes == null ? 0 : this.prefixes.hashCode()); return result; } @Override public String toString() { return "Apply the following prefixes: " + this.prefixes; } }