1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.databind.codegen;
7   
8   import java.net.URI;
9   import java.util.LinkedList;
10  import java.util.List;
11  
12  import edu.umd.cs.findbugs.annotations.NonNull;
13  
14  /**
15   * Tracks metadata about a Java package during code generation.
16   * <p>
17   * This class aggregates information about generated module classes that share
18   * the same package name, ensuring consistent XML namespace association.
19   */
20  class PackageMetadata {
21    @NonNull
22    private final String packageName;
23    @NonNull
24    private final URI xmlNamespace;
25    @NonNull
26    private final List<IGeneratedModuleClass> moduleProductions = new LinkedList<>();
27  
28    /**
29     * Construct package metadata based on an initial module production.
30     *
31     * @param moduleProduction
32     *          the first module production for this package
33     */
34    public PackageMetadata(@NonNull IGeneratedModuleClass moduleProduction) {
35      packageName = moduleProduction.getPackageName();
36      xmlNamespace = moduleProduction.getModule().getXmlNamespace();
37      moduleProductions.add(moduleProduction);
38    }
39  
40    /**
41     * Get the Java package name.
42     *
43     * @return the package name
44     */
45    @NonNull
46    protected String getPackageName() {
47      return packageName;
48    }
49  
50    /**
51     * Get the XML namespace associated with this package.
52     *
53     * @return the XML namespace URI
54     */
55    @NonNull
56    protected URI getXmlNamespace() {
57      return xmlNamespace;
58    }
59  
60    /**
61     * Get the module productions associated with this package.
62     *
63     * @return the list of module productions
64     */
65    @NonNull
66    protected List<IGeneratedModuleClass> getModuleProductions() {
67      return moduleProductions;
68    }
69  
70    /**
71     * Add a module production to this package.
72     *
73     * @param moduleProduction
74     *          the module production to add
75     * @throws IllegalStateException
76     *           if the module's XML namespace does not match the package's
77     *           namespace
78     */
79    public void addModule(@NonNull IGeneratedModuleClass moduleProduction) {
80      URI nextXmlNamespace = moduleProduction.getModule().getXmlNamespace();
81      if (!xmlNamespace.equals(nextXmlNamespace)) {
82        throw new IllegalStateException(String.format(
83            "The package %s is associated with the XML namespaces '%s' and '%s'."
84                + " A package must be associated with a single XML namespace.",
85            getPackageName(), getXmlNamespace().toASCIIString(), nextXmlNamespace.toASCIIString()));
86      }
87      moduleProductions.add(moduleProduction);
88    }
89  }