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.proj;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.themis.exc.ThemisIOException;
21  import io.github.tonywasher.joceanus.themis.parser.base.ThemisParserDef;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.util.ArrayList;
28  import java.util.LinkedHashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  /**
33   * Project.
34   */
35  public class ThemisProject {
36      /**
37       * The project name.
38       */
39      private final String theName;
40  
41      /**
42       * The location.
43       */
44      private final File theLocation;
45  
46      /**
47       * The module map.
48       */
49      private final Map<ThemisMavenId, ThemisModule> theModules;
50  
51      /**
52       * The dependencies.
53       */
54      private final List<ThemisMavenId> theDependencies;
55  
56      /**
57       * Constructor.
58       *
59       * @param pLocation the project location
60       * @throws OceanusException on error
61       */
62      public ThemisProject(final File pLocation) throws OceanusException {
63          /* Store the name and location */
64          theLocation = pLocation;
65  
66          /* Create the list */
67          theModules = new LinkedHashMap<>();
68          theDependencies = new ArrayList<>();
69  
70          /* Initiate search for modules */
71          final ThemisMaven myPom = parseProjectFile(null, new File(theLocation, ThemisMaven.POM));
72          theName = myPom == null ? null : myPom.getMavenId().getArtifactId();
73  
74          /* Remove own mavenIds from dependency list */
75          theDependencies.removeIf(theModules::containsKey);
76  
77          /* For all dependencies */
78          final List<ThemisMavenId> myDependencies = new ArrayList<>(theDependencies);
79          for (ThemisMavenId myId : myDependencies) {
80              processDependency(myId);
81          }
82      }
83  
84      /**
85       * Process dependency.
86       *
87       * @param pId the maven id
88       */
89      private void processDependency(final ThemisMavenId pId) throws OceanusException {
90          final File myFile = pId.getMavenPomPath();
91          /* Protect against exceptions */
92          try (InputStream myInStream = new FileInputStream(myFile)) {
93              /* Parse the Project definition file */
94              final ThemisMaven myPom = new ThemisMaven(null, myInStream);
95  
96              /* Add any unique dependencies */
97              for (final ThemisMavenId myDepId : myPom.getDependencies()) {
98                  if (!theDependencies.contains(myDepId)) {
99                      theDependencies.add(myDepId);
100                     if (myDepId.getClassifier() == null) {
101                         processDependency(myDepId);
102                     }
103                 }
104             }
105         } catch (IOException e) {
106             throw new ThemisIOException("Failed to parse pom file", e);
107         }
108     }
109 
110     /**
111      * Obtain the name.
112      *
113      * @return the name
114      */
115     public String getName() {
116         return theName;
117     }
118 
119     /**
120      * Obtain the location.
121      *
122      * @return the location
123      */
124     File getLocation() {
125         return theLocation;
126     }
127 
128     /**
129      * Obtain the modules.
130      *
131      * @return the modules
132      */
133     public List<ThemisModule> getModules() {
134         return new ArrayList<>(theModules.values());
135     }
136 
137     /**
138      * Obtain the dependencies.
139      *
140      * @return the dependencies
141      */
142     public List<ThemisMavenId> getDependencies() {
143         return theDependencies;
144     }
145 
146     @Override
147     public String toString() {
148         return theName;
149     }
150 
151     /**
152      * Parse the maven project file.
153      *
154      * @param pParent the parent
155      * @param pPom    the project file
156      * @return the artifact name
157      * @throws OceanusException on error
158      */
159     private ThemisMaven parseProjectFile(final ThemisMaven pParent,
160                                          final File pPom) throws OceanusException {
161         /* If the pom file does not exist, just return */
162         if (!pPom.exists()) {
163             return null;
164         }
165 
166         /* Protect against exceptions */
167         try (InputStream myInStream = new FileInputStream(pPom)) {
168             /* Parse the Project definition file */
169             final ThemisMaven myPom = new ThemisMaven(pParent, myInStream);
170 
171             /* If source directory exists */
172             final File mySrc = new File(pPom.getParent(), ThemisPackage.PATH_XTRA);
173             if (mySrc.exists()
174                     && mySrc.isDirectory()) {
175                 /* Add the module to the list */
176                 theModules.put(myPom.getMavenId(), new ThemisModule(new File(pPom.getParent()), myPom));
177 
178                 /* Add any unique dependencies */
179                 for (final ThemisMavenId myDepId : myPom.getDependencies()) {
180                     if (!theDependencies.contains(myDepId)) {
181                         theDependencies.add(myDepId);
182                     }
183                 }
184             }
185 
186             /* Loop through the modules */
187             for (final String myModuleName : myPom.getModules()) {
188                 /* Access module directory */
189                 final File myModuleDir = new File(pPom.getParentFile(), myModuleName);
190 
191                 /* Process the project file */
192                 parseProjectFile(myPom, new File(myModuleDir, ThemisMaven.POM));
193             }
194 
195             /* Return the POM */
196             return myPom;
197 
198             /* Catch exceptions */
199         } catch (IOException e) {
200             /* Convert Exception */
201             throw new ThemisIOException("Failed to parse Project file", e);
202         }
203     }
204 
205     /**
206      * parse the java code.
207      *
208      * @param pParser the parser
209      * @throws OceanusException on error
210      */
211     public void parseJavaCode(final ThemisParserDef pParser) throws OceanusException {
212         /* Loop through the modules */
213         for (ThemisModule myModule : theModules.values()) {
214             /* Process the module */
215             myModule.parseJavaCode(pParser);
216         }
217     }
218 }