/** * Copyright (C) 2019 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 org.unitConverter.unit; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Objects; import java.util.Optional; import java.util.Set; /** * A class that can be used to specify names and a symbol for a unit. * * @author Adrien Hopkins * @since 2019-10-21 */ public final class NameSymbol { public static final NameSymbol EMPTY = new NameSymbol(Optional.empty(), Optional.empty(), new HashSet<>()); /** * Gets a {@code NameSymbol} with a primary name, a symbol and no other names. * * @param name name to use * @param symbol symbol to use * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if name or symbol is null */ public static final NameSymbol of(final String name, final String symbol) { return new NameSymbol(Optional.of(name), Optional.of(symbol), new HashSet<>()); } /** * Gets a {@code NameSymbol} with a primary name, a symbol and additional names. * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if any argument is null */ public static final NameSymbol of(final String name, final String symbol, final Set otherNames) { return new NameSymbol(Optional.of(name), Optional.of(symbol), new HashSet<>(Objects.requireNonNull(otherNames, "otherNames must not be null."))); } /** * h * Gets a {@code NameSymbol} with a primary name, a symbol and additional * names. * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if any argument is null */ public static final NameSymbol of(final String name, final String symbol, final String... otherNames) { return new NameSymbol(Optional.of(name), Optional.of(symbol), new HashSet<>(Arrays.asList(Objects.requireNonNull(otherNames, "otherNames must not be null.")))); } /** * Gets a {@code NameSymbol} with a primary name, a symbol and an additional * name. * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @param name2 alternate name * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if any argument is null */ public static final NameSymbol of(final String name, final String symbol, final String name2) { final Set otherNames = new HashSet<>(); otherNames.add(Objects.requireNonNull(name2, "name2 must not be null.")); return new NameSymbol(Optional.of(name), Optional.of(symbol), otherNames); } /** * Gets a {@code NameSymbol} with a primary name, a symbol and additional names. * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @param name2 alternate name * @param name3 alternate name * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if any argument is null */ public static final NameSymbol of(final String name, final String symbol, final String name2, final String name3) { final Set otherNames = new HashSet<>(); otherNames.add(Objects.requireNonNull(name2, "name2 must not be null.")); otherNames.add(Objects.requireNonNull(name3, "name3 must not be null.")); return new NameSymbol(Optional.of(name), Optional.of(symbol), otherNames); } /** * Gets a {@code NameSymbol} with a primary name, a symbol and additional names. * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @param name2 alternate name * @param name3 alternate name * @param name4 alternate name * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if any argument is null */ public static final NameSymbol of(final String name, final String symbol, final String name2, final String name3, final String name4) { final Set otherNames = new HashSet<>(); otherNames.add(Objects.requireNonNull(name2, "name2 must not be null.")); otherNames.add(Objects.requireNonNull(name3, "name3 must not be null.")); otherNames.add(Objects.requireNonNull(name4, "name4 must not be null.")); return new NameSymbol(Optional.of(name), Optional.of(symbol), otherNames); } /** * Gets a {@code NameSymbol} with a primary name, no symbol, and no other names. * * @param name name to use * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if name is null */ public static final NameSymbol ofName(final String name) { return new NameSymbol(Optional.of(name), Optional.empty(), new HashSet<>()); } /** * Gets a {@code NameSymbol} with a primary name, a symbol and additional names. *

* If any argument is null, this static factory replaces it with an empty * Optional or empty Set. *

* If {@code name} is null and {@code otherNames} is not empty, a primary name * will be picked from {@code otherNames}. This name will not appear in * getOtherNames(). * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @return NameSymbol instance * @since 2019-11-26 */ public static final NameSymbol ofNullable(final String name, final String symbol, final Set otherNames) { return NameSymbol.create(name, symbol, otherNames == null ? new HashSet<>() : new HashSet<>(otherNames)); } /** * Creates a {@code NameSymbol}, ensuring that if primaryName is null and * otherNames is not empty, one name is moved from otherNames to primaryName * * Ensure that otherNames is a copy of the inputted argument. */ private static final NameSymbol create(final String name, final String symbol, final Set otherNames) { final Optional primaryName; if (name == null && !otherNames.isEmpty()) { // get primary name and remove it from savedNames Iterator it = otherNames.iterator(); assert it.hasNext(); primaryName = Optional.of(it.next()); otherNames.remove(primaryName.get()); } else { primaryName = Optional.ofNullable(name); } return new NameSymbol(primaryName, Optional.ofNullable(symbol), otherNames); } /** * h * Gets a {@code NameSymbol} with a primary name, a symbol and additional * names. *

* If any argument is null, this static factory replaces it with an empty * Optional or empty Set. *

* If {@code name} is null and {@code otherNames} is not empty, a primary name * will be picked from {@code otherNames}. This name will not appear in * getOtherNames(). * * @param name name to use * @param symbol symbol to use * @param otherNames other names to use * @return NameSymbol instance * @since 2019-11-26 */ public static final NameSymbol ofNullable(final String name, final String symbol, final String... otherNames) { return create(name, symbol, otherNames == null ? new HashSet<>() : new HashSet<>(Arrays.asList(otherNames))); } /** * Gets a {@code NameSymbol} with a symbol and no names. * * @param symbol symbol to use * @return NameSymbol instance * @since 2019-10-21 * @throws NullPointerException if symbol is null */ public static final NameSymbol ofSymbol(final String symbol) { return new NameSymbol(Optional.empty(), Optional.of(symbol), new HashSet<>()); } private final Optional primaryName; private final Optional symbol; private final Set otherNames; /** * Creates the {@code NameSymbol}. * * @param primaryName primary name of unit * @param symbol symbol used to represent unit * @param otherNames other names and/or spellings, should be a mutable copy of * the argument * @since 2019-10-21 */ private NameSymbol(final Optional primaryName, final Optional symbol, final Set otherNames) { this.primaryName = primaryName; this.symbol = symbol; otherNames.remove(null); this.otherNames = Collections.unmodifiableSet(otherNames); } /** * @return otherNames * @since 2019-10-21 */ public final Set getOtherNames() { return this.otherNames; } /** * @return primaryName * @since 2019-10-21 */ public final Optional getPrimaryName() { return this.primaryName; } /** * @return symbol * @since 2019-10-21 */ public final Optional getSymbol() { return this.symbol; } }