001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.mappaint; 003 004import java.util.function.BiFunction; 005 006import org.openstreetmap.josm.data.preferences.BooleanProperty; 007import org.openstreetmap.josm.data.preferences.DoubleProperty; 008import org.openstreetmap.josm.data.preferences.StringProperty; 009import org.openstreetmap.josm.tools.Logging; 010 011/** 012 * Factory to create matching {@link StyleSetting} instances. 013 * @since 15731 014 */ 015public final class StyleSettingFactory { 016 017 private StyleSettingFactory() { 018 // private constructor for factory classes 019 } 020 021 /** 022 * Creates a new {@code StyleSetting} based on the specified type by {@code c}. 023 * The type must be supported by {@link Cascade#convertTo} as well as {@link org.openstreetmap.josm.data.preferences.AbstractProperty}. 024 * @param c cascade 025 * @param parentStyle parent style source 026 * @param key setting identifier 027 * @return newly created {@code StyleSetting} 028 */ 029 public static StyleSetting create(Cascade c, StyleSource parentStyle, String key) { 030 final String type = c.get("type", null, String.class); 031 final String qualifiedKey = String.join(":", parentStyle.url, type, key); 032 switch (type) { 033 case "boolean": 034 return forLabelAndDefault(c, Boolean.class, (label, defaultValue) -> { 035 final BooleanProperty property = new BooleanProperty(qualifiedKey, defaultValue); 036 return new StyleSetting.BooleanStyleSetting(parentStyle, label, property); 037 }); 038 case "double": 039 return forLabelAndDefault(c, Double.class, (label, defaultValue) -> { 040 final DoubleProperty property = new DoubleProperty(qualifiedKey, defaultValue); 041 return new StyleSetting.PropertyStyleSetting<>(parentStyle, label, Double.class, property); 042 }); 043 case "string": 044 return forLabelAndDefault(c, String.class, (label, defaultValue) -> { 045 final StringProperty property = new StringProperty(qualifiedKey, defaultValue); 046 return new StyleSetting.PropertyStyleSetting<>(parentStyle, label, String.class, property); 047 }); 048 default: 049 Logging.warn("Unknown setting type {0} for style {1}", type, parentStyle.url); 050 return null; 051 } 052 } 053 054 private static <T> StyleSetting forLabelAndDefault(Cascade c, final Class<T> type, BiFunction<String, T, StyleSetting> function) { 055 String label = c.get("label", null, String.class); 056 if (label == null) { 057 Logging.warn("property 'label' required for style setting of type " + type); 058 return null; 059 } 060 T defaultValue = c.get("default", null, type); 061 if (defaultValue == null) { 062 Logging.warn("property 'default' required for style setting of type " + type); 063 return null; 064 } 065 return function.apply(label, defaultValue); 066 } 067}