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.lethe.analysis;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.themis.exc.ThemisIOException;
21  
22  import java.io.File;
23  import java.io.FileInputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  /**
30   * Project.
31   */
32  public class ThemisAnalysisProject
33          implements ThemisAnalysisElement {
34      /**
35       * Consolidation Pass error.
36       */
37      private static final String CONSOLIDATION_ERROR = "Failed on consolidation Pass";
38  
39      /**
40       * The project name.
41       */
42      private final String theName;
43  
44      /**
45       * The location.
46       */
47      private final File theLocation;
48  
49      /**
50       * The module list.
51       */
52      private final List<ThemisAnalysisModule> theModules;
53  
54      /**
55       * The initial dataMap.
56       */
57      private final ThemisAnalysisDataMap theDataMap;
58  
59      /**
60       * The error.
61       */
62      private OceanusException theError;
63  
64      /**
65       * Constructor.
66       *
67       * @param pLocation the project location
68       */
69      public ThemisAnalysisProject(final File pLocation) {
70          /* Store the name and location */
71          theLocation = pLocation;
72  
73          /* Create the list */
74          theModules = new ArrayList<>();
75  
76          /* Create the dataMap */
77          theDataMap = new ThemisAnalysisDataMap();
78  
79          /* Initiate search for modules */
80          final ThemisAnalysisMavenId myId = parseProjectFile(new File(theLocation, ThemisAnalysisMaven.POM));
81          theName = myId == null ? null : myId.getArtifactId();
82  
83          /* InitialPass */
84          if (theError == null) {
85              performInitialPass();
86          }
87  
88          /* ConsolidationPass */
89          if (theError == null) {
90              performConsolidationPass();
91          }
92  
93          /* FinalPass */
94          if (theError == null) {
95              performFinalPass();
96          }
97      }
98  
99      /**
100      * Obtain the name.
101      *
102      * @return the name
103      */
104     public String getName() {
105         return theName;
106     }
107 
108     /**
109      * Obtain the location.
110      *
111      * @return the location
112      */
113     File getLocation() {
114         return theLocation;
115     }
116 
117     /**
118      * Obtain the error.
119      *
120      * @return the error
121      */
122     public OceanusException getError() {
123         return theError;
124     }
125 
126     /**
127      * Obtain the modules.
128      *
129      * @return the modules
130      */
131     public List<ThemisAnalysisModule> getModules() {
132         return theModules;
133     }
134 
135     /**
136      * Obtain the dataMap.
137      *
138      * @return the map
139      */
140     ThemisAnalysisDataMap getDataMap() {
141         return theDataMap;
142     }
143 
144     @Override
145     public String toString() {
146         return theName;
147     }
148 
149     /**
150      * Parse the maven top-level project file.
151      *
152      * @param pPom the project file
153      * @return the mavenId of the project
154      */
155     private ThemisAnalysisMavenId parseProjectFile(final File pPom) {
156         /* If the pom file does not exist, just return */
157         if (!pPom.exists()) {
158             return null;
159         }
160 
161         /* Protect against exceptions */
162         try {
163             /* Add module if source directory exists */
164             final File mySrc = new File(pPom.getParent(), ThemisAnalysisModule.PATH_XTRA);
165             if (mySrc.exists()
166                     && mySrc.isDirectory()) {
167                 /* Add the module to the list */
168                 theModules.add(new ThemisAnalysisModule(this, new File(pPom.getParent())));
169             }
170 
171             /* Handle exceptions */
172         } catch (OceanusException e) {
173             /* Save Exception */
174             theError = new ThemisIOException(CONSOLIDATION_ERROR, e);
175             return null;
176         }
177 
178         /* Protect against exceptions */
179         try (InputStream myInStream = new FileInputStream(pPom)) {
180             /* Parse the Project definition file */
181             final ThemisAnalysisMaven myPom = new ThemisAnalysisMaven(myInStream);
182 
183             /* Loop through the modules */
184             for (final String myModuleName : myPom.getModules()) {
185                 /* Access module directory */
186                 final File myModuleDir = new File(pPom.getParentFile(), myModuleName);
187 
188                 /* Process the project file */
189                 parseProjectFile(new File(myModuleDir, ThemisAnalysisMaven.POM));
190 
191                 /* Break loop on error */
192                 if (theError != null) {
193                     break;
194                 }
195             }
196 
197             return myPom.getMavenId();
198 
199             /* Catch exceptions */
200         } catch (IOException
201                  | OceanusException e) {
202             /* Save Exception */
203             theError = new ThemisIOException("Failed to parse Project file", e);
204             return null;
205         }
206     }
207 
208     /**
209      * initialPass.
210      */
211     private void performInitialPass() {
212         /* Protect against exceptions */
213         try {
214             /* Loop through the modules */
215             for (ThemisAnalysisModule myModule : theModules) {
216                 /* Process the module */
217                 myModule.performInitialPass();
218             }
219 
220             /* Handle exceptions */
221         } catch (OceanusException e) {
222             /* Save Exception */
223             theError = new ThemisIOException(CONSOLIDATION_ERROR, e);
224         }
225     }
226 
227     /**
228      * consolidationPass.
229      */
230     private void performConsolidationPass() {
231         /* Protect against exceptions */
232         try {
233             /* Loop through the modules */
234             for (ThemisAnalysisModule myModule : theModules) {
235                 /* Process the module */
236                 myModule.performConsolidationPass();
237             }
238 
239             /* Handle exceptions */
240         } catch (OceanusException e) {
241             /* Save Exception */
242             theError = new ThemisIOException(CONSOLIDATION_ERROR, e);
243         }
244     }
245 
246     /**
247      * finalPass.
248      */
249     private void performFinalPass() {
250         /* Protect against exceptions */
251         try {
252             /* Loop through the modules */
253             for (ThemisAnalysisModule myModule : theModules) {
254                 /* Process the module */
255                 myModule.performFinalPass();
256             }
257 
258             /* Handle exceptions */
259         } catch (OceanusException e) {
260             /* Save Exception */
261             theError = new ThemisIOException("Failed on final pass", e);
262         }
263     }
264 }