1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.schemagen.datatype;
7   
8   import java.util.Collections;
9   import java.util.HashSet;
10  import java.util.LinkedHashMap;
11  import java.util.Map;
12  import java.util.Set;
13  import java.util.concurrent.ConcurrentHashMap;
14  
15  import dev.metaschema.core.datatype.IDataTypeAdapter;
16  import edu.umd.cs.findbugs.annotations.NonNull;
17  
18  /**
19   * Provides a common base implementation for datatype management during schema
20   * generation.
21   * <p>
22   * This class maintains a mapping between Metaschema data type adapters and
23   * their corresponding schema type names, handling the translation from
24   * Metaschema datatype names to format-specific type names.
25   */
26  public abstract class AbstractDatatypeManager implements IDatatypeManager {
27    @NonNull
28    private static final Map<String, String> DATATYPE_TRANSLATION_MAP = new LinkedHashMap<>();
29  
30    static {
31      DATATYPE_TRANSLATION_MAP.put("base64", "Base64Datatype");
32      DATATYPE_TRANSLATION_MAP.put("boolean", "BooleanDatatype");
33      DATATYPE_TRANSLATION_MAP.put("date", "DateDatatype");
34      DATATYPE_TRANSLATION_MAP.put("date-with-timezone", "DateWithTimezoneDatatype");
35      DATATYPE_TRANSLATION_MAP.put("date-time", "DateTimeDatatype");
36      DATATYPE_TRANSLATION_MAP.put("date-time-with-timezone", "DateTimeWithTimezoneDatatype");
37      DATATYPE_TRANSLATION_MAP.put("day-time-duration", "DayTimeDurationDatatype");
38      DATATYPE_TRANSLATION_MAP.put("decimal", "DecimalDatatype");
39      DATATYPE_TRANSLATION_MAP.put("email-address", "EmailAddressDatatype");
40      DATATYPE_TRANSLATION_MAP.put("hostname", "HostnameDatatype");
41      DATATYPE_TRANSLATION_MAP.put("integer", "IntegerDatatype");
42      DATATYPE_TRANSLATION_MAP.put("ip-v4-address", "IPV4AddressDatatype");
43      DATATYPE_TRANSLATION_MAP.put("ip-v6-address", "IPV6AddressDatatype");
44      DATATYPE_TRANSLATION_MAP.put("markup-line", "MarkupLineDatatype");
45      DATATYPE_TRANSLATION_MAP.put("markup-multiline", "MarkupMultilineDatatype");
46      DATATYPE_TRANSLATION_MAP.put("non-negative-integer", "NonNegativeIntegerDatatype");
47      DATATYPE_TRANSLATION_MAP.put("positive-integer", "PositiveIntegerDatatype");
48      DATATYPE_TRANSLATION_MAP.put("string", "StringDatatype");
49      DATATYPE_TRANSLATION_MAP.put("token", "TokenDatatype");
50      DATATYPE_TRANSLATION_MAP.put("uri", "URIDatatype");
51      DATATYPE_TRANSLATION_MAP.put("uri-reference", "URIReferenceDatatype");
52      DATATYPE_TRANSLATION_MAP.put("uuid", "UUIDDatatype");
53      DATATYPE_TRANSLATION_MAP.put("year-month-duration", "YearMonthDurationDatatype");
54    }
55  
56    @NonNull
57    private final Map<IDataTypeAdapter<?>, String> datatypeToTypeMap = new ConcurrentHashMap<>();
58  
59    /**
60     * Get the mapping of Metaschema datatype names to schema type names.
61     *
62     * @return an unmodifiable map of datatype name translations
63     */
64    @SuppressWarnings("null")
65    @NonNull
66    protected static Map<String, String> getDatatypeTranslationMap() {
67      return Collections.unmodifiableMap(DATATYPE_TRANSLATION_MAP);
68    }
69  
70    @Override
71    public Set<String> getUsedTypes() {
72      return new HashSet<>(datatypeToTypeMap.values());
73    }
74  
75    @SuppressWarnings("null")
76    @Override
77    @NonNull
78    public String getTypeNameForDatatype(@NonNull IDataTypeAdapter<?> datatype) {
79      return datatypeToTypeMap.computeIfAbsent(
80          datatype,
81          key -> getDatatypeTranslationMap().get(key.getPreferredName().getLocalName()));
82    }
83  }