1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.databind.codegen;
7   
8   import gov.nist.secauto.metaschema.core.model.IModule;
9   import gov.nist.secauto.metaschema.core.util.ObjectUtils;
10  import gov.nist.secauto.metaschema.databind.codegen.typeinfo.IMetaschemaClassFactory;
11  
12  import java.io.IOException;
13  import java.nio.file.Path;
14  import java.util.Collection;
15  import java.util.Collections;
16  import java.util.HashMap;
17  import java.util.List;
18  import java.util.Map;
19  import java.util.stream.Collectors;
20  import java.util.stream.Stream;
21  
22  import edu.umd.cs.findbugs.annotations.NonNull;
23  
24  class ProductionImpl implements IProduction {
25  
26    @NonNull
27    private final Map<IModule, IGeneratedModuleClass> moduleToProductionMap // NOPMD - immutable
28        = new HashMap<>();
29    @NonNull
30    private final Map<String, IPackageProduction> packageNameToProductionMap // NOPMD - immutable
31        = new HashMap<>();
32  
33    public void addModule(
34        @NonNull IModule module,
35        @NonNull IMetaschemaClassFactory classFactory,
36        @NonNull Path targetDirectory) throws IOException {
37      for (IModule importedModule : module.getImportedModules()) {
38        assert importedModule != null;
39        addModule(importedModule, classFactory, targetDirectory);
40      }
41  
42      if (moduleToProductionMap.get(module) == null) {
43        IGeneratedModuleClass metaschemaClass = classFactory.generateClass(module, targetDirectory);
44        moduleToProductionMap.put(module, metaschemaClass);
45      }
46    }
47  
48    protected IPackageProduction addPackage(
49        @NonNull PackageMetadata metadata,
50        @NonNull IMetaschemaClassFactory classFactory,
51        @NonNull Path targetDirectory)
52        throws IOException {
53      String javaPackage = metadata.getPackageName();
54  
55      IPackageProduction retval
56          = new PackageProductionImpl(
57              metadata,
58              classFactory,
59              targetDirectory);
60      packageNameToProductionMap.put(javaPackage, retval);
61      return retval;
62    }
63  
64    @Override
65    @SuppressWarnings("null")
66    public Collection<IGeneratedModuleClass> getModuleProductions() {
67      return Collections.unmodifiableCollection(moduleToProductionMap.values());
68    }
69  
70    @SuppressWarnings("null")
71    @NonNull
72    protected Collection<IPackageProduction> getPackageProductions() {
73      return Collections.unmodifiableCollection(packageNameToProductionMap.values());
74    }
75  
76    @Override
77    public IGeneratedModuleClass getModuleProduction(IModule module) {
78      return moduleToProductionMap.get(module);
79    }
80  
81    @Override
82    public List<IGeneratedDefinitionClass> getGlobalDefinitionClasses() {
83      return ObjectUtils.notNull(getModuleProductions().stream()
84          .flatMap(metaschema -> metaschema.getGeneratedDefinitionClasses().stream())
85          .collect(Collectors.toUnmodifiableList()));
86    }
87  
88    @Override
89    public Stream<? extends IGeneratedClass> getGeneratedClasses() {
90      return ObjectUtils.notNull(Stream.concat(
91          // generated definitions and Metaschema module
92          getModuleProductions().stream()
93              .flatMap(module -> Stream.concat(
94                  Stream.of(module),
95                  module.getGeneratedDefinitionClasses().stream())),
96          // generated package-info.java
97          getPackageProductions().stream()
98              .flatMap(javaPackage -> Stream.of(javaPackage.getGeneratedClass()))));
99    }
100 
101 }