11package de .vill .main ;
22
33import de .vill .model .*;
4+ import de .vill .model .building .AbstractUVLElementFactory ;
5+ import de .vill .model .building .DefaultUVLElementFactory ;
6+ import de .vill .model .building .FeatureModelBuilder ;
47import de .vill .model .building .VariableReference ;
58import de .vill .model .constraint .*;
69import de .vill .model .expression .*;
3437import org .antlr .v4 .runtime .ConsoleErrorListener ;
3538import org .antlr .v4 .runtime .RecognitionException ;
3639import org .antlr .v4 .runtime .Recognizer ;
37- import org .antlr .v4 .runtime .tree .ParseTreeWalker ;
3840
3941import java .io .IOException ;
4042import java .nio .file .FileSystems ;
@@ -47,10 +49,16 @@ public class UVLModelFactory {
4749
4850 private final Map <LanguageLevel , Class <? extends IConversionStrategy >> conversionStrategiesDrop ;
4951 private final Map <LanguageLevel , Class <? extends IConversionStrategy >> conversionStrategiesConvert ;
52+ private final AbstractUVLElementFactory elementFactory ;
5053
5154 private final List <ParseError > errorList = new LinkedList <>();
5255
5356 public UVLModelFactory () {
57+ this (new DefaultUVLElementFactory ());
58+ }
59+
60+ public UVLModelFactory (AbstractUVLElementFactory elementFactory ) {
61+ this .elementFactory = elementFactory ;
5462 this .conversionStrategiesDrop = new HashMap <>();
5563 this .conversionStrategiesDrop .put (LanguageLevel .GROUP_CARDINALITY , DropGroupCardinality .class );
5664 this .conversionStrategiesDrop .put (LanguageLevel .FEATURE_CARDINALITY , DropFeatureCardinality .class );
@@ -119,8 +127,9 @@ public Constraint parseConstraint(String constraintString) throws ParseError {
119127 UVLJavaLexer .addErrorListener (listener );
120128 UVLJavaParser .addErrorListener (listener );
121129
122- UVLListener uvlListener = new UVLListener ();
123- ParseTreeWalker walker = new ParseTreeWalker ();
130+ UVLListener uvlListener = createUVLListener ();
131+ IterativeParseTreeWalker walker = new IterativeParseTreeWalker ();
132+
124133 walker .walk (uvlListener , UVLJavaParser .constraintLine ());
125134
126135 return uvlListener .getConstraint ();
@@ -267,6 +276,10 @@ private List<LanguageLevel> getActualLanguageLevelsToRemoveInOrder(FeatureModel
267276 return completeOrderedLevelsToRemove ;
268277 }
269278
279+ private UVLListener createUVLListener () {
280+ return new UVLListener (new FeatureModelBuilder (elementFactory ));
281+ }
282+
270283 private String getPath (String rootPath , Import referencedImport ) {
271284 return rootPath + FileSystems .getDefault ().getSeparator () + referencedImport .getNamespace ().replace ("." , FileSystems .getDefault ().getSeparator ()) + ".uvl" ;
272285 }
@@ -285,8 +298,10 @@ private FeatureModel parseFeatureModelWithImports(String text, String rootPath,
285298 UVLJavaParser .addErrorListener (listener );
286299
287300
288- UVLListener uvlListener = new UVLListener ();
289- ParseTreeWalker walker = new ParseTreeWalker ();
301+
302+ UVLListener uvlListener = createUVLListener ();
303+ IterativeParseTreeWalker walker = new IterativeParseTreeWalker ();
304+
290305 walker .walk (uvlListener , UVLJavaParser .featureModel ());
291306 FeatureModel featureModel = null ;
292307
@@ -378,42 +393,55 @@ private FeatureModel parseFeatureModelWithImports(String text, String rootPath,
378393 }
379394
380395 private void resolveImportPlaceholders (Constraint constraint , FeatureModel featureModel ) {
381- if (constraint instanceof AndConstraint || constraint instanceof OrConstraint || constraint instanceof NotConstraint || constraint instanceof ImplicationConstraint || constraint instanceof ParenthesisConstraint || constraint instanceof EquivalenceConstraint ) {
382- for (Constraint subPart : constraint .getConstraintSubParts ()) {
383- resolveImportPlaceholders (subPart , featureModel );
396+ final Deque <Constraint > stack = new ArrayDeque <>();
397+ stack .push (constraint );
398+
399+ while (!stack .isEmpty ()) {
400+ final Constraint current = stack .pop ();
401+
402+ if (current instanceof ExpressionConstraint ) {
403+ ExpressionConstraint expressionConstraint = (ExpressionConstraint ) current ;
404+ resolveImportPlaceholders (expressionConstraint .getLeft (), featureModel );
405+ resolveImportPlaceholders (expressionConstraint .getRight (), featureModel );
406+ } else if (current instanceof LiteralConstraint ) {
407+ LiteralConstraint literalConstraint = (LiteralConstraint ) current ;
408+ if (literalConstraint .getReference () instanceof ImportedVariablePlaceholder ) {
409+ ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder ) literalConstraint .getReference ();
410+ literalConstraint .setReference (resolvePlaceholder (placeholder , featureModel ));
411+ }
384412 }
385- } else if (constraint instanceof ExpressionConstraint ) {
386- ExpressionConstraint expressionConstraint = (ExpressionConstraint ) constraint ;
387- resolveImportPlaceholders (expressionConstraint .getLeft (), featureModel );
388- resolveImportPlaceholders (expressionConstraint .getRight (), featureModel );
389- } else if (constraint instanceof LiteralConstraint ) {
390- LiteralConstraint literalConstraint = (LiteralConstraint ) constraint ;
391- if (literalConstraint .getReference () instanceof ImportedVariablePlaceholder ) {
392- ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder ) literalConstraint .getReference ();
393- literalConstraint .setReference (resolvePlaceholder (placeholder , featureModel ));
413+
414+ final List <Constraint > subConstraints = current .getConstraintSubParts ();
415+ for (int i = subConstraints .size () - 1 ; i >= 0 ; i --) {
416+ stack .push (subConstraints .get (i ));
394417 }
395418 }
396419 }
397420
398421 private void resolveImportPlaceholders (Expression expression , FeatureModel featureModel ) {
399- if (expression instanceof BinaryExpression ) {
400- BinaryExpression binaryExpression = (BinaryExpression ) expression ;
401- resolveImportPlaceholders (binaryExpression .getLeft (), featureModel );
402- resolveImportPlaceholders (binaryExpression .getRight (), featureModel );
403- } else if (expression instanceof ParenthesisExpression ) {
404- ParenthesisExpression parenthesisExpression = (ParenthesisExpression ) expression ;
405- resolveImportPlaceholders (parenthesisExpression .getContent (), featureModel );
406- } else if (expression instanceof LengthAggregateFunctionExpression ) {
407- LengthAggregateFunctionExpression lengthAggregateFunctionExpression = (LengthAggregateFunctionExpression ) expression ;
408- if (lengthAggregateFunctionExpression .getReference () instanceof ImportedVariablePlaceholder ) {
409- ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder ) lengthAggregateFunctionExpression .getReference ();
410- lengthAggregateFunctionExpression .setReference (resolvePlaceholder (placeholder , featureModel ));
422+ final Deque <Expression > stack = new ArrayDeque <>();
423+ stack .push (expression );
424+
425+ while (!stack .isEmpty ()) {
426+ final Expression current = stack .pop ();
427+
428+ if (current instanceof LengthAggregateFunctionExpression ) {
429+ LengthAggregateFunctionExpression lengthAggregateFunctionExpression = (LengthAggregateFunctionExpression ) current ;
430+ if (lengthAggregateFunctionExpression .getReference () instanceof ImportedVariablePlaceholder ) {
431+ ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder ) lengthAggregateFunctionExpression .getReference ();
432+ lengthAggregateFunctionExpression .setReference (resolvePlaceholder (placeholder , featureModel ));
433+ }
434+ } else if (current instanceof LiteralExpression ) {
435+ LiteralExpression literalExpression = (LiteralExpression ) current ;
436+ if (literalExpression .getContent () instanceof ImportedVariablePlaceholder ) {
437+ ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder ) literalExpression .getContent ();
438+ literalExpression .setContent (resolvePlaceholder (placeholder , featureModel ));
439+ }
411440 }
412- } else if (expression instanceof LiteralExpression ) {
413- LiteralExpression literalExpression = (LiteralExpression ) expression ;
414- if (literalExpression .getContent () instanceof ImportedVariablePlaceholder ) {
415- ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder ) literalExpression .getContent ();
416- literalExpression .setContent (resolvePlaceholder (placeholder , featureModel ));
441+
442+ final List <Expression > subExpressions = current .getExpressionSubParts ();
443+ for (int i = subExpressions .size () - 1 ; i >= 0 ; i --) {
444+ stack .push (subExpressions .get (i ));
417445 }
418446 }
419447 }
@@ -537,28 +565,38 @@ private void validateTypeLevelConstraints(final FeatureModel featureModel) {
537565 }
538566
539567 private boolean validateTypeLevelConstraint (final Constraint constraint ) {
540- boolean result = true ;
541- if (constraint instanceof ExpressionConstraint ) {
542- String leftReturnType = ((ExpressionConstraint ) constraint ).getLeft ().getReturnType ();
543- String rightReturnType = ((ExpressionConstraint ) constraint ).getRight ().getReturnType ();
568+ final Deque <Constraint > stack = new ArrayDeque <>();
569+ stack .push (constraint );
544570
545- if (!(leftReturnType .equalsIgnoreCase (Constants .TRUE ) || rightReturnType .equalsIgnoreCase (Constants .TRUE ))) {
546- // if not attribute constraint
547- result = result && ((ExpressionConstraint ) constraint ).getLeft ().getReturnType ().equalsIgnoreCase (((ExpressionConstraint ) constraint ).getRight ().getReturnType ());
548- }
549- if (!result ) {
550- return false ;
551- }
552- for (final Expression expr : ((ExpressionConstraint ) constraint ).getExpressionSubParts ()) {
553- result = result && validateTypeLevelExpression (expr );
571+ while (!stack .isEmpty ()) {
572+ final Constraint current = stack .pop ();
573+
574+ if (current instanceof ExpressionConstraint ) {
575+ final ExpressionConstraint expressionConstraint = (ExpressionConstraint ) current ;
576+
577+ final String leftReturnType = expressionConstraint .getLeft ().getReturnType ();
578+ final String rightReturnType = expressionConstraint .getRight ().getReturnType ();
579+
580+ if (!(leftReturnType .equalsIgnoreCase (Constants .TRUE ) || rightReturnType .equalsIgnoreCase (Constants .TRUE ))) {
581+ if (!leftReturnType .equalsIgnoreCase (rightReturnType )) {
582+ return false ;
583+ }
584+ }
585+
586+ for (final Expression expr : expressionConstraint .getExpressionSubParts ()) {
587+ if (!validateTypeLevelExpression (expr )) {
588+ return false ;
589+ }
590+ }
554591 }
555- }
556592
557- for (final Constraint subCons : constraint .getConstraintSubParts ()) {
558- result = result && validateTypeLevelConstraint (subCons );
593+ final List <Constraint > subConstraints = current .getConstraintSubParts ();
594+ for (int i = subConstraints .size () - 1 ; i >= 0 ; i --) {
595+ stack .push (subConstraints .get (i ));
596+ }
559597 }
560598
561- return result ;
599+ return true ;
562600 }
563601
564602 private boolean validateTypeLevelExpression (final Expression expression ) {
0 commit comments