View Javadoc
1   /*
2    * Themis: Java Project Framework
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.themis.parser.project;
18  
19  import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
20  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
21  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
22  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
23  import io.github.tonywasher.joceanus.tethys.api.thread.TethysUIThreadStatusReport;
24  import io.github.tonywasher.joceanus.themis.parser.base.ThemisChar;
25  import io.github.tonywasher.joceanus.themis.parser.base.ThemisDataResource;
26  import io.github.tonywasher.joceanus.themis.parser.base.ThemisParserDef;
27  import io.github.tonywasher.joceanus.themis.parser.maven.ThemisMavenPom;
28  import io.github.tonywasher.joceanus.themis.parser.mod.ThemisModModule;
29  
30  import java.io.File;
31  import java.util.ArrayList;
32  import java.util.List;
33  import java.util.Objects;
34  
35  /**
36   * Module.
37   */
38  public class ThemisModule
39          implements MetisFieldItem {
40      /**
41       * Report fields.
42       */
43      private static final MetisFieldSet<ThemisModule> FIELD_DEFS = MetisFieldSet.newFieldSet(ThemisModule.class);
44  
45      /*
46       * Declare Fields.
47       */
48      static {
49          FIELD_DEFS.declareLocalField(ThemisDataResource.DATA_NAME, ThemisModule::getName);
50          FIELD_DEFS.declareLocalField(ThemisDataResource.DATA_PACKAGES, ThemisModule::getPackages);
51      }
52  
53      /**
54       * The module-info file.
55       */
56      private static final String MODULE_INFO = "module-info" + ThemisFile.SFX_JAVA;
57  
58      /**
59       * The module name.
60       */
61      private final String theName;
62  
63      /**
64       * The locations.
65       */
66      private final File theLocation;
67  
68      /**
69       * The package list.
70       */
71      private final List<ThemisPackage> thePackages;
72  
73      /**
74       * The module-info declaration.
75       */
76      private ThemisModModule theModuleInfo;
77  
78      /**
79       * Constructor.
80       *
81       * @param pPom the module Pom
82       */
83      ThemisModule(final ThemisMavenPom pPom) {
84          /* Create the list */
85          thePackages = new ArrayList<>();
86  
87          /* Store the name and location */
88          final File myLocation = pPom.getLocation();
89          theLocation = new File(myLocation, ThemisPackage.PATH_XTRA);
90          theName = myLocation.getName();
91  
92          /* Initiate search for packages */
93          checkForPackage(theLocation, null);
94  
95          /* Add any extraDirs */
96          for (String myXtra : pPom.getXtraDirs()) {
97              final File myXtraDir = new File(myLocation, myXtra);
98              checkForPackage(myXtraDir, null);
99          }
100     }
101 
102     @Override
103     public MetisFieldSet<ThemisModule> getDataFieldSet() {
104         return FIELD_DEFS;
105     }
106 
107     @Override
108     public String formatObject(final OceanusDataFormatter pFormatter) {
109         return toString();
110     }
111 
112     /**
113      * Obtain the name.
114      *
115      * @return the name
116      */
117     public String getName() {
118         return theName;
119     }
120 
121     @Override
122     public String toString() {
123         return getName();
124     }
125 
126     /**
127      * Obtain the packages.
128      *
129      * @return the packages
130      */
131     public List<ThemisPackage> getPackages() {
132         return thePackages;
133     }
134 
135     /**
136      * Obtain the module-info.
137      *
138      * @return the module-info
139      */
140     public ThemisModModule getModuleInfo() {
141         return theModuleInfo;
142     }
143 
144     /**
145      * Check for package.
146      *
147      * @param pLocation the location to search
148      * @param pPackage  the package name
149      */
150     void checkForPackage(final File pLocation,
151                          final String pPackage) {
152         /* Assume not a package */
153         boolean isPackage = false;
154 
155         /* Determine the location to search */
156         final File myLocation = pPackage == null
157                 ? pLocation
158                 : new File(pLocation, pPackage.replace(ThemisChar.PERIOD, ThemisChar.COMMENT));
159 
160         /* Look for java files or further packages */
161         for (File myFile : Objects.requireNonNull(myLocation.listFiles())) {
162             /* Access file name */
163             final String myName = myFile.getName();
164 
165             /* If this is a directory */
166             if (myFile.isDirectory()) {
167                 final String myPackage = pPackage == null
168                         ? myName
169                         : pPackage + ThemisChar.PERIOD + myName;
170                 checkForPackage(pLocation, myPackage);
171             }
172 
173             /* If this is a Java file name */
174             if (myName.endsWith(ThemisFile.SFX_JAVA)
175                     && !MODULE_INFO.equals(myName)) {
176                 isPackage = pPackage != null;
177             }
178         }
179 
180         /* If this is a package */
181         if (isPackage) {
182             /* Add the package to the list */
183             thePackages.add(new ThemisPackage(pLocation, pPackage));
184         }
185     }
186 
187     /**
188      * Parse java code.
189      *
190      * @param pParser the parser
191      * @throws OceanusException on error
192      */
193     void parseJavaCode(final ThemisParserDef pParser) throws OceanusException {
194         /* Obtain the reporter */
195         final TethysUIThreadStatusReport myReport = pParser.getReporter();
196         myReport.setNumSteps(thePackages.size());
197 
198         /* Loop through the packages */
199         for (ThemisPackage myPackage : thePackages) {
200             /* Process the package */
201             myReport.setNextStep();
202             myPackage.parseJavaCode(pParser);
203         }
204 
205         /* Check for and load the module-info file if found */
206         final File myModuleInfo = new File(theLocation, MODULE_INFO);
207         if (myModuleInfo.exists()) {
208             theModuleInfo = (ThemisModModule) pParser.parseModuleInfo(myModuleInfo);
209         }
210     }
211 }