001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.metaschema.databind.codegen; 007 008import gov.nist.secauto.metaschema.core.model.IModule; 009import gov.nist.secauto.metaschema.databind.codegen.config.IBindingConfiguration; 010import gov.nist.secauto.metaschema.databind.codegen.typeinfo.IMetaschemaClassFactory; 011import gov.nist.secauto.metaschema.databind.codegen.typeinfo.ITypeResolver; 012 013import java.io.IOException; 014import java.nio.file.Path; 015import java.util.Collection; 016import java.util.HashMap; 017import java.util.Map; 018import java.util.stream.Stream; 019 020import edu.umd.cs.findbugs.annotations.NonNull; 021import edu.umd.cs.findbugs.annotations.Nullable; 022 023/** 024 * Information about Java classes generated for a collection of Module modules. 025 */ 026public interface IProduction { 027 028 /** 029 * Get information about the Java classes generated for each Module module in 030 * the collection. 031 * 032 * @return the Java class information for each module 033 */ 034 @NonNull 035 Collection<IGeneratedModuleClass> getModuleProductions(); 036 037 /** 038 * Get information about the Java classes generated for the provided Module 039 * {@code module}. 040 * 041 * @param module 042 * the Module module to get information for 043 * @return the Java class information for the module or {@code null} if this 044 * production did not involve generating classes for the provided module 045 */ 046 @Nullable 047 IGeneratedModuleClass getModuleProduction(@NonNull IModule module); 048 049 /** 050 * Get a stream of all definition Java classes generated as part of this 051 * production. 052 * <p> 053 * This will include each unique class generated for all Module modules 054 * associated with this production. 055 * 056 * @return the stream of generated Java classes 057 */ 058 @NonNull 059 Collection<IGeneratedDefinitionClass> getGlobalDefinitionClasses(); 060 061 /** 062 * Get a stream of all Java classes generated as part of this production, 063 * including module, definition, and package-info classes. 064 * 065 * @return the stream of generated Java classes 066 */ 067 @NonNull 068 Stream<? extends IGeneratedClass> getGeneratedClasses(); 069 070 /** 071 * Create a new production for the provided set of Module {@code modules}. 072 * 073 * @param modules 074 * the Module modules to generate and compile classes for 075 * @param bindingConfiguration 076 * binding customizations that can be used to set namespaces, class 077 * names, and other aspects of generated classes 078 * @param classDir 079 * the directory to generate and compile classes in 080 * @return the production information 081 * @throws IOException 082 * if an error occurred while generating or compiling the classes 083 */ 084 @NonNull 085 static IProduction of( // NOPMD - intentional 086 @NonNull Collection<? extends IModule> modules, 087 @NonNull IBindingConfiguration bindingConfiguration, 088 @NonNull Path classDir) throws IOException { 089 090 ITypeResolver typeResolver = ITypeResolver.newTypeResolver(bindingConfiguration); 091 092 IMetaschemaClassFactory classFactory = IMetaschemaClassFactory.newInstance(typeResolver); 093 094 ProductionImpl retval = new ProductionImpl(); 095 for (IModule module : modules) { 096 assert module != null; 097 retval.addModule(module, classFactory, classDir); 098 } 099 100 Map<String, PackageMetadata> packageNameToPackageMetadataMap = new HashMap<>(); // NOPMD - no concurrency 101 for (IGeneratedModuleClass moduleProduction : retval.getModuleProductions()) { 102 String packageName = moduleProduction.getPackageName(); 103 104 PackageMetadata metadata = packageNameToPackageMetadataMap.get(packageName); 105 if (metadata == null) { 106 metadata = new PackageMetadata(moduleProduction); // NOPMD - intentional 107 packageNameToPackageMetadataMap.put(metadata.getPackageName(), metadata); 108 } else { 109 metadata.addModule(moduleProduction); 110 } 111 } 112 113 for (PackageMetadata metadata : packageNameToPackageMetadataMap.values()) { 114 assert metadata != null; 115 retval.addPackage( 116 metadata, 117 classFactory, 118 classDir); 119 } 120 return retval; 121 } 122}