View Javadoc
1   /*
2    * Portions of this software was developed by employees of the National Institute
3    * of Standards and Technology (NIST), an agency of the Federal Government and is
4    * being made available as a public service. Pursuant to title 17 United States
5    * Code Section 105, works of NIST employees are not subject to copyright
6    * protection in the United States. This software may be subject to foreign
7    * copyright. Permission in the United States and in foreign countries, to the
8    * extent that NIST may hold copyright, to use, copy, modify, create derivative
9    * works, and distribute this software and its documentation without fee is hereby
10   * granted on a non-exclusive basis, provided that this notice and disclaimer
11   * of warranty appears in all copies.
12   *
13   * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14   * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15   * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17   * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18   * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
19   * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20   * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21   * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22   * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23   * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24   * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25   */
26  
27  package gov.nist.secauto.metaschema.databind.codegen;
28  
29  import gov.nist.secauto.metaschema.core.model.IModule;
30  import gov.nist.secauto.metaschema.databind.codegen.typeinfo.ITypeResolver;
31  
32  import java.io.IOException;
33  import java.nio.file.Path;
34  import java.util.Collection;
35  import java.util.HashMap;
36  import java.util.Map;
37  import java.util.stream.Stream;
38  
39  import edu.umd.cs.findbugs.annotations.NonNull;
40  import edu.umd.cs.findbugs.annotations.Nullable;
41  
42  /**
43   * Information about Java classes generated for a collection of Module modules.
44   */
45  public interface IProduction {
46  
47    /**
48     * Get information about the Java classes generated for each Module module in
49     * the collection.
50     *
51     * @return the Java class information for each module
52     */
53    @NonNull
54    Collection<IGeneratedModuleClass> getModuleProductions();
55  
56    /**
57     * Get information about the Java classes generated for the provided Module
58     * {@code module}.
59     *
60     * @param module
61     *          the Module module to get information for
62     * @return the Java class information for the module or {@code null} if this
63     *         production did not involve generating classes for the provided module
64     */
65    @Nullable
66    IGeneratedModuleClass getModuleProduction(@NonNull IModule module);
67  
68    /**
69     * Get a stream of all definition Java classes generated as part of this
70     * production.
71     * <p>
72     * This will include each unique class generated for all Module modules
73     * associated with this production.
74     *
75     * @return the stream of generated Java classes
76     */
77    @NonNull
78    Stream<IGeneratedDefinitionClass> getGlobalDefinitionClassesAsStream();
79  
80    /**
81     * Get a stream of all Java classes generated as part of this production,
82     * including module, definition, and package-info classes.
83     *
84     * @return the stream of generated Java classes
85     */
86    @NonNull
87    Stream<? extends IGeneratedClass> getGeneratedClasses();
88  
89    /**
90     * Create a new production for the provided set of Module {@code modules}.
91     *
92     * @param modules
93     *          the Module modules to generate and compile classes for
94     * @param typeResolver
95     *          the resolve used to determine type names
96     * @param classDir
97     *          the directory to generate and compile classes in
98     * @return the production information
99     * @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 }