1 // © 2022 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 package com.ibm.icu.message2; 5 6 import java.util.HashMap; 7 import java.util.Map; 8 import java.util.Set; 9 10 /** 11 * This class is used to register mappings between various function 12 * names and the factories that can create those functions. 13 * 14 * <p>For example to add formatting for a {@code Person} object one would need to:</p> 15 * <ul> 16 * <li>write a function (class, lambda, etc.) that does the formatting proper 17 * (implementing {@link Formatter})</li> 18 * <li>write a factory that creates such a function 19 * (implementing {@link FormatterFactory})</li> 20 * <li>add a mapping from the function name as used in the syntax 21 * (for example {@code "person"}) to the factory</li> 22 * <li>optionally add a mapping from the class to format ({@code ...Person.class}) to 23 * the formatter name ({@code "person"}), so that one can use a placeholder in the message 24 * without specifying a function (for example {@code "... {$me} ..."} instead of 25 * {@code "... {$me :person} ..."}, if the class of {@code $me} is an {@code instanceof Person}). 26 * </li> 27 * </ul> 28 * 29 * @internal ICU 72 technology preview 30 * @deprecated This API is for technology preview only. 31 */ 32 @Deprecated 33 public class Mf2FunctionRegistry { 34 private final Map<String, FormatterFactory> formattersMap; 35 private final Map<String, SelectorFactory> selectorsMap; 36 private final Map<Class<?>, String> classToFormatter; 37 Mf2FunctionRegistry(Builder builder)38 private Mf2FunctionRegistry(Builder builder) { 39 this.formattersMap = new HashMap<>(builder.formattersMap); 40 this.selectorsMap = new HashMap<>(builder.selectorsMap); 41 this.classToFormatter = new HashMap<>(builder.classToFormatter); 42 } 43 44 /** 45 * Creates a builder. 46 * 47 * @return the Builder. 48 * 49 * @internal ICU 72 technology preview 50 * @deprecated This API is for technology preview only. 51 */ 52 @Deprecated builder()53 public static Builder builder() { 54 return new Builder(); 55 } 56 57 /** 58 * Returns the formatter factory used to create the formatter for function 59 * named {@code name}. 60 * 61 * <p>Note: function name here means the name used to refer to the function in the 62 * MessageFormat 2 syntax, for example {@code "... {$exp :datetime} ..."}<br> 63 * The function name here is {@code "datetime"}, and does not have to correspond to the 64 * name of the methods / classes used to implement the functionality.</p> 65 * 66 * <p>For example one might write a {@code PersonFormatterFactory} returning a {@code PersonFormatter}, 67 * and map that to the MessageFormat function named {@code "person"}.<br> 68 * The only name visible to the users of MessageFormat syntax will be {@code "person"}.</p> 69 * 70 * @param formatterName the function name. 71 * @return the factory creating formatters for {@code name}. Returns {@code null} if none is registered. 72 * 73 * @internal ICU 72 technology preview 74 * @deprecated This API is for technology preview only. 75 */ 76 @Deprecated getFormatter(String formatterName)77 public FormatterFactory getFormatter(String formatterName) { 78 return formattersMap.get(formatterName); 79 } 80 81 /** 82 * Get all know names that have a mappings from name to {@link FormatterFactory}. 83 * 84 * @return a set of all the known formatter names. 85 * 86 * @internal ICU 72 technology preview 87 * @deprecated This API is for technology preview only. 88 */ 89 @Deprecated getFormatterNames()90 public Set<String> getFormatterNames() { 91 return formattersMap.keySet(); 92 } 93 94 /** 95 * Returns the name of the formatter used to format an object of type {@code clazz}. 96 * 97 * @param clazz the class of the object to format. 98 * @return the name of the formatter class, if registered. Returns {@code null} otherwise. 99 * 100 * @internal ICU 72 technology preview 101 * @deprecated This API is for technology preview only. 102 */ 103 @Deprecated getDefaultFormatterNameForType(Class<?> clazz)104 public String getDefaultFormatterNameForType(Class<?> clazz) { 105 // Search for the class "as is", to save time. 106 // If we don't find it then we iterate the registered classes and check 107 // if the class is an instanceof the ones registered. 108 // For example a BuddhistCalendar when we only registered Calendar 109 String result = classToFormatter.get(clazz); 110 if (result != null) { 111 return result; 112 } 113 // We didn't find the class registered explicitly "as is" 114 for (Map.Entry<Class<?>, String> e : classToFormatter.entrySet()) { 115 if (e.getKey().isAssignableFrom(clazz)) { 116 return e.getValue(); 117 } 118 } 119 return null; 120 } 121 122 /** 123 * Get all know classes that have a mappings from class to function name. 124 * 125 * @return a set of all the known classes that have mapping to function names. 126 * 127 * @internal ICU 72 technology preview 128 * @deprecated This API is for technology preview only. 129 */ 130 @Deprecated getDefaultFormatterTypes()131 public Set<Class<?>> getDefaultFormatterTypes() { 132 return classToFormatter.keySet(); 133 } 134 135 /** 136 * Returns the selector factory used to create the selector for function 137 * named {@code name}. 138 * 139 * <p>Note: the same comments about naming as the ones on {@code getFormatter} apply.</p> 140 * 141 * @param selectorName the selector name. 142 * @return the factory creating selectors for {@code name}. Returns {@code null} if none is registered. 143 * @see #getFormatter(String) 144 * 145 * @internal ICU 72 technology preview 146 * @deprecated This API is for technology preview only. 147 */ 148 @Deprecated getSelector(String selectorName)149 public SelectorFactory getSelector(String selectorName) { 150 return selectorsMap.get(selectorName); 151 } 152 153 /** 154 * Get all know names that have a mappings from name to {@link SelectorFactory}. 155 * 156 * @return a set of all the known selector names. 157 * 158 * @internal ICU 72 technology preview 159 * @deprecated This API is for technology preview only. 160 */ 161 @Deprecated getSelectorNames()162 public Set<String> getSelectorNames() { 163 return selectorsMap.keySet(); 164 } 165 166 /** 167 * A {@code Builder} used to build instances of {@link Mf2FunctionRegistry}. 168 * 169 * @internal ICU 72 technology preview 170 * @deprecated This API is for technology preview only. 171 */ 172 @Deprecated 173 public static class Builder { 174 private final Map<String, FormatterFactory> formattersMap = new HashMap<>(); 175 private final Map<String, SelectorFactory> selectorsMap = new HashMap<>(); 176 private final Map<Class<?>, String> classToFormatter = new HashMap<>(); 177 178 // Prevent direct creation Builder()179 private Builder() { 180 } 181 182 /** 183 * Adds all the mapping from another registry to this one. 184 * 185 * @param functionRegistry the registry to copy from. 186 * @return the builder, for fluent use. 187 * 188 * @internal ICU 72 technology preview 189 * @deprecated This API is for technology preview only. 190 */ 191 @Deprecated addAll(Mf2FunctionRegistry functionRegistry)192 public Builder addAll(Mf2FunctionRegistry functionRegistry) { 193 formattersMap.putAll(functionRegistry.formattersMap); 194 selectorsMap.putAll(functionRegistry.selectorsMap); 195 classToFormatter.putAll(functionRegistry.classToFormatter); 196 return this; 197 } 198 199 /** 200 * Adds a mapping from a formatter name to a {@link FormatterFactory} 201 * 202 * @param formatterName the function name (as used in the MessageFormat 2 syntax). 203 * @param formatterFactory the factory that handles the name. 204 * @return the builder, for fluent use. 205 * 206 * @internal ICU 72 technology preview 207 * @deprecated This API is for technology preview only. 208 */ 209 @Deprecated setFormatter(String formatterName, FormatterFactory formatterFactory)210 public Builder setFormatter(String formatterName, FormatterFactory formatterFactory) { 211 formattersMap.put(formatterName, formatterFactory); 212 return this; 213 } 214 215 /** 216 * Remove the formatter associated with the name. 217 * 218 * @param formatterName the name of the formatter to remove. 219 * @return the builder, for fluent use. 220 * 221 * @internal ICU 72 technology preview 222 * @deprecated This API is for technology preview only. 223 */ 224 @Deprecated removeFormatter(String formatterName)225 public Builder removeFormatter(String formatterName) { 226 formattersMap.remove(formatterName); 227 return this; 228 } 229 230 /** 231 * Remove all the formatter mappings. 232 * 233 * @return the builder, for fluent use. 234 * 235 * @internal ICU 72 technology preview 236 * @deprecated This API is for technology preview only. 237 */ 238 @Deprecated clearFormatters()239 public Builder clearFormatters() { 240 formattersMap.clear(); 241 return this; 242 } 243 244 /** 245 * Adds a mapping from a type to format to a {@link FormatterFactory} formatter name. 246 * 247 * @param clazz the class of the type to format. 248 * @param formatterName the formatter name (as used in the MessageFormat 2 syntax). 249 * @return the builder, for fluent use. 250 * 251 * @internal ICU 72 technology preview 252 * @deprecated This API is for technology preview only. 253 */ 254 @Deprecated setDefaultFormatterNameForType(Class<?> clazz, String formatterName)255 public Builder setDefaultFormatterNameForType(Class<?> clazz, String formatterName) { 256 classToFormatter.put(clazz, formatterName); 257 return this; 258 } 259 260 /** 261 * Remove the function name associated with the class. 262 * 263 * @param clazz the class to remove the mapping for. 264 * @return the builder, for fluent use. 265 * 266 * @internal ICU 72 technology preview 267 * @deprecated This API is for technology preview only. 268 */ 269 @Deprecated removeDefaultFormatterNameForType(Class<?> clazz)270 public Builder removeDefaultFormatterNameForType(Class<?> clazz) { 271 classToFormatter.remove(clazz); 272 return this; 273 } 274 275 /** 276 * Remove all the class to formatter-names mappings. 277 * 278 * @return the builder, for fluent use. 279 * 280 * @internal ICU 72 technology preview 281 * @deprecated This API is for technology preview only. 282 */ 283 @Deprecated clearDefaultFormatterNames()284 public Builder clearDefaultFormatterNames() { 285 classToFormatter.clear(); 286 return this; 287 } 288 289 /** 290 * Adds a mapping from a selector name to a {@link SelectorFactory} 291 * 292 * @param selectorName the function name (as used in the MessageFormat 2 syntax). 293 * @param selectorFactory the factory that handles the name. 294 * @return the builder, for fluent use. 295 * 296 * @internal ICU 72 technology preview 297 * @deprecated This API is for technology preview only. 298 */ 299 @Deprecated setSelector(String selectorName, SelectorFactory selectorFactory)300 public Builder setSelector(String selectorName, SelectorFactory selectorFactory) { 301 selectorsMap.put(selectorName, selectorFactory); 302 return this; 303 } 304 305 /** 306 * Remove the selector associated with the name. 307 * 308 * @param selectorName the name of the selector to remove. 309 * @return the builder, for fluent use. 310 * 311 * @internal ICU 72 technology preview 312 * @deprecated This API is for technology preview only. 313 */ 314 @Deprecated removeSelector(String selectorName)315 public Builder removeSelector(String selectorName) { 316 selectorsMap.remove(selectorName); 317 return this; 318 } 319 320 /** 321 * Remove all the selector mappings. 322 * 323 * @return the builder, for fluent use. 324 * 325 * @internal ICU 72 technology preview 326 * @deprecated This API is for technology preview only. 327 */ 328 @Deprecated clearSelectors()329 public Builder clearSelectors() { 330 selectorsMap.clear(); 331 return this; 332 } 333 334 /** 335 * Builds an instance of {@link Mf2FunctionRegistry}. 336 * 337 * @return the function registry created. 338 * 339 * @internal ICU 72 technology preview 340 * @deprecated This API is for technology preview only. 341 */ 342 @Deprecated build()343 public Mf2FunctionRegistry build() { 344 return new Mf2FunctionRegistry(this); 345 } 346 } 347 } 348