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.ThemisDataException;
21  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisContainer.ThemisAnalysisAdoptable;
22  
23  import java.util.ArrayDeque;
24  import java.util.Deque;
25  import java.util.Objects;
26  
27  /**
28   * Embedded Block.
29   */
30  public class ThemisAnalysisEmbedded
31          implements ThemisAnalysisContainer, ThemisAnalysisAdoptable {
32      /**
33       * The Parent.
34       */
35      private ThemisAnalysisContainer theParent;
36  
37      /**
38       * The Header.
39       */
40      private final ThemisAnalysisLine theHeader;
41  
42      /**
43       * The embedded contents.
44       */
45      private final Deque<ThemisAnalysisElement> theEmbedded;
46  
47      /**
48       * The trailer.
49       */
50      private final ThemisAnalysisLine theTrailer;
51  
52      /**
53       * The number of lines.
54       */
55      private final int theNumLines;
56  
57      /**
58       * Constructor.
59       *
60       * @param pParser the parser
61       * @param pType   the embed Type
62       * @param pLine   the initial class line
63       * @throws OceanusException on error
64       */
65      ThemisAnalysisEmbedded(final ThemisAnalysisParser pParser,
66                             final ThemisAnalysisEmbedType pType,
67                             final ThemisAnalysisLine pLine) throws OceanusException {
68          /* Store parameters */
69          theHeader = pLine;
70  
71          /* Build the embedded content */
72          theEmbedded = new ArrayDeque<>();
73          switch (pType) {
74              case LAMBDA:
75                  theEmbedded.add(new ThemisAnalysisLambda(pParser, pLine));
76                  break;
77              case ANON:
78                  theEmbedded.add(new ThemisAnalysisAnonClass(pParser, pLine));
79                  break;
80              case ARRAY:
81                  theEmbedded.add(new ThemisAnalysisArrayInit(pParser, pLine));
82                  break;
83              case NONE:
84              default:
85                  break;
86          }
87  
88          /* Store parent */
89          theParent = pParser.getParent();
90  
91          /* Parse the body */
92          theNumLines = 2;
93  
94          /* Pop the trailing line */
95          theTrailer = (ThemisAnalysisLine) pParser.popNextLine();
96  
97          /* Make sure that there is a trailing semicolon */
98          if (!theTrailer.endsWithChar(ThemisAnalysisChar.SEMICOLON)) {
99              throw new ThemisDataException("Invalid embedded item");
100         }
101     }
102 
103     /**
104      * Obtain the header.
105      *
106      * @return the header
107      */
108     ThemisAnalysisLine getHeader() {
109         return theHeader;
110     }
111 
112     @Override
113     public Deque<ThemisAnalysisElement> getContents() {
114         return theEmbedded;
115     }
116 
117     @Override
118     public ThemisAnalysisContainer getParent() {
119         return theParent;
120     }
121 
122     @Override
123     public void setParent(final ThemisAnalysisContainer pParent) {
124         theParent = pParent;
125         theEmbedded.forEach(e -> ((ThemisAnalysisAdoptable) e).setParent(pParent));
126     }
127 
128     @Override
129     public ThemisAnalysisDataMap getDataMap() {
130         return ((ThemisAnalysisContainer) Objects.requireNonNull(theEmbedded.peekFirst())).getDataMap();
131     }
132 
133     @Override
134     public int getNumLines() {
135         return theNumLines;
136     }
137 
138     /**
139      * Check For embedded type.
140      *
141      * @param pLine the line
142      * @return the embedded type
143      */
144     static ThemisAnalysisEmbedType checkForEmbedded(final ThemisAnalysisLine pLine) {
145         if (ThemisAnalysisLambda.checkLambda(pLine)) {
146             return ThemisAnalysisEmbedType.LAMBDA;
147         }
148         if (ThemisAnalysisAnonClass.checkAnon(pLine)) {
149             return ThemisAnalysisEmbedType.ANON;
150         }
151         if (ThemisAnalysisArrayInit.checkArrayInit(pLine)) {
152             return ThemisAnalysisEmbedType.ARRAY;
153         }
154         if (ThemisAnalysisMethodBody.checkMethodBody(pLine)) {
155             return ThemisAnalysisEmbedType.METHOD;
156         }
157         return ThemisAnalysisEmbedType.NONE;
158     }
159 
160     /**
161      * The embedded Type.
162      */
163     enum ThemisAnalysisEmbedType {
164         /**
165          * Lambda.
166          */
167         LAMBDA,
168 
169         /**
170          * AnonClass.
171          */
172         ANON,
173 
174         /**
175          * ArrayInit.
176          */
177         ARRAY,
178 
179         /**
180          * MethodBody.
181          */
182         METHOD,
183 
184         /**
185          * None.
186          */
187         NONE;
188     }
189 }