// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.turnrestrictions.editor; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; /** * ExceptValueModel is a model for the value of the tag 'except' in a turn * restriction. * */ public class ExceptValueModel { /** * The set of standard vehicle types which can be used in the * 'except' tag */ public static final Set<String> STANDARD_VEHICLE_EXCEPTION_VALUES; static { HashSet<String> s = new HashSet<>(); s.add("psv"); s.add("hgv"); s.add("bicycle"); s.add("moped"); s.add("motorcar"); STANDARD_VEHICLE_EXCEPTION_VALUES = Collections.unmodifiableSet(s); } /** * Replies true, if {@code v} is a standard vehicle type. Replies * false if {@code v} is null * * @param v the vehicle type. * @return true, if {@code v} is a standard vehicle type. */ public static boolean isStandardVehicleExceptionValue(String v) { if (v == null) return false; v = v.trim().toLowerCase(); return STANDARD_VEHICLE_EXCEPTION_VALUES.contains(v); } private String value = ""; private boolean isStandard = true; private final Set<String> vehicleExceptions = new HashSet<>(); protected void parseValue(String value) { if (value == null || value.trim().equals("")) value = ""; this.value = value; isStandard = true; vehicleExceptions.clear(); if (value.equals("")) return; String[] values = value.split(";"); for (String v: values) { v = v.trim().toLowerCase(); if (isStandardVehicleExceptionValue(v)) { vehicleExceptions.add(v); } else { isStandard = false; } } } /** * Creates a new model for an empty standard value */ public ExceptValueModel() {} /** * Creates a new model for the tag value {@code value}. * * @param value the tag value * @see #parseValue(String) */ public ExceptValueModel(String value) { if (value == null || value.trim().equals("")) return; parseValue(value); } /** * Replies the tag value representing the state of this model. */ public String getValue() { if (isStandard) { StringBuffer sb = new StringBuffer(); // we use an ordered list because equals() // is based on getValue() // List<String> values = new ArrayList<>(vehicleExceptions); Collections.sort(values); for (String v: values) { if (sb.length() > 0) { sb.append(";"); } sb.append(v); } return sb.toString(); } else { return value; } } /** * Sets the value in this model */ public void setValue(String value) { parseValue(value); } /** * Replies true if this model currently holds a standard 'except' value */ public boolean isStandard() { return isStandard; } /** * Tells this model to use standard values only. * */ public void setStandard(boolean isStandard) { this.isStandard = isStandard; } /** * Replies true if {@code vehicleType} is currently set as exception in this * model. * * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} * @return true if {@code vehicleType} is currently set as exception in this * model. * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type */ public boolean isVehicleException(String vehicleType) throws IllegalArgumentException { if (vehicleType == null) return false; if (!isStandardVehicleExceptionValue(vehicleType)) { throw new IllegalArgumentException(MessageFormat.format("vehicleType ''{0}'' isn''t a valid standard vehicle type", vehicleType)); } vehicleType = vehicleType.trim().toLowerCase(); return vehicleExceptions.contains(vehicleType); } /** * Sets the {@code vehicleType} as exception in this turn restriction. * * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type */ public void setVehicleException(String vehicleType) throws IllegalArgumentException { if (!isStandardVehicleExceptionValue(vehicleType)) { throw new IllegalArgumentException(MessageFormat.format("vehicleType ''{0}'' isn''t a valid standard vehicle type", vehicleType)); } vehicleExceptions.add(vehicleType.trim().toLowerCase()); } /** * Sets or removes the {@code vehicleType} as exception in this turn restriction, depending * on whether {@code setOrRemove} is true or false, respectively. * * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} * @param setOrRemove if true, the exception is set; otherwise, it is removed * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type */ public void setVehicleException(String vehicleType, boolean setOrRemove) throws IllegalArgumentException { if (setOrRemove) { setVehicleException(vehicleType); } else { removeVehicleException(vehicleType); } } /** * Removes the {@code vehicleType} as exception in this turn restriction * * @param vehicleType one of the standard vehicle types from {@see #STANDARD_VEHICLE_EXCEPTION_VALUES} * @exception IllegalArgumentException thrown if {@code vehicleType} isn't a standard vehicle type */ public void removeVehicleException(String vehicleType) throws IllegalArgumentException { if (!isStandardVehicleExceptionValue(vehicleType)) { throw new IllegalArgumentException(MessageFormat.format("vehicleType ''{0}'' isn''t a valid standard vehicle type", vehicleType)); } vehicleExceptions.remove(vehicleType.trim().toLowerCase()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + getValue().hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ExceptValueModel other = (ExceptValueModel) obj; return getValue().equals(other.getValue()); } }