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;
016
017/**
018 * An assembly model builder.
019 *
020 * @param <MI>
021 *          the model instance Java type
022 * @param <NMI>
023 *          the named model instance Java type
024 * @param <FI>
025 *          the field instance Java type
026 * @param <AI>
027 *          the assembly instance Java type
028 * @param <CI>
029 *          the choice instance Java type
030 * @param <CGI>
031 *          the choice group instance Java type
032 * @see DefaultChoiceGroupModelBuilder for a choice group model builder
033 * @see DefaultChoiceModelBuilder for a choice model builder
034 */
035@SuppressWarnings("PMD.UseConcurrentHashMap")
036public class DefaultAssemblyModelBuilder<
037    MI extends IModelInstance,
038    NMI extends INamedModelInstance,
039    FI extends IFieldInstance,
040    AI extends IAssemblyInstance,
041    CI extends IChoiceInstance,
042    CGI extends IChoiceGroupInstance>
043    extends DefaultChoiceModelBuilder<MI, NMI, FI, AI> {
044  // collections to store model instances
045  @NonNull
046  private final List<CI> choiceInstances = new LinkedList<>();
047  @NonNull
048  private final Map<String, CGI> choiceGroupInstances = new LinkedHashMap<>();
049
050  /**
051   * Append the instance.
052   *
053   * @param instance
054   *          the instance to append
055   */
056  @SuppressWarnings("unchecked")
057  public void append(@NonNull CI instance) {
058    getModelInstances().add((MI) instance);
059    choiceInstances.add(instance);
060  }
061
062  /**
063   * Append the instance.
064   *
065   * @param instance
066   *          the instance to append
067   */
068  @SuppressWarnings("unchecked")
069  public void append(@NonNull CGI instance) {
070    getModelInstances().add((MI) instance);
071    choiceGroupInstances.put(instance.getGroupAsName(), instance);
072  }
073
074  /**
075   * Get the appended choice instances.
076   *
077   * @return the instances or an empty list if no instances were appended
078   */
079  @NonNull
080  protected List<CI> getChoiceInstances() {
081    return choiceInstances;
082  }
083
084  /**
085   * Get the appended choice group instances.
086   *
087   * @return the instances or an empty map if no instances were appended
088   */
089  @NonNull
090  protected Map<String, CGI> getChoiceGroupInstances() {
091    return choiceGroupInstances;
092  }
093
094  /**
095   * Build an immutable assembly model container based on the appended instances.
096   *
097   * @return the container
098   */
099  @NonNull
100  public IContainerModelAssemblySupport<MI, NMI, FI, AI, CI, CGI> buildAssembly() {
101    return getModelInstances().isEmpty()
102        ? IContainerModelAssemblySupport.empty()
103        : new DefaultContainerModelAssemblySupport<>(
104            CollectionUtil.unmodifiableList(getModelInstances()),
105            CollectionUtil.unmodifiableMap(getNamedModelInstances()),
106            CollectionUtil.unmodifiableMap(getFieldInstances()),
107            CollectionUtil.unmodifiableMap(getAssemblyInstances()),
108            CollectionUtil.unmodifiableList(getChoiceInstances()),
109            CollectionUtil.unmodifiableMap(getChoiceGroupInstances()));
110  }
111}