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.solver.proj;
18  
19  import io.github.tonywasher.joceanus.themis.parser.base.ThemisChar;
20  import io.github.tonywasher.joceanus.themis.parser.proj.ThemisModule;
21  import io.github.tonywasher.joceanus.themis.parser.proj.ThemisPackage;
22  import io.github.tonywasher.joceanus.themis.solver.proj.ThemisSolverDef.ThemisSolverModuleDef;
23  import io.github.tonywasher.joceanus.themis.solver.proj.ThemisSolverDef.ThemisSolverProjectDef;
24  
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  /**
32   * Solver Module.
33   */
34  public class ThemisSolverModule
35          implements ThemisSolverModuleDef {
36      /**
37       * The root package.
38       */
39      public static final String ROOT = "";
40  
41      /**
42       * The owning project.
43       */
44      private final ThemisSolverProjectDef theProject;
45  
46      /**
47       * The underlying module.
48       */
49      private final ThemisModule theModule;
50  
51      /**
52       * The list of packages.
53       */
54      private final Map<String, ThemisSolverPackage> thePackages;
55  
56      /**
57       * Constructor.
58       *
59       * @param pProject the owning project
60       * @param pModule  the parsed module
61       */
62      ThemisSolverModule(final ThemisSolverProjectDef pProject,
63                         final ThemisModule pModule) {
64          /* Store the parameters */
65          theProject = pProject;
66          theModule = pModule;
67  
68          /* Initialise the packages */
69          thePackages = new LinkedHashMap<>();
70          for (ThemisPackage myPackage : theModule.getPackages()) {
71              final ThemisSolverPackage mySolverPackage = new ThemisSolverPackage(this, myPackage);
72              thePackages.put(mySolverPackage.getPackageName(), mySolverPackage);
73          }
74  
75          /* Create placeHolders*/
76          createPlaceHolders();
77      }
78  
79      @Override
80      public ThemisSolverProjectDef getOwningProject() {
81          return theProject;
82      }
83  
84      @Override
85      public ThemisModule getUnderlyingModule() {
86          return theModule;
87      }
88  
89      /**
90       * Obtain the packages.
91       *
92       * @return the packages
93       */
94      public Map<String, ThemisSolverPackage> getPackages() {
95          return thePackages;
96      }
97  
98      @Override
99      public String toString() {
100         return theModule.toString();
101     }
102 
103     /**
104      * Create placeHolder packages.
105      */
106     private void createPlaceHolders() {
107         /* Create a list and map of real packages */
108         final HashMap<String, ThemisSolverPackage> myPackageMap = new HashMap<>(thePackages);
109         final List<ThemisSolverPackage> myPackages = new ArrayList<>(thePackages.values());
110 
111         /* Loop through the full packages */
112         for (ThemisSolverPackage myPackage : myPackages) {
113             /* Add the parent link */
114             addParentLink(myPackageMap, myPackage);
115         }
116     }
117 
118     /**
119      * Create placeHolder packages.
120      *
121      * @param pPackageMap the referenceMap
122      * @param pPackage    the package
123      */
124     private void addParentLink(final Map<String, ThemisSolverPackage> pPackageMap,
125                                final ThemisSolverPackage pPackage) {
126         /* Determine name of parent package */
127         final String myName = pPackage.getPackageName();
128         final int iIndex = myName.lastIndexOf(ThemisChar.PERIOD);
129         final String myParentName = iIndex == -1 ? ROOT : myName.substring(0, iIndex);
130 
131         /* Look up parent */
132         ThemisSolverPackage myParent = pPackageMap.get(myParentName);
133 
134         /* If we did not find a parent */
135         if (myParent == null) {
136             /* Create a placeholder parent and put into maps */
137             myParent = new ThemisSolverPackage(this, new ThemisPackage(myParentName));
138             pPackageMap.put(myParentName, myParent);
139             thePackages.put(myParentName, myParent);
140 
141             /* Add further links if we have not reached ROOT */
142             if (!ROOT.equals(myParentName)) {
143                 addParentLink(pPackageMap, myParent);
144             }
145         }
146 
147         /* Add child to parent */
148         myParent.addChild(pPackage);
149     }
150 
151     /**
152      * Look for packages that are immediate roots.
153      *
154      * @return the immediate roots
155      */
156     public ThemisSolverPackage getRoot() {
157         /* Return the root */
158         return thePackages.get(ROOT);
159     }
160 }