001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.core.model; 007 008import java.util.LinkedHashMap; 009import java.util.LinkedList; 010import java.util.List; 011import java.util.Map; 012 013import dev.metaschema.core.model.impl.DefaultContainerModelAssemblySupport; 014import dev.metaschema.core.util.CollectionUtil; 015import edu.umd.cs.findbugs.annotations.NonNull; 016import edu.umd.cs.findbugs.annotations.Nullable; 017 018/** 019 * An assembly model builder. 020 * 021 * @param <MI> 022 * the model instance Java type 023 * @param <NMI> 024 * the named model instance Java type 025 * @param <FI> 026 * the field instance Java type 027 * @param <AI> 028 * the assembly instance Java type 029 * @param <CI> 030 * the choice instance Java type 031 * @param <CGI> 032 * the choice group instance Java type 033 * @see DefaultChoiceGroupModelBuilder for a choice group model builder 034 * @see DefaultChoiceModelBuilder for a choice model builder 035 */ 036@SuppressWarnings("PMD.UseConcurrentHashMap") 037public class DefaultAssemblyModelBuilder< 038 MI extends IModelInstance, 039 NMI extends INamedModelInstance, 040 FI extends IFieldInstance, 041 AI extends IAssemblyInstance, 042 CI extends IChoiceInstance, 043 CGI extends IChoiceGroupInstance> 044 extends DefaultChoiceModelBuilder<MI, NMI, FI, AI> { 045 // collections to store model instances 046 @NonNull 047 private final List<CI> choiceInstances = new LinkedList<>(); 048 @NonNull 049 private final Map<String, CGI> choiceGroupInstances = new LinkedHashMap<>(); 050 @Nullable 051 private IAnyInstance anyInstance; 052 053 /** 054 * Append the instance. 055 * 056 * @param instance 057 * the instance to append 058 */ 059 @SuppressWarnings("unchecked") 060 public void append(@NonNull CI instance) { 061 getModelInstances().add((MI) instance); 062 choiceInstances.add(instance); 063 } 064 065 /** 066 * Append the instance. 067 * 068 * @param instance 069 * the instance to append 070 */ 071 @SuppressWarnings("unchecked") 072 public void append(@NonNull CGI instance) { 073 getModelInstances().add((MI) instance); 074 choiceGroupInstances.put(instance.getGroupAsName(), instance); 075 } 076 077 /** 078 * Get the appended choice instances. 079 * 080 * @return the instances or an empty list if no instances were appended 081 */ 082 @NonNull 083 protected List<CI> getChoiceInstances() { 084 return choiceInstances; 085 } 086 087 /** 088 * Get the appended choice group instances. 089 * 090 * @return the instances or an empty map if no instances were appended 091 */ 092 @NonNull 093 protected Map<String, CGI> getChoiceGroupInstances() { 094 return choiceGroupInstances; 095 } 096 097 /** 098 * Get the {@code any} instance. 099 * 100 * @return the {@code any} instance, or {@code null} if none has been set 101 */ 102 @Nullable 103 public IAnyInstance getAnyInstance() { 104 return anyInstance; 105 } 106 107 /** 108 * Set the {@code any} instance for this model. 109 * 110 * @param anyInstance 111 * the {@code any} instance, or {@code null} to clear it 112 */ 113 public void setAnyInstance(@Nullable IAnyInstance anyInstance) { 114 this.anyInstance = anyInstance; 115 } 116 117 /** 118 * Build an immutable assembly model container based on the appended instances. 119 * 120 * @return the container 121 */ 122 @NonNull 123 public IContainerModelAssemblySupport<MI, NMI, FI, AI, CI, CGI> buildAssembly() { 124 return getModelInstances().isEmpty() && anyInstance == null 125 ? IContainerModelAssemblySupport.empty() 126 : new DefaultContainerModelAssemblySupport<>( 127 CollectionUtil.unmodifiableList(getModelInstances()), 128 CollectionUtil.unmodifiableMap(getNamedModelInstances()), 129 CollectionUtil.unmodifiableMap(getFieldInstances()), 130 CollectionUtil.unmodifiableMap(getAssemblyInstances()), 131 CollectionUtil.unmodifiableList(getChoiceInstances()), 132 CollectionUtil.unmodifiableMap(getChoiceGroupInstances()), 133 anyInstance); 134 } 135}