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.lethe.analysis.ThemisAnalysisContainer.ThemisAnalysisAdoptable;
21  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisIf.ThemisIteratorChain;
22  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisStatement.ThemisAnalysisStatementHolder;
23  
24  import java.util.ArrayDeque;
25  import java.util.Collections;
26  import java.util.Deque;
27  import java.util.Iterator;
28  
29  /**
30   * Else construct.
31   */
32  public class ThemisAnalysisElse
33          implements ThemisAnalysisContainer, ThemisAnalysisAdoptable, ThemisAnalysisStatementHolder {
34      /**
35       * The parent.
36       */
37      private ThemisAnalysisContainer theParent;
38  
39      /**
40       * The condition.
41       */
42      private final ThemisAnalysisStatement theCondition;
43  
44      /**
45       * The contents.
46       */
47      private final Deque<ThemisAnalysisElement> theContents;
48  
49      /**
50       * The else clause(s).
51       */
52      private final ThemisAnalysisElse theElse;
53  
54      /**
55       * The number of lines.
56       */
57      private final int theNumLines;
58  
59      /**
60       * The dataMap.
61       */
62      private final ThemisAnalysisDataMap theDataMap;
63  
64      /**
65       * Constructor.
66       *
67       * @param pParser the parser
68       * @param pOwner  the owning if
69       * @param pLine   the initial else line
70       * @throws OceanusException on error
71       */
72      ThemisAnalysisElse(final ThemisAnalysisParser pParser,
73                         final ThemisAnalysisContainer pOwner,
74                         final ThemisAnalysisLine pLine) throws OceanusException {
75          /* Record the parent */
76          theParent = pOwner;
77          theDataMap = new ThemisAnalysisDataMap(theParent.getDataMap());
78  
79          /* Strip any if token */
80          pLine.stripStartSequence(ThemisAnalysisKeyWord.IF.getKeyWord());
81  
82          /* Parse the condition */
83          final Deque<ThemisAnalysisElement> myHeaders = ThemisAnalysisBuilder.parseHeaders(pParser, pLine);
84          theNumLines = myHeaders.size() + 1;
85          theCondition = new ThemisAnalysisStatement(myHeaders);
86  
87          /* Parse the body */
88          final Deque<ThemisAnalysisElement> myLines = ThemisAnalysisBuilder.processBody(pParser);
89  
90          /* Look for else clauses */
91          theElse = (ThemisAnalysisElse) pParser.processExtra(pOwner, ThemisAnalysisKeyWord.ELSE);
92  
93          /* Create a parser */
94          theContents = new ArrayDeque<>();
95          final ThemisAnalysisParser myParser = new ThemisAnalysisParser(myLines, theContents, this);
96          myParser.processLines();
97      }
98  
99      @Override
100     public Deque<ThemisAnalysisElement> getContents() {
101         return theContents;
102     }
103 
104     @Override
105     public Iterator<ThemisAnalysisStatement> statementIterator() {
106         final Iterator<ThemisAnalysisStatement> myLocal = theCondition.nullParameters()
107                 ? Collections.emptyIterator()
108                 : Collections.singleton(theCondition).iterator();
109         return theElse == null ? myLocal : new ThemisIteratorChain<>(myLocal, theElse.statementIterator());
110     }
111 
112     @Override
113     public Iterator<ThemisAnalysisContainer> containerIterator() {
114         return theElse == null
115                 ? Collections.emptyIterator()
116                 : Collections.singleton((ThemisAnalysisContainer) theElse).iterator();
117     }
118 
119     @Override
120     public ThemisAnalysisContainer getParent() {
121         return theParent;
122     }
123 
124     @Override
125     public void setParent(final ThemisAnalysisContainer pParent) {
126         theParent = pParent;
127         theDataMap.setParent(pParent.getDataMap());
128         if (theElse != null) {
129             theElse.setParent(pParent);
130         }
131     }
132 
133     @Override
134     public ThemisAnalysisDataMap getDataMap() {
135         return theDataMap;
136     }
137 
138     @Override
139     public void postProcessExtras() throws OceanusException {
140         /* Process the else clause if required */
141         if (theElse != null) {
142             theElse.postProcessLines();
143         }
144     }
145 
146     /**
147      * Obtain the additional else clause (if any).
148      *
149      * @return the else clause
150      */
151     public ThemisAnalysisElse getElse() {
152         return theElse;
153     }
154 
155     @Override
156     public int getNumLines() {
157         return theNumLines;
158     }
159 
160     @Override
161     public String toString() {
162         return theCondition.toString();
163     }
164 }