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.themis.parser.base.ThemisChar;
24  import io.github.tonywasher.joceanus.themis.parser.base.ThemisDataResource;
25  import io.github.tonywasher.joceanus.themis.parser.base.ThemisParserDef;
26  
27  import java.io.File;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.Objects;
31  
32  /**
33   * Package.
34   */
35  public class ThemisPackage
36          implements MetisFieldItem {
37      /**
38       * Report fields.
39       */
40      private static final MetisFieldSet<ThemisPackage> FIELD_DEFS = MetisFieldSet.newFieldSet(ThemisPackage.class);
41  
42      /*
43       * Declare Fields.
44       */
45      static {
46          FIELD_DEFS.declareLocalField(ThemisDataResource.DATA_NAME, ThemisPackage::getShortName);
47          FIELD_DEFS.declareLocalField(ThemisDataResource.DATA_FILES, ThemisPackage::getFiles);
48      }
49  
50      /**
51       * The path xtra.
52       */
53      static final String PATH_XTRA = ".src.main.java".replace(ThemisChar.PERIOD, File.separatorChar);
54  
55      /**
56       * The package-info file.
57       */
58      private static final String PACKAGE_INFO = "package-info" + ThemisFile.SFX_JAVA;
59  
60      /**
61       * The package name.
62       */
63      private final String thePackage;
64  
65      /**
66       * The short name.
67       */
68      private final String theShortName;
69  
70      /**
71       * The package name.
72       */
73      private final String theParentName;
74  
75      /**
76       * The location.
77       */
78      private final File theLocation;
79  
80      /**
81       * The list of files in this package.
82       */
83      private final List<ThemisFile> theFiles;
84  
85      /**
86       * Is this a standard package?
87       */
88      private final boolean isStandard;
89  
90      /**
91       * Is this a placeHolder package?
92       */
93      private final boolean isPlaceHolder;
94  
95      /**
96       * Constructor.
97       *
98       * @param pLocation the location
99       * @param pPackage  the package name.
100      */
101     ThemisPackage(final File pLocation,
102                   final String pPackage) {
103         /* Store package name */
104         theLocation = pLocation;
105         thePackage = pPackage;
106         isStandard = pLocation.getAbsolutePath().endsWith(PATH_XTRA);
107         isPlaceHolder = false;
108 
109         /* Determine the short name */
110         final int iIndex = thePackage.lastIndexOf(ThemisChar.PERIOD);
111         theShortName = iIndex == -1 ? thePackage : thePackage.substring(iIndex + 1);
112         theParentName = iIndex == -1 ? null : thePackage.substring(0, iIndex);
113 
114         /* Create directory path and record the location */
115         final String myPath = pPackage.replace(ThemisChar.PERIOD, File.separatorChar);
116         final File myLocation = new File(pLocation, myPath);
117 
118         /* Build list of files */
119         theFiles = listFiles(myLocation);
120     }
121 
122     @Override
123     public MetisFieldSet<ThemisPackage> getDataFieldSet() {
124         return FIELD_DEFS;
125     }
126 
127     @Override
128     public String formatObject(final OceanusDataFormatter pFormatter) {
129         return toString();
130     }
131 
132     /**
133      * Constructor.
134      *
135      * @param pPackage the package name.
136      */
137     public ThemisPackage(final String pPackage) {
138         /* Store package name */
139         theLocation = null;
140         thePackage = pPackage;
141         isStandard = false;
142         isPlaceHolder = true;
143 
144         /* Determine the short name */
145         final int iIndex = thePackage.lastIndexOf(ThemisChar.PERIOD);
146         theShortName = iIndex == -1 ? thePackage : thePackage.substring(iIndex + 1);
147         theParentName = iIndex == -1 ? null : thePackage.substring(0, iIndex);
148 
149         /* Build empty list of files */
150         theFiles = new ArrayList<>();
151     }
152 
153     /**
154      * Obtain the package.
155      *
156      * @return the package
157      */
158     public String getPackage() {
159         return thePackage;
160     }
161 
162     /**
163      * Obtain the shortName.
164      *
165      * @return the shortName
166      */
167     public String getShortName() {
168         return theShortName;
169     }
170 
171     /**
172      * Obtain the parentName.
173      *
174      * @return the parentName
175      */
176     public String getParentName() {
177         return theParentName;
178     }
179 
180     /**
181      * Is this the root package.
182      *
183      * @return true/false
184      */
185     public boolean isRoot() {
186         return theShortName.isEmpty();
187     }
188 
189     /**
190      * Obtain the location.
191      *
192      * @return the location
193      */
194     public File getLocation() {
195         return theLocation;
196     }
197 
198     /**
199      * Obtain the files.
200      *
201      * @return the files
202      */
203     public List<ThemisFile> getFiles() {
204         return theFiles;
205     }
206 
207     /**
208      * Is this a standard package?
209      *
210      * @return true/false
211      */
212     public boolean isStandard() {
213         return isStandard;
214     }
215 
216     /**
217      * Is this a placeHolder package?
218      *
219      * @return true/false
220      */
221     public boolean isPlaceHolder() {
222         return isPlaceHolder;
223     }
224 
225     /**
226      * Build list of files.
227      *
228      * @param pLocation the location
229      * @return the list of files
230      */
231     List<ThemisFile> listFiles(final File pLocation) {
232         /* Allocate the list */
233         final List<ThemisFile> myFiles = new ArrayList<>();
234 
235         /* Loop through the entries in the directory */
236         for (File myEntry : Objects.requireNonNull(pLocation.listFiles())) {
237             /* Handle files */
238             if (!myEntry.isDirectory()) {
239                 /* Access the name of the file */
240                 final String myName = myEntry.getName();
241 
242                 /* If this is a .java that is not package-info */
243                 if (myName.endsWith(ThemisFile.SFX_JAVA)
244                         && !PACKAGE_INFO.equals(myName)) {
245                     /* Add the class */
246                     final ThemisFile myFile = new ThemisFile(myEntry);
247                     myFiles.add(myFile);
248                 }
249             }
250         }
251 
252         /* Return the files */
253         return myFiles;
254     }
255 
256     /**
257      * parse the Java Code.
258      *
259      * @param pParser the parser
260      * @throws OceanusException on error
261      */
262     void parseJavaCode(final ThemisParserDef pParser) throws OceanusException {
263         /* Set the current package */
264         pParser.setCurrentPackage(thePackage);
265 
266         /* Loop through the classes */
267         for (ThemisFile myFile : theFiles) {
268             /* Process the file */
269             myFile.parseJavaCode(pParser);
270         }
271     }
272 
273     @Override
274     public String toString() {
275         return thePackage;
276     }
277 }