/
UmpleInternalParser_CodeMixset.ump
675 lines (608 loc) · 24.2 KB
/
UmpleInternalParser_CodeMixset.ump
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
/*
Copyright: All contributers to the Umple Project
This file is made available subject to the open source license found at:
http://umple.org/license
This file analyzses mixset related tokens to populate the Umple meta model for
mixsets.
Please refer to UmpleInternalParser.ump for more details.
*/
namespace cruise.umple.compiler;
class UmpleModel{
/*
* This method returns a mixset from UmpleModel based on its name.
* return null if the mixset is not found.
* @Abdulaziz
*/
Mixset getMixset(String name) {
Mixset mixset = null;
for(MixsetOrFile mOrF : getMixsetOrFiles())
{
if (mOrF.getIsMixset() && mOrF.getName().equals(name))
mixset = (Mixset)mOrF;
}
return mixset;
}
/*
* This method returns UmpleFile from UmpleModel based on its name.
* return null if the mixset is not found.
* usage: to know if the file in which a mixset is mentioned was already used before.
* @Abdulaziz
*/
UmpleFile getUmpleFile(String name){
UmpleFile uFile = null;
for(MixsetOrFile mOrF : getMixsetOrFiles())
{
if (! mOrF.getIsMixset() && mOrF.getName().equals(name))
uFile = (UmpleFile)mOrF;
}
return uFile;
}
}
class UmpleInternalParser
{
depend cruise.umple.compiler.UmpleFile;
depend java.util.stream.*;
Map<String, Boolean> parsedUmpfiles = new HashMap<>(); // The key is to store names of parsed umple files. The value is to specify if fully parsed file (true) or partially (false).
after init
{
parser.addGrammarFile("/mixset/umple_mixsets.grammar");
}
mixset StateMachine {
// prepare mixsets that are inside a state machine.
private void analyzeMixsetDefinition(List<Token> tokenList , StateMachine stateMachine)
{
if (tokenList.size() < 1)
return;
for(Token aToken : tokenList)
{
if(stateMachine.getUmpleClass().getName() == null)
return;
//otherwise
analyzeMixsetBodyToken(aToken);
}
}
}
private void analyzeMixsetBodyToken(Token token)
{
Token mixsetBodyToken = token.getSubToken("extraCode");
// Code bellow accepts a one element and changes it to be an extraCode
// To allow one element mixset that is placed inside a class, trait, etc.
if (token.getSubToken("oneElement") != null)
{
Token oneElementToken = token.getSubToken("oneElement");
oneElementToken.setValue(oneElementToken.getValue()+" ;");
oneElementToken.setName("extraCode");
mixsetBodyToken = oneElementToken;
}
// end
if(mixsetBodyToken == null)
{
String mixsetName = token.getSubToken("mixsetName").getValue();
getParseResult().addErrorMessage(new ErrorMessage(1511,token.getPosition(), mixsetName));
return;
}
else
mixsetBodyToken.setValue(getMixsetFragmentWithEnclosingElement(token,mixsetBodyToken.getValue()));
analyzeMixset(token);
}
// This method takes a mixset fragment and adds its context.
private String getMixsetFragmentWithEnclosingElement(Token token, String mixsetBody)
{
if (token.is("ROOT") || token == null)
return mixsetBody ;
String tokenKey ="";
String prefix ="";
boolean returnMixsetBody= false;
mixset Class {
if (token.is("classDefinition"))
{
tokenKey = "name";
prefix ="class";
returnMixsetBody= true;
}
}
mixset StateMachine {
else if (token.is("state"))
{
tokenKey = "stateName";
}
else if (token.is("inlineStateMachine"))
{
tokenKey = "name";
}
}
mixset Trait {
else if (token.is("traitDefinition"))
{
tokenKey = "name";
prefix ="trait";
returnMixsetBody= true;
}
}
mixset Association {
else if (token.is("associationDefinition"))
{
tokenKey = "name";
prefix ="association";
}
}
if(! tokenKey.equals(""))
{
mixsetBody = " "+prefix +" "+ token.getValue(tokenKey) + " { " + mixsetBody + " } ";
if(returnMixsetBody)
return mixsetBody;
}
return getMixsetFragmentWithEnclosingElement(token.getParentToken(), mixsetBody) ;
}
/*
* This method handles mixset use statements appearing in both code and in the console. The method adds mixset use statements to umple model in the first round on analysis, before
* other umple elements are added to umple model. So, there is no issue regarding which line the mixset use statements are mentioned in.
*/
private void analyzeMixsetUseStatement(Token t, int analysisStep){
if (analysisStep != 1) // the analyze occurs just for analysisStep == 1.
{
return;
}
//else
if (t.is("useStatement"))
{
String value = t.getValue("use");
// ignore .ump files since they are proccessed in UseStatementParserAction class (UmpleInternalParser_CodeParserHandlers.ump).
if (value.endsWith(".ump"))
{
return;
}
//Otherwise
int useLineNumber = t.getPosition().getLineNumber();
//UmpleFile mixsetUseFile = model.getUmpleFile();
String fileName = t.getPosition().getFilename();
UmpleFile mixsetUseFile = new UmpleFile(fileName);
ArrayList<String> mixsetNames = new ArrayList<String>();
mixsetNames.add(value); // add first use.
for(Token subToken : t.getSubTokens()) // add the rest of use-statment that are in : use M1,M2, ...
{
if(subToken.is("extraUse"))
mixsetNames.add(subToken.getValue("extraUse"));
}
for (String mixsetName : mixsetNames)
{
// check if the mixset was added before
Mixset mixset = model.getMixset(mixsetName.trim());
if(mixset == null)
{
mixset = new Mixset(mixsetName);
mixset.setUseUmpleFile(mixsetUseFile);
mixset.setUseUmpleLine(useLineNumber);
model.addMixsetOrFile(mixset);
}
else if (mixset.getUseUmpleFile() == null)
{
mixset.setUseUmpleFile(mixsetUseFile);
mixset.setUseUmpleLine(useLineNumber);
}
// this handles the case when a mixset definition is in a file and the mixset use exists in a subsequent file.
parseMixset(mixset);
}
}
}
/*
* This method parses all waiting fragments of a mixset, if there is a mixset-use-statment specified in some of the files.
*/
/*
private void parseMixset(){
for (MixsetOrFile mOrF : model.getMixsetOrFiles())
{
if(mOrF.getIsMixset() && (mOrF.getUseUmpleFile() != null) ) // the second condition is to check if there is a use statement.
{
Mixset mixset =(Mixset) mOrF;
for(MixsetFragment mixsetWaitingFrag: mixset.getFragments())
{
//String allMixsetBody = modelMixset.getWaitingFragments().stream().map(mixsetFrag -> mixsetFrag.getBody()).collect(Collectors.joining(" "));
ParseResult pResult= parse("MixsetFragmentParsing", mixsetWaitingFrag.getBody());
Token answer = parser.getRootToken(); // result of parsing the body of a mixset waitingFragments
analyzeAllTokens(answer);
}
}
}
}
*/
/*
* This method loops through a mixset to parse its waiting fragments.
* It should be used after checking existing of a mixset-use-statment.
*/
private void parseMixset(Mixset mixset){
for(MixsetFragment mixsetFragment: mixset.getMixsetFragments())
{
if(mixsetFragment.getIsParsed())
continue;
//Otherwise
parseMixsetWaitingFragment(mixsetFragment);
}
}
/*
* This method parses a waiting fragment of a mixset.
* It should be used after checking existing of a mixset-use-statment.
*/
depend cruise.umple.compiler.exceptions.*;
private void parseMixsetWaitingFragment(MixsetFragment mixsetFragment){
if(! mixsetFragment.getIsParsed()) // a fragment that is not parsed before.
{
String mixsetFragmentFile = mixsetFragment.getOriginalUmpFile().getPath()+"/"+mixsetFragment.getOriginalUmpFile().getFileName();
int mixsetFragmentLine = mixsetFragment.getOriginalUmpLine() - 1;
/* This additon to mixset fragment body becuase init(.....) of ParserDataPackage splits by '\\n', and then its stores the splited string appended with a newline
* in its 'input' filed. If there is an error at the last item of the mixset body, umple will not figure out the correct postion of the error. Because 'input' has
* items end with new line, while the original string may not end with empty line. Adding "\n;" to the body fixes the issue.
*/
String mixsetFragmentBodyExtraLine = mixsetFragment.getBody()+"\n;";
ParseResult result= parse("MixsetFragmentParsing", mixsetFragmentBodyExtraLine, mixsetFragmentFile, null, mixsetFragmentLine,0);
setParseResult(result);
Token answer = parser.getRootToken(); // result of parsing the body of a mixset waitingFragments
setRootToken(answer);
model.setLastResult(result);
answer.setName("mixsetDefinition"); //attach the mixset name for the fragment instead of ROOT
answer.setValue(mixsetFragment.getMixset().getMixsetName());
analyzeAllTokens(answer);
mixsetFragment.setIsParsed(true);
}
}
private void analyzeMixsetToken(Token t, int analysisStep)
{
if (analysisStep != 2)
{
shouldProcessAgain = shouldProcessAgain || (analysisStep == 1);
return;
}
if (t.is("mixsetDefinition"))
{
analyzeMixset(t);
}
}
private Mixset analyzeMixset(Token token){
String mixsetName = token.getValue("mixsetName");
// check if the mixset is was not added before
Mixset mixset = model.getMixset(mixsetName);
if(mixset == null)
{
mixset = new Mixset(mixsetName);
model.addMixsetOrFile(mixset);
}
//inline mixset def.
MixsetFragment mixsetFragment = createMixsetFragment(token, mixset);
if(mixsetFragment == null)
return mixset;
//else
// Here the mixset fragment is considered as waitingFragment (mixsetFragment.isParsed==false).
mixset.addMixsetFragment(mixsetFragment);
mixsetFragment.setMixset(mixset);
// parse mixset fragments right away if there is a use-statement.
if(mixset.getUseUmpleFile() != null)
parseMixsetWaitingFragment(mixsetFragment);
return mixset;
}
private MixsetFragment createMixsetFragment(Token token, Mixset mixset) {
MixsetFragment mixsetFragment = createMixsetFragment(token);
if(mixsetFragment == null || mixset == null)
return null;
else
mixsetFragment.setMixset(mixset);
return mixsetFragment;
}
private MixsetFragment createMixsetFragment(Token token) {
Position mixsetFragmentPosition = null;
int mixsetFragmentLineNumber = 0;
String mixsetBody = token.getValue("extraCode");
if(mixsetBody != null)
{
mixsetFragmentPosition = token.getSubToken("extraCode").getPosition();
}
String entityType = token.getValue("entityType");
String entityName = token.getValue("entityName");
// mixset with one element
String oneElementMixset = token.getValue("oneElement");
if(entityType != null) {
if (oneElementMixset != null)
{
mixsetBody = entityType + " "+entityName + " { "+ oneElementMixset + " }";
mixsetFragmentPosition = token.getSubToken("oneElementMixset").getPosition();
}
else
mixsetBody = entityType + " "+entityName + " { "+ mixsetBody + " }";
mixsetFragmentPosition = token.getSubToken("extraCode").getPosition();
}
else if (oneElementMixset != null)
{
mixsetBody = oneElementMixset;
mixsetFragmentPosition = token.getSubToken("oneElementMixset").getPosition();
}
if(mixsetBody == null)
return null; // because there is no fragment to add.
mixsetFragmentLineNumber = mixsetFragmentPosition.getLineNumber();
UmpleFile mixsetFragmentUmpleFile = model.getUmpleFile(); // where the mixset keyword is encountered. Not the use statement
// Start: update the fragment file if the fragment came from a file included by use statement.
Token lookForUseStToken = token;
while((lookForUseStToken = lookForUseStToken.getParentToken()) != null)
{
if(lookForUseStToken.is("useStatement"))
{
mixsetFragmentUmpleFile = new UmpleFile(lookForUseStToken.getSubToken("use").getValue());
break;
}
}
//End
MixsetFragment mixsetFragment = new MixsetFragment(mixsetFragmentUmpleFile, mixsetFragmentLineNumber, mixsetBody);
return mixsetFragment;
}
// this method specifies kinds of tokens to be parsed for unused mixset.
private void parseMixsetNotUsedToken(Token token){
mixset FeatureModel {
//parse require statments.
analyzeRequireStatement(token, 2);
}
// parse nested mixset def.
if(token.is("mixsetDefinition"))
{
String mixsetName = token.getValue("mixsetName");
// check if the mixset is was not added before
Mixset mixset = model.getMixset(mixsetName);
if(mixset == null)
{
mixset = new Mixset(mixsetName);
model.addMixsetOrFile(mixset);
}
parseMixsetFragmentNotUsed(createMixsetFragment(token), mixset.getName());
}
}
private void parseMixsetFragmentNotUsed(MixsetFragment mixsetFragment, String parentMixset){
if(mixsetFragment == null)
return;
//else
if(! mixsetFragment.getIsParsed()) // process a fragment that has not been parsed.
{
String mixsetFragmentFile = mixsetFragment.getOriginalUmpFile().getPath()+"/"+mixsetFragment.getOriginalUmpFile().getFileName();
int mixsetFragmentLine = mixsetFragment.getOriginalUmpLine() - 1;
String mixsetFragmentBodyExtraLine = mixsetFragment.getBody()+"\n;";
ParseResult result= parse("MixsetFragmentParsing", mixsetFragmentBodyExtraLine, mixsetFragmentFile, null, mixsetFragmentLine,0);
setParseResult(result);
Token answer = getParser().getRootToken(); // result of parsing the body of a MixsetFragment
// setRootToken(answer);
// model.setLastResult(result);
answer.setName("mixsetDefinition"); //attach the mixset name for the fragment instead of ROOT
answer.setValue(parentMixset);
// getIsFeature()
//isFeature + umpFiles(use-st) + require-st
for(Token token : answer.getSubTokens())
{
parseMixsetNotUsedToken(token);
// an ump file included in an unused mixset: it should be partially parsed to know mixsets' dependencies.
//
if (token.is("useStatement"))
{
String umpFileName = token.getSubToken("use").getValue();
if(parsedUmpfiles.keySet().contains(umpFileName)) // accept a file that has not been parsed before.
return;
//else
for (Token subToken : token.getSubTokens())
{
parseMixsetNotUsedToken(subToken);
}
parsedUmpfiles.put(umpFileName, false); // add current file to partially parsed files.
}
}
}
}
/*
* This method does partial parsing for mixsets that have no use-statements.
*/
private void parseMixsetsNotUsed() {
List<Mixset> mixsetList = model.getMixsetOrFiles().stream().filter(mixset -> mixset.getIsMixset()).map(obj -> (Mixset)obj).collect(Collectors.toList());
for (Mixset aMixset: mixsetList)
{
List<MixsetFragment>mixsetFragmentList = aMixset.getMixsetFragments();
for(MixsetFragment aMixsetFragment : mixsetFragmentList)
{
if(aMixsetFragment.getIsParsed()) // the fragment is already parsed
continue;
else
{
parseMixsetFragmentNotUsed(aMixsetFragment, aMixsetFragment.getMixset().getName());
}
}
}
}
// a helper method that process pure code to either remove it or to let mixset content stay.
private String processInlineMixset(String methodCode, MethodBody methodBody) {
// process mixsets inside code
ArrayList<MixsetInMethod> mixsetInCodeList = MethodBody.getMixsetsFromCode(methodCode) ;
for (MixsetInMethod aMixsetInMethod : mixsetInCodeList)
{
// update the code according to use statements (of mixsets)
methodCode = MethodBody.handelMixsetInsideMethod(this.getModel(), aMixsetInMethod, methodCode);
if(methodBody !=null)
{
methodBody.addMixsetInMethod(aMixsetInMethod);
}
}
return methodCode;
}
}
mixset AspectInjection {
class CodeInjection{
String injectionlabel = "";
boolean codeBlockProcessed = false;
boolean hasCodeLabel()
{
return ! injectionlabel.equals("");
}
}
class CodeBlock{
depend java.util.regex.Matcher;
depend java.util.regex.Pattern;
public ArrayList<String> getCodeWithLabels(String codesKey) {
ArrayList <String> codeLabels = new ArrayList<String>();
String codeToLockAt = getCode(codesKey);
ArrayList<String> codeWithLabels = new ArrayList<String>();
Pattern labelPatternToMatch = Pattern.compile("(\\S+):");
Matcher matcher = labelPatternToMatch.matcher(codeToLockAt);
int lastMatchedIndex=0;
while (matcher.find()) {
String codeBeforeLabel = codeToLockAt.substring(lastMatchedIndex, matcher.start());
if(!codeBeforeLabel.equals(""))
codeWithLabels.add(codeBeforeLabel);
codeWithLabels.add(matcher.group()); //add the label itself to the source code.
codeLabels.add(matcher.group().replaceFirst(":","")); // remove colon and add it the list of labels
lastMatchedIndex = matcher.end();
}
// This for last label, to add the code after last matched label
String codeAfterLastLabel =codeToLockAt.substring(lastMatchedIndex);
codeWithLabels.add(codeAfterLastLabel);
return codeWithLabels;
}
}
class MethodBody
{
depend java.util.regex.Matcher;
depend java.util.regex.Pattern;
public static int indexOfMixsetClosingBracket(String strInput) {
int closeIndex = 0;
int numOfclosingBracket=0;
for(int i = 0; i< strInput.length();i++)
{
char currentChar = strInput.charAt(i);
if(currentChar =='{')
numOfclosingBracket++;
else if(currentChar == '}')
{
numOfclosingBracket--;
if(numOfclosingBracket==0)
{
closeIndex = i+1;
break;
}
}
}
return closeIndex;
}
public ArrayList<MixsetInMethod> getMixsetsWithinMethod(){
return getMixsetsFromCode(this.getCodeblock().getCode());
}
public static ArrayList<MixsetInMethod> getMixsetsFromCode(String codeToLockAt){
ArrayList<MixsetInMethod> mixsetInsideMethodList = new ArrayList<MixsetInMethod>();
Pattern labelPatternToMatch = Pattern.compile("mixset\\s+\\S+\\s+\\{"); // to detect mixset def.
Matcher matcher = labelPatternToMatch.matcher(codeToLockAt);
while (matcher.find()) {
String mixsetDefPlusAfterCode = codeToLockAt.substring(matcher.start());
// mixset def. + the code after the mixset def.
int indexOfMixsetClosingBracket = matcher.start() + indexOfMixsetClosingBracket(mixsetDefPlusAfterCode);
String mixsetBodyWithDef = codeToLockAt.substring(matcher.start(),indexOfMixsetClosingBracket);
// get the name of the mixset
String mixsetName = matcher.group().replace("mixset", "").replace("{", "").trim();
MixsetInMethod mixsetInsideMethod = new MixsetInMethod(mixsetName,matcher.start(),indexOfMixsetClosingBracket,mixsetBodyWithDef);
// place inner method in their right position.
for(MixsetInMethod tempMixsetInMethod:mixsetInsideMethodList)
{
if(mixsetInsideMethod.getStartPositionIndex() > tempMixsetInMethod.getStartPositionIndex()
& mixsetInsideMethod.getEndPositionIndex() < tempMixsetInMethod.getEndPositionIndex())
{
// a nested mixset should be bounded by its close parent mixset
mixsetInsideMethod.setParentInnerMixset(tempMixsetInMethod);
tempMixsetInMethod.addChildMixset(mixsetInsideMethod);
}
}
// a nested mixset should not add here.
if(mixsetInsideMethod.getParentInnerMixset() == null) // its not bounded by another mixset
{
mixsetInsideMethodList.add(mixsetInsideMethod);
}
}
return mixsetInsideMethodList;
}
}
}
mixset Template {
class TemplateDefinitionWalker {
depend java.util.ArrayList;
private void handleTemplateTokenContainMixset(Token codeToken) {
if (codeToken != null)
{
String codeToLookAt = codeToken.getValue();
ArrayList<MixsetInMethod> mixsetWithinTemplate = MethodBody.getMixsetsFromCode(codeToLookAt);
if (mixsetWithinTemplate.size() > 0) {
for (MixsetInMethod inlineMixsetFragment : mixsetWithinTemplate) {
codeToLookAt = MethodBody.handelMixsetInsideMethod(this.getParser().getModel(), inlineMixsetFragment,codeToLookAt);
codeToken.setValue(codeToLookAt);
}
}
}
}
private void processInlineMixset(Token aToken) {
Token templateTextContentToken = null;
Token templateAttributeToken = aToken.getSubToken("templateAttribute");
for (Token templateAttributeSubToken : templateAttributeToken.getSubTokens())
{
Token templateCodeBlock = templateAttributeSubToken.getSubToken("templateCodeBlock");
if (templateCodeBlock != null)
{
// handle inline mixsets within Template CodeBlock
Token templateLanguageCodeToken = templateCodeBlock.getSubToken("templateLanguageCode");
handleTemplateTokenContainMixset(templateLanguageCodeToken);
}
// handle inline mixsets within Template templateTextContent
if (templateAttributeSubToken == null || templateAttributeSubToken.getSubTokens().size() < 1)
continue;
Token templateTextContent_sub = templateAttributeSubToken.getSubToken("templateTextContent");
if (templateTextContent_sub != null)
{
templateTextContentToken = templateAttributeSubToken.getSubToken("templateTextContent");
if (templateTextContentToken == null)
continue;
//else
handleTemplateTokenContainMixset(templateTextContentToken);
}
}
}
}
class MethodBody {
public static String handelMixsetInsideMethod(UmpleModel umodel, MixsetInMethod mixsetInMethod, String sourceCodeBody)
{
Mixset mixset = umodel.getMixset(mixsetInMethod.getMixsetName());
boolean mixsetIsUsed = false;
try {
if(mixset != null) // the mixset has been used.
{
if(mixset.getUseUmpleFile() != null)
{
mixsetIsUsed = true;
//first process children
for(MixsetInMethod childMixsetInMethod : mixsetInMethod.getChildMixsets())
sourceCodeBody = handelMixsetInsideMethod(umodel, childMixsetInMethod, sourceCodeBody);
//Then ...
String methodCode = sourceCodeBody;
Pattern labelPatternToMatch = Pattern.compile("mixset\\s+\\S+\\s+\\{");
Matcher matcher = labelPatternToMatch.matcher(methodCode);
// below code, to delete mixset def. and its closing bracket.
if (matcher.find()) {
String mixsetDefPlusAfterCode = methodCode.substring(matcher.start());
int indexOfMixsetClosingBracket = matcher.start() + MethodBody.indexOfMixsetClosingBracket(mixsetDefPlusAfterCode) - 1 ;
String methodCodeRemovedMixset = methodCode.substring(0,indexOfMixsetClosingBracket) + " " ; // remove closing bracket
if(indexOfMixsetClosingBracket + 1 < methodCode.length())
methodCodeRemovedMixset = methodCodeRemovedMixset + methodCode.substring(indexOfMixsetClosingBracket +1);
methodCodeRemovedMixset = methodCodeRemovedMixset.substring(0,matcher.start()) + methodCodeRemovedMixset.substring(matcher.end()+1); // remove mixset def.
sourceCodeBody = methodCodeRemovedMixset;
}
}
}
}
finally
{
if(!mixsetIsUsed)
{
// delete body of unused mixsets
String mixsetInMethodCode = mixsetInMethod.getMixsetFragment();
String code = sourceCodeBody.replace(mixsetInMethodCode, "");
sourceCodeBody = code;
}
}
return sourceCodeBody; // after processing
}
}
}