Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#217 Implemented for loop in speclang2
- Loading branch information
Showing
13 changed files
with
349 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
galen-core/src/main/java/net/mindengine/galen/speclang2/reader/pagespec/ForLoop.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,137 @@ | |||
/******************************************************************************* | |||
* Copyright 2015 Ivan Shubin http://mindengine.net | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
******************************************************************************/ | |||
package net.mindengine.galen.speclang2.reader.pagespec; | |||
|
|||
import net.mindengine.galen.parser.ProcessedStructNode; | |||
import net.mindengine.galen.parser.StructNode; | |||
import net.mindengine.galen.parser.SyntaxException; | |||
import net.mindengine.galen.specs.reader.StringCharReader; | |||
import net.mindengine.galen.suite.reader.Line; | |||
|
|||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.regex.Pattern; | |||
|
|||
import static net.mindengine.galen.suite.reader.Line.UNKNOWN_LINE; | |||
|
|||
public class ForLoop { | |||
|
|||
public static final String INDEX_DEFAULT_NAME = "index"; | |||
private List<String> sequence; | |||
private String indexName; | |||
|
|||
public ForLoop(List<String> sequence, String indexName) { | |||
this.sequence = sequence; | |||
this.indexName = indexName; | |||
} | |||
|
|||
public static ForLoop read(StringCharReader reader, StructNode originNode) { | |||
try { | |||
String emptyness = reader.readUntilSymbol('[').trim(); | |||
if (!emptyness.isEmpty()) { | |||
throw originNode.createSyntaxException("Unexpected token: " + emptyness); | |||
} | |||
|
|||
String parameterizations = reader.readUntilSymbol(']'); | |||
List<String> sequence = readSequence(parameterizations); | |||
String indexName = INDEX_DEFAULT_NAME; | |||
|
|||
if (reader.hasMoreNormalSymbols()) { | |||
String as = reader.readWord(); | |||
if (as.equals("as")) { | |||
|
|||
} else { | |||
throw new SyntaxException("Invalid token: " + as); | |||
} | |||
|
|||
indexName = reader.readWord(); | |||
|
|||
if (indexName.isEmpty()) { | |||
throw new SyntaxException("Missing index"); | |||
} | |||
|
|||
if (reader.hasMoreNormalSymbols()) { | |||
throw new SyntaxException("Unknown statement: " + reader.getTheRest().trim()); | |||
} | |||
} | |||
return new ForLoop(sequence, indexName); | |||
} catch (SyntaxException ex) { | |||
ex.setLine(new Line(originNode.getSource(), originNode.getFileLineNumber())); | |||
throw ex; | |||
} | |||
} | |||
|
|||
private static List<String> readSequence(String sequenceText) { | |||
sequenceText = sequenceText.replace(" ", ""); | |||
sequenceText = sequenceText.replace("\t", ""); | |||
Pattern sequencePattern = Pattern.compile(".*\\-.*"); | |||
try { | |||
String[] values = sequenceText.split(","); | |||
|
|||
List<String> sequence = new LinkedList<String>(); | |||
|
|||
for (String value : values) { | |||
if (sequencePattern.matcher(value).matches()) { | |||
sequence.addAll(createSequence(value)); | |||
} | |||
else { | |||
sequence.add(value); | |||
} | |||
} | |||
|
|||
return sequence; | |||
} | |||
catch (Exception ex) { | |||
throw new SyntaxException(UNKNOWN_LINE, "Incorrect sequence syntax: " + sequenceText, ex); | |||
} | |||
} | |||
|
|||
private static List<String> createSequence(String value) { | |||
int dashIndex = value.indexOf('-'); | |||
|
|||
int rangeA = Integer.parseInt(value.substring(0, dashIndex)); | |||
int rangeB = Integer.parseInt(value.substring(dashIndex + 1)); | |||
|
|||
return createSequence(rangeA, rangeB); | |||
} | |||
|
|||
private static List<String> createSequence(int min, int max) { | |||
if (max >= min) { | |||
List<String> parameters = new LinkedList<String>(); | |||
for (int i = min; i <= max; i++) { | |||
parameters.add(Integer.toString(i)); | |||
} | |||
return parameters; | |||
} | |||
else { | |||
return Collections.emptyList(); | |||
} | |||
} | |||
|
|||
public List<ProcessedStructNode> apply(LoopVisitor loopVisitor) { | |||
List<ProcessedStructNode> resultingNodes = new LinkedList<ProcessedStructNode>(); | |||
|
|||
for (final String sequenceValue : sequence) { | |||
resultingNodes.addAll(loopVisitor.visitLoop(new HashMap<String, String>(){{ | |||
put(indexName, sequenceValue); | |||
}})); | |||
} | |||
|
|||
return resultingNodes; | |||
} | |||
} |
89 changes: 89 additions & 0 deletions
89
galen-core/src/main/java/net/mindengine/galen/speclang2/reader/pagespec/LogicProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,89 @@ | |||
/******************************************************************************* | |||
* Copyright 2015 Ivan Shubin http://mindengine.net | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
******************************************************************************/ | |||
package net.mindengine.galen.speclang2.reader.pagespec; | |||
|
|||
import net.mindengine.galen.parser.ProcessedStructNode; | |||
import net.mindengine.galen.parser.StructNode; | |||
import net.mindengine.galen.specs.reader.StringCharReader; | |||
|
|||
import java.util.*; | |||
|
|||
public class LogicProcessor { | |||
private final PageSpecProcessor pageSpecProcessor; | |||
|
|||
public LogicProcessor(PageSpecProcessor pageSpecProcessor) { | |||
this.pageSpecProcessor = pageSpecProcessor; | |||
} | |||
|
|||
public List<ProcessedStructNode> process(List<StructNode> nodes) { | |||
List<ProcessedStructNode> resultingNodes = new LinkedList<ProcessedStructNode>(); | |||
|
|||
for (StructNode node : nodes) { | |||
ProcessedStructNode processedNode = pageSpecProcessor.processExpressionsIn(node); | |||
|
|||
if (isLogicStatement(processedNode.getName())) { | |||
resultingNodes.addAll(processLogicStatement(processedNode)); | |||
} else { | |||
resultingNodes.add(processNonLogicStatement(processedNode)); | |||
} | |||
} | |||
|
|||
return resultingNodes; | |||
} | |||
|
|||
private ProcessedStructNode processNonLogicStatement(ProcessedStructNode processedNode) { | |||
if (processedNode.getChildNodes() != null) { | |||
ProcessedStructNode fullyProcessed = new ProcessedStructNode(processedNode.getName(), processedNode); | |||
|
|||
fullyProcessed.setChildNodes(convertList(process(processedNode.getChildNodes()))); | |||
return fullyProcessed; | |||
} else { | |||
return processedNode; | |||
} | |||
} | |||
|
|||
private List<StructNode> convertList(List<ProcessedStructNode> processed) { | |||
List<StructNode> list = new LinkedList<StructNode>(); | |||
for (ProcessedStructNode item: processed) { | |||
list.add(item); | |||
} | |||
return list; | |||
} | |||
|
|||
|
|||
private List<ProcessedStructNode> processLogicStatement(final ProcessedStructNode logicStatementNode) { | |||
StringCharReader reader = new StringCharReader(logicStatementNode.getName()); | |||
String firstWord = reader.readWord(); | |||
if (firstWord.equals("@for")) { | |||
ForLoop forLoop = ForLoop.read(reader, logicStatementNode); | |||
|
|||
return forLoop.apply(new LoopVisitor() { | |||
@Override | |||
public List<ProcessedStructNode> visitLoop(Map<String, String> variables) { | |||
pageSpecProcessor.setGlobalVariables(variables, logicStatementNode); | |||
return process(logicStatementNode.getChildNodes()); | |||
} | |||
}); | |||
|
|||
} else { | |||
throw logicStatementNode.createSyntaxException("Invalid statement: " + firstWord); | |||
} | |||
} | |||
|
|||
private boolean isLogicStatement(String name) { | |||
return name.startsWith("@"); | |||
} | |||
} |
25 changes: 25 additions & 0 deletions
25
galen-core/src/main/java/net/mindengine/galen/speclang2/reader/pagespec/LoopVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,25 @@ | |||
/******************************************************************************* | |||
* Copyright 2015 Ivan Shubin http://mindengine.net | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
******************************************************************************/ | |||
package net.mindengine.galen.speclang2.reader.pagespec; | |||
|
|||
import net.mindengine.galen.parser.ProcessedStructNode; | |||
|
|||
import java.util.List; | |||
import java.util.Map; | |||
|
|||
public interface LoopVisitor { | |||
List<ProcessedStructNode> visitLoop(Map<String, String> variables); | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.