All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.exactpro.sf.aml.reader.AMLReader Maven / Gradle / Ivy
/******************************************************************************
* Copyright 2009-2018 Exactpro (Exactpro Systems Limited)
*
* 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 com.exactpro.sf.aml.reader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.exactpro.sf.aml.AMLBlockBrace;
import com.exactpro.sf.aml.AMLException;
import com.exactpro.sf.aml.AMLLangConst;
import com.exactpro.sf.aml.generator.Alert;
import com.exactpro.sf.aml.generator.AlertCollector;
import com.exactpro.sf.aml.generator.AlertType;
import com.exactpro.sf.aml.generator.matrix.Column;
import com.exactpro.sf.aml.generator.matrix.JavaStatement;
import com.exactpro.sf.aml.iomatrix.AdvancedMatrixReader;
import com.exactpro.sf.aml.iomatrix.SimpleCell;
import com.exactpro.sf.aml.reader.struct.AMLBlock;
import com.exactpro.sf.aml.reader.struct.AMLElement;
import com.exactpro.sf.aml.reader.struct.AMLMatrix;
public class AMLReader {
private static final Logger logger = LoggerFactory.getLogger(AMLReader.class);
public static AMLMatrix read(AdvancedMatrixReader matrixReader) throws IOException, AMLException {
return read(matrixReader, false);
}
public static AMLMatrix read(AdvancedMatrixReader matrixReader, boolean skipOptional) throws IOException, AMLException {
logger.debug("Start reading matrix");
AlertCollector alertCollector = new AlertCollector();
List blocks = new ArrayList<>();
Stack statementStack = new Stack<>();
Stack blockStack = new Stack<>();
AMLBlockBrace blockBrace = null;
List header = prepareHeader(matrixReader.getHeader());
int line = 0;
while(matrixReader.hasNext()) {
Map cells = matrixReader.readCells();
if (cells.containsKey(Column.Reference.getName())) {
line = cells.get(Column.Reference.getName()).getLineNumber();
} else if (cells.containsKey(Column.Action.getName())) {
line = cells.get(Column.Action.getName()).getLineNumber();
} else {
line = matrixReader.getRowNumber();
}
if(cells.isEmpty()) {
continue;
}
AMLElement element = new AMLElement(line, cells, skipOptional);
if(AMLLangConst.YES.equalsIgnoreCase(element.getValue(Column.Comment))) {
continue;
}
String actionName = element.getValue(Column.Action);
AMLBlockBrace currentBlockBrace = AMLBlockBrace.value(actionName);
// workaround for "include block" action for SailfishURI init
if(AMLLangConst.INCLUDE_BLOCK_OLD_ACTION.equalsIgnoreCase(actionName)) {
actionName = JavaStatement.INCLUDE_BLOCK.getValue();
element.setValue(Column.Action, actionName);
}
if(currentBlockBrace != null) {
if(blockStack.isEmpty() && !currentBlockBrace.isStart()) {
alertCollector.add(new Alert(line, "No block to close"));
continue;
}
if(blockStack.size() == 1) {
if(currentBlockBrace.isStart()) {
alertCollector.add(new Alert(line, "Unclosed block at line: " + blockStack.peek().getLine()));
continue;
} else if(blockBrace != currentBlockBrace.getInversed()) {
String error = String.format("Invalid close statement: %s (expected: %s)", currentBlockBrace, blockBrace.getInversed());
alertCollector.add(new Alert(line, error));
continue;
}
}
if(blockStack.size() > 1) {
alertCollector.add(new Alert(line, "Unclosed block at line: " + blockStack.peek().getLine()));
continue;
}
if(currentBlockBrace.isStart()) {
AMLBlock block = new AMLBlock(line, cells, skipOptional);
blockBrace = currentBlockBrace;
blockStack.push(block);
} else {
blocks.add(blockStack.pop());
blockBrace = null;
}
continue;
}
if(blockStack.isEmpty()) {
if(element.isExecutable() && (actionName != null || element.containsCell(Column.Reference) || element.containsCell(Column.ReferenceToFilter))) {
alertCollector.add(new Alert(line, "Block is not opened"));
}
continue;
}
AMLBlock block = blockStack.peek();
JavaStatement statement = JavaStatement.value(actionName);
if(statement != null) {
switch(statement) {
case DEFINE_HEADER:
case DEFINE_SERVICE_NAME:
case INCLUDE_BLOCK:
case SET_STATIC:
block.addElement(element);
continue;
case BEGIN_IF:
AMLBlock statementBlock = new AMLBlock(line);
AMLBlock innerBlock = new AMLBlock(line, cells, skipOptional);
statementBlock.setValue(Column.Execute, element.isExecutable() ? AMLLangConst.YES : AMLLangConst.NO);
block.addElement(statementBlock);
statementBlock.addElement(innerBlock);
blockStack.push(statementBlock);
blockStack.push(innerBlock);
statementStack.push(statement);
continue;
case BEGIN_LOOP:
statementBlock = new AMLBlock(line, cells, skipOptional);
block.addElement(statementBlock);
blockStack.push(statementBlock);
statementStack.push(statement);
continue;
case BEGIN_ELIF:
case BEGIN_ELSE:
if(statementStack.isEmpty()) {
alertCollector.add(new Alert(line, "Missing '" + JavaStatement.BEGIN_IF + "' statement"));
continue;
}
JavaStatement previousStatement = statementStack.peek();
if(previousStatement != JavaStatement.BEGIN_IF && previousStatement != JavaStatement.BEGIN_ELIF) {
String error = String.format("Missing '%s' or '%s' statement", JavaStatement.BEGIN_IF, JavaStatement.BEGIN_ELIF);
alertCollector.add(new Alert(line, error));
continue;
}
blockStack.pop();
statementStack.pop();
block = blockStack.peek();
innerBlock = new AMLBlock(line, cells, skipOptional);
block.addElement(innerBlock);
blockStack.push(innerBlock);
statementStack.push(statement);
continue;
case END_IF:
if(statementStack.isEmpty() || (statementStack.peek() != JavaStatement.BEGIN_IF && statementStack.peek() != JavaStatement.BEGIN_ELIF && statementStack.peek() != JavaStatement.BEGIN_ELSE)) {
String error = String.format("Missing '%s', '%s' or '%s' statement", JavaStatement.BEGIN_IF, JavaStatement.BEGIN_ELIF, JavaStatement.BEGIN_ELSE);
alertCollector.add(new Alert(line, error));
continue;
}
blockStack.pop();
blockStack.pop();
statementStack.pop();
continue;
case END_LOOP:
if(statementStack.isEmpty() || statementStack.peek() != JavaStatement.BEGIN_LOOP) {
String error = "Missing '" + JavaStatement.BEGIN_LOOP + "' statement";
alertCollector.add(new Alert(line, error));
continue;
}
blockStack.pop();
statementStack.pop();
continue;
default:
alertCollector.add(new Alert(line, "Unknown statement: " + statement.getValue()));
continue;
}
}
block.addElement(element);
}
while(!blockStack.isEmpty()) {
alertCollector.add(new Alert(line + 1, "Unclosed block at line: " + blockStack.pop().getLine()));
}
if(alertCollector.getCount(AlertType.ERROR) > 0) {
throw new AMLException("Failed to read matrix", alertCollector);
}
logger.debug("Read is completed");
return new AMLMatrix(header, blocks);
}
/**
* Removes empty columns from header
*
* @param header list of header columns to process
* @return processed header without empty cells
*/
private static List prepareHeader(List header) {
List newHeader = new ArrayList<>();
for(SimpleCell column : header) {
if(StringUtils.isNotBlank(column.getValue())) {
newHeader.add(column);
}
}
return newHeader;
}
}