1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.testsupport.builder;
7   
8   import java.util.List;
9   
10  import dev.metaschema.core.model.IAssemblyDefinition;
11  import dev.metaschema.core.model.INamedModelInstanceAbsolute;
12  import dev.metaschema.core.model.ISource;
13  import dev.metaschema.core.qname.IEnhancedQName;
14  import edu.umd.cs.findbugs.annotations.NonNull;
15  import edu.umd.cs.findbugs.annotations.Nullable;
16  
17  /**
18   * A reference to an assembly definition by name. This class implements
19   * {@link IModelBuilder} to allow it to be used in model instance lists, but the
20   * actual instance is created during module resolution when the referenced
21   * definition is available.
22   *
23   * <p>
24   * This enables recursive assembly structures where an assembly can contain
25   * instances of itself or other assemblies that are defined later in the module.
26   */
27  final class AssemblyReference
28      implements IModelBuilder<AssemblyReference>, IModelReference {
29  
30    private final String referencedName;
31    private ISource source;
32  
33    /**
34     * Construct a new assembly reference.
35     *
36     * @param referencedName
37     *          the local name of the referenced assembly definition
38     */
39    AssemblyReference(@NonNull String referencedName) {
40      this.referencedName = referencedName;
41    }
42  
43    @Override
44    @NonNull
45    public String getReferencedName() {
46      return referencedName;
47    }
48  
49    @Override
50    public AssemblyReference reset() {
51      this.source = null;
52      return this;
53    }
54  
55    @Override
56    @NonNull
57    public AssemblyReference namespace(@NonNull String name) {
58      // References use the name from construction; namespace is set by ModuleBuilder
59      return this;
60    }
61  
62    @Override
63    @NonNull
64    public AssemblyReference name(@NonNull String name) {
65      // References use the name from construction
66      return this;
67    }
68  
69    @Override
70    @NonNull
71    public AssemblyReference qname(@NonNull IEnhancedQName qname) {
72      // References use the name from construction
73      return this;
74    }
75  
76    @Override
77    @NonNull
78    public AssemblyReference source(@NonNull ISource source) {
79      this.source = source;
80      return this;
81    }
82  
83    /**
84     * Get the source associated with this reference.
85     *
86     * @return the source, or {@code null} if not set
87     */
88    @Nullable
89    protected ISource getSource() {
90      return source;
91    }
92  
93    @Override
94    @NonNull
95    public AssemblyReference flags(@Nullable List<IFlagBuilder> flags) {
96      // References don't support flags - they reference existing definitions
97      throw new UnsupportedOperationException("Assembly references cannot have flags");
98    }
99  
100   /**
101    * This method should not be called directly. Assembly references are resolved
102    * during module construction.
103    *
104    * @param parent
105    *          ignored
106    * @return never returns normally
107    * @throws UnsupportedOperationException
108    *           always, as references must be resolved during module construction
109    */
110   @Override
111   @NonNull
112   public INamedModelInstanceAbsolute toInstance(@NonNull IAssemblyDefinition parent) {
113     throw new UnsupportedOperationException(
114         "Assembly references must be resolved during module construction. "
115             + "Use ModuleBuilder to build the module, which will resolve references.");
116   }
117 }