1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.databind.model.impl;
7   
8   import java.util.Arrays;
9   import java.util.LinkedHashMap;
10  import java.util.Map;
11  import java.util.Set;
12  import java.util.stream.Collectors;
13  
14  import dev.metaschema.core.datatype.markup.MarkupLine;
15  import dev.metaschema.core.datatype.markup.MarkupMultiline;
16  import dev.metaschema.core.model.AbstractAssemblyInstance;
17  import dev.metaschema.core.model.IAttributable;
18  import dev.metaschema.core.model.IBoundObject;
19  import dev.metaschema.core.util.CollectionUtil;
20  import dev.metaschema.core.util.ObjectUtils;
21  import dev.metaschema.databind.model.IBoundDefinitionModelAssembly;
22  import dev.metaschema.databind.model.IBoundInstanceModelChoiceGroup;
23  import dev.metaschema.databind.model.IBoundInstanceModelGroupedAssembly;
24  import dev.metaschema.databind.model.IBoundProperty;
25  import dev.metaschema.databind.model.annotations.BoundGroupedAssembly;
26  import dev.metaschema.databind.model.annotations.ModelUtil;
27  import edu.umd.cs.findbugs.annotations.NonNull;
28  import nl.talsmasoftware.lazy4j.Lazy;
29  
30  /**
31   * Represents an assembly model instance that is a member of a choice group
32   * instance.
33   */
34  /**
35   * Implementation of an assembly instance within a choice group.
36   * <p>
37   * This class represents an assembly that is a member of a choice group,
38   * allowing polymorphic model content.
39   */
40  public class InstanceModelGroupedAssembly
41      extends AbstractAssemblyInstance<
42          IBoundInstanceModelChoiceGroup,
43          IBoundDefinitionModelAssembly,
44          IBoundInstanceModelGroupedAssembly,
45          IBoundDefinitionModelAssembly>
46      implements IBoundInstanceModelGroupedAssembly {
47    @NonNull
48    private final BoundGroupedAssembly annotation;
49    @NonNull
50    private final IBoundDefinitionModelAssembly definition;
51    @NonNull
52    private final Lazy<Map<String, IBoundProperty<?>>> jsonProperties;
53    @NonNull
54    private final Lazy<Map<IAttributable.Key, Set<String>>> properties;
55  
56    /**
57     * Construct a new assembly model instance instance that is a member of a choice
58     * group instance.
59     *
60     * @param annotation
61     *          the Java annotation the instance is bound to
62     * @param definition
63     *          the assembly definition this instance is bound to
64     * @param container
65     *          the choice group instance containing the instance
66     */
67    public InstanceModelGroupedAssembly(
68        @NonNull BoundGroupedAssembly annotation,
69        @NonNull IBoundDefinitionModelAssembly definition,
70        @NonNull IBoundInstanceModelChoiceGroup container) {
71      super(container);
72      this.annotation = annotation;
73      this.definition = definition;
74      // IBoundInstanceFlag jsonKey = getEffectiveJsonKey();
75      // Predicate<IBoundInstanceFlag> flagFilter = jsonKey == null ? null : (flag) ->
76      // !jsonKey.equals(flag);
77      // return getDefinition().getJsonProperties(flagFilter);
78      this.jsonProperties = ObjectUtils.notNull(Lazy.of(() -> getDefinition().getJsonProperties(null)));
79      this.properties = ObjectUtils.notNull(
80          Lazy.of(() -> CollectionUtil.unmodifiableMap(ObjectUtils.notNull(
81              Arrays.stream(annotation.properties())
82                  .map(ModelUtil::toPropertyEntry)
83                  .collect(
84                      Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v2, LinkedHashMap::new))))));
85    }
86  
87    private BoundGroupedAssembly getAnnotation() {
88      return annotation;
89    }
90  
91    // ------------------------------------------
92    // - Start annotation driven code - CPD-OFF -
93    // ------------------------------------------
94  
95    @Override
96    public Class<? extends IBoundObject> getBoundClass() {
97      return getAnnotation().binding();
98    }
99  
100   @Override
101   public Map<String, IBoundProperty<?>> getJsonProperties() {
102     return ObjectUtils.notNull(jsonProperties.get());
103   }
104 
105   @Override
106   public IBoundDefinitionModelAssembly getDefinition() {
107     return definition;
108   }
109 
110   @Override
111   public String getFormalName() {
112     return ModelUtil.resolveNoneOrValue(getAnnotation().formalName());
113   }
114 
115   @Override
116   public MarkupLine getDescription() {
117     return ModelUtil.resolveToMarkupLine(getAnnotation().description());
118   }
119 
120   @Override
121   public Map<Key, Set<String>> getProperties() {
122     return ObjectUtils.notNull(properties.get());
123   }
124 
125   @Override
126   public MarkupMultiline getRemarks() {
127     return ModelUtil.resolveToMarkupMultiline(getAnnotation().remarks());
128   }
129 
130   @Override
131   public String getDiscriminatorValue() {
132     return ModelUtil.resolveNoneOrValue(getAnnotation().discriminatorValue());
133   }
134 
135   @Override
136   public String getUseName() {
137     return ModelUtil.resolveNoneOrValue(getAnnotation().useName());
138   }
139 
140   @Override
141   public Integer getUseIndex() {
142     return ModelUtil.resolveDefaultInteger(getAnnotation().useIndex());
143   }
144 }