001/* 002 * Portions of this software was developed by employees of the National Institute 003 * of Standards and Technology (NIST), an agency of the Federal Government and is 004 * being made available as a public service. Pursuant to title 17 United States 005 * Code Section 105, works of NIST employees are not subject to copyright 006 * protection in the United States. This software may be subject to foreign 007 * copyright. Permission in the United States and in foreign countries, to the 008 * extent that NIST may hold copyright, to use, copy, modify, create derivative 009 * works, and distribute this software and its documentation without fee is hereby 010 * granted on a non-exclusive basis, provided that this notice and disclaimer 011 * of warranty appears in all copies. 012 * 013 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 014 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 015 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 017 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 018 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 019 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 020 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 021 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 022 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 023 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 024 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 025 */ 026 027package gov.nist.secauto.metaschema.databind.codegen; 028 029import gov.nist.secauto.metaschema.core.model.IModule; 030import gov.nist.secauto.metaschema.databind.codegen.typeinfo.ITypeResolver; 031 032import java.io.IOException; 033import java.nio.file.Path; 034import java.util.Collection; 035import java.util.HashMap; 036import java.util.Map; 037import java.util.stream.Stream; 038 039import edu.umd.cs.findbugs.annotations.NonNull; 040import edu.umd.cs.findbugs.annotations.Nullable; 041 042/** 043 * Information about Java classes generated for a collection of Module modules. 044 */ 045public interface IProduction { 046 047 /** 048 * Get information about the Java classes generated for each Module module in 049 * the collection. 050 * 051 * @return the Java class information for each module 052 */ 053 @NonNull 054 Collection<IGeneratedModuleClass> getModuleProductions(); 055 056 /** 057 * Get information about the Java classes generated for the provided Module 058 * {@code module}. 059 * 060 * @param module 061 * the Module module to get information for 062 * @return the Java class information for the module or {@code null} if this 063 * production did not involve generating classes for the provided module 064 */ 065 @Nullable 066 IGeneratedModuleClass getModuleProduction(@NonNull IModule module); 067 068 /** 069 * Get a stream of all definition Java classes generated as part of this 070 * production. 071 * <p> 072 * This will include each unique class generated for all Module modules 073 * associated with this production. 074 * 075 * @return the stream of generated Java classes 076 */ 077 @NonNull 078 Stream<IGeneratedDefinitionClass> getGlobalDefinitionClassesAsStream(); 079 080 /** 081 * Get a stream of all Java classes generated as part of this production, 082 * including module, definition, and package-info classes. 083 * 084 * @return the stream of generated Java classes 085 */ 086 @NonNull 087 Stream<? extends IGeneratedClass> getGeneratedClasses(); 088 089 /** 090 * Create a new production for the provided set of Module {@code modules}. 091 * 092 * @param modules 093 * the Module modules to generate and compile classes for 094 * @param typeResolver 095 * the resolve used to determine type names 096 * @param classDir 097 * the directory to generate and compile classes in 098 * @return the production information 099 * @throws IOException 100 * if an error occurred while generating or compiling the classes 101 */ 102 @NonNull 103 static IProduction of( // NOPMD - intentional 104 @NonNull Collection<? extends IModule> modules, 105 @NonNull ITypeResolver typeResolver, 106 @NonNull Path classDir) throws IOException { 107 108 IMetaschemaClassFactory classFactory = IMetaschemaClassFactory.newInstance(typeResolver); 109 110 ProductionImpl retval = new ProductionImpl(); 111 for (IModule module : modules) { 112 assert module != null; 113 retval.addModule(module, classFactory, classDir); 114 } 115 116 Map<String, PackageMetadata> packageNameToPackageMetadataMap = new HashMap<>(); // NOPMD - no concurrency 117 for (IGeneratedModuleClass moduleProduction : retval.getModuleProductions()) { 118 String packageName = moduleProduction.getPackageName(); 119 120 PackageMetadata metadata = packageNameToPackageMetadataMap.get(packageName); 121 if (metadata == null) { 122 metadata = new PackageMetadata(moduleProduction); // NOPMD - intentional 123 packageNameToPackageMetadataMap.put(metadata.getPackageName(), metadata); 124 } else { 125 metadata.addModule(moduleProduction); 126 } 127 } 128 129 for (PackageMetadata metadata : packageNameToPackageMetadataMap.values()) { 130 assert metadata != null; 131 retval.addPackage( 132 metadata, 133 classFactory, 134 classDir); 135 } 136 return retval; 137 } 138}