1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.ArrayList;
26 import java.util.Deque;
27 import java.util.Iterator;
28 import java.util.List;
29
30
31
32
33 public class ThemisAnalysisFor
34 implements ThemisAnalysisContainer, ThemisAnalysisAdoptable, ThemisAnalysisStatementHolder {
35
36
37
38 private final Deque<ThemisAnalysisElement> theContents;
39
40
41
42
43 private final ThemisAnalysisStack theHeaders;
44
45
46
47
48 private final List<ThemisAnalysisField> theFields;
49
50
51
52
53 private final List<ThemisAnalysisStatement> theStatements;
54
55
56
57
58 private final int theNumLines;
59
60
61
62
63 private final ThemisAnalysisDataMap theDataMap;
64
65
66
67
68 private ThemisAnalysisContainer theParent;
69
70
71
72
73
74
75
76
77 ThemisAnalysisFor(final ThemisAnalysisParser pParser,
78 final ThemisAnalysisLine pLine) throws OceanusException {
79
80 theParent = pParser.getParent();
81 theDataMap = new ThemisAnalysisDataMap(theParent.getDataMap());
82
83
84 final Deque<ThemisAnalysisElement> myHeaders = ThemisAnalysisBuilder.parseHeaders(pParser, pLine);
85 final Deque<ThemisAnalysisElement> myLines = ThemisAnalysisBuilder.processBody(pParser);
86 theNumLines = myHeaders.size() + 1;
87
88
89 theContents = new ArrayDeque<>();
90 final ThemisAnalysisParser myParser = new ThemisAnalysisParser(myLines, theContents, this);
91 myParser.processLines();
92
93
94 theFields = new ArrayList<>();
95 theStatements = new ArrayList<>();
96 theHeaders = new ThemisAnalysisStack(myHeaders);
97 }
98
99 @Override
100 public Deque<ThemisAnalysisElement> getContents() {
101 return theContents;
102 }
103
104 @Override
105 public ThemisAnalysisContainer getParent() {
106 return theParent;
107 }
108
109 @Override
110 public void setParent(final ThemisAnalysisContainer pParent) {
111 theParent = pParent;
112 theDataMap.setParent(pParent.getDataMap());
113 }
114
115 @Override
116 public ThemisAnalysisDataMap getDataMap() {
117 return theDataMap;
118 }
119
120 @Override
121 public int getNumLines() {
122 return theNumLines;
123 }
124
125 @Override
126 public void postProcessExtras() throws OceanusException {
127 parseHeaders();
128 }
129
130 @Override
131 public Iterator<ThemisAnalysisStatement> statementIterator() {
132 final Iterator<ThemisAnalysisStatement> myField = ThemisAnalysisField.statementIteratorForFields(theFields);
133 final Iterator<ThemisAnalysisStatement> myStatement = theStatements.iterator();
134 return new ThemisIteratorChain<>(myField, myStatement);
135 }
136
137
138
139
140
141
142 private void parseHeaders() throws OceanusException {
143
144 final ThemisAnalysisStack myParts = theHeaders.extractParentheses();
145 final ThemisAnalysisScanner myScanner = new ThemisAnalysisScanner(myParts);
146
147
148 char mySep = ThemisAnalysisChar.COLON;
149 if (!myScanner.checkForSeparator(mySep)) {
150 mySep = ThemisAnalysisChar.SEMICOLON;
151 }
152
153
154 boolean isField = true;
155 while (myParts.hasLines()) {
156
157 final Deque<ThemisAnalysisElement> myPart = myScanner.scanForSeparator(mySep);
158 final ThemisAnalysisStack myStack = new ThemisAnalysisStack(myPart);
159 if (myStack.isEmpty()) {
160 continue;
161 }
162
163
164 if (isField) {
165 parseField(myStack);
166 } else {
167 parseStatement(myStack);
168 }
169 isField = false;
170 }
171 }
172
173
174
175
176
177
178
179 private void parseField(final ThemisAnalysisStack pField) throws OceanusException {
180
181 final ThemisAnalysisScanner myScanner = new ThemisAnalysisScanner(pField);
182 myScanner.skipGenerics();
183 ThemisAnalysisField myLast = null;
184 while (pField.hasLines()) {
185 final Deque<ThemisAnalysisElement> myResource = myScanner.scanForSeparator(ThemisAnalysisChar.COMMA);
186 myLast = myLast == null
187 ? new ThemisAnalysisField(getDataMap(), new ThemisAnalysisStack(myResource))
188 : new ThemisAnalysisField(myLast, new ThemisAnalysisStack(myResource));
189 theFields.add(myLast);
190 }
191 }
192
193
194
195
196
197
198
199 private void parseStatement(final ThemisAnalysisStack pStatement) throws OceanusException {
200
201 final ThemisAnalysisScanner myScanner = new ThemisAnalysisScanner(pStatement);
202 while (pStatement.hasLines()) {
203 final Deque<ThemisAnalysisElement> myResource = myScanner.scanForSeparator(ThemisAnalysisChar.COMMA);
204 theStatements.add(new ThemisAnalysisStatement(myResource));
205 }
206 }
207
208 @Override
209 public String toString() {
210
211 final StringBuilder myBuilder = new StringBuilder();
212
213
214 boolean bFirst = true;
215 for (ThemisAnalysisField myField : theFields) {
216
217 if (!bFirst) {
218 myBuilder.append(ThemisAnalysisChar.LF);
219 } else {
220 bFirst = false;
221 }
222
223
224 myBuilder.append(myField);
225 }
226
227
228 for (ThemisAnalysisStatement myStatement : theStatements) {
229
230 if (!bFirst) {
231 myBuilder.append(ThemisAnalysisChar.LF);
232 } else {
233 bFirst = false;
234 }
235
236
237 myBuilder.append(myStatement);
238 }
239
240
241 return myBuilder.toString();
242 }
243 }