1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.schemagen.json.impl.builder;
7   
8   import com.fasterxml.jackson.databind.node.ArrayNode;
9   import com.fasterxml.jackson.databind.node.ObjectNode;
10  
11  import gov.nist.secauto.metaschema.core.model.IGroupable;
12  import gov.nist.secauto.metaschema.core.model.INamedModelInstanceAbsolute;
13  import gov.nist.secauto.metaschema.core.model.INamedModelInstanceGrouped;
14  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
15  import gov.nist.secauto.metaschema.schemagen.json.IJsonGenerationState;
16  
17  import java.util.List;
18  
19  public class SingletonOrListBuilder implements IModelInstanceBuilder<SingletonOrListBuilder> {
20    private int minOccurrence = IGroupable.DEFAULT_GROUP_AS_MIN_OCCURS;
21    private final ArrayBuilder arrayBuilder;
22    private final SingletonBuilder singletonBuilder;
23  
24    public SingletonOrListBuilder() {
25      this.arrayBuilder = new ArrayBuilder();
26      // the array must minimally have 2 items or else the singleton will be used
27      this.arrayBuilder.minItems(2);
28      this.singletonBuilder = new SingletonBuilder();
29    }
30  
31    @Override
32    public List<IType> getTypes() {
33      return arrayBuilder.getTypes();
34    }
35  
36    @Override
37    public SingletonOrListBuilder addItemType(INamedModelInstanceGrouped itemType) {
38      arrayBuilder.addItemType(itemType);
39      singletonBuilder.addItemType(itemType);
40      return this;
41    }
42  
43    @Override
44    public SingletonOrListBuilder addItemType(INamedModelInstanceAbsolute itemType) {
45      arrayBuilder.addItemType(itemType);
46      singletonBuilder.addItemType(itemType);
47      return this;
48    }
49  
50    @Override
51    public void build(
52        ObjectNode object,
53        IJsonGenerationState state) {
54      ArrayNode oneOf = object.putArray("oneOf");
55      singletonBuilder.build(ObjectUtils.notNull(oneOf.addObject()), state);
56      arrayBuilder.build(ObjectUtils.notNull(oneOf.addObject()), state);
57    }
58  
59    @Override
60    public SingletonOrListBuilder minItems(int min) {
61      this.minOccurrence = min;
62      arrayBuilder.minItems(Integer.max(2, min));
63      if (min > 0) {
64        singletonBuilder.minItems(1);
65      }
66      return this;
67    }
68  
69    @Override
70    public SingletonOrListBuilder maxItems(int max) {
71      arrayBuilder.maxItems(max);
72      return this;
73    }
74  
75    @Override
76    public int getMinOccurrence() {
77      return minOccurrence;
78    }
79  
80    @Override
81    public int getMaxOccurrence() {
82      return arrayBuilder.getMaxOccurrence();
83    }
84  
85  }