/* * Copyright 2015 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.rf.ide.core.testdata.mapping.table; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Stack; import org.rf.ide.core.testdata.model.FilePosition; import org.rf.ide.core.testdata.model.RobotFileOutput; import org.rf.ide.core.testdata.text.read.IRobotLineElement; import org.rf.ide.core.testdata.text.read.IRobotTokenType; import org.rf.ide.core.testdata.text.read.ParsingState; import org.rf.ide.core.testdata.text.read.RobotLine; import org.rf.ide.core.testdata.text.read.recognizer.RobotToken; import org.rf.ide.core.testdata.text.read.recognizer.RobotTokenType; public class PrettyAlignSpaceUtility { private final ParsingStateHelper stateHelper; public PrettyAlignSpaceUtility() { this.stateHelper = new ParsingStateHelper(); } public void fixOnlyPrettyAlignLinesInSettings(final RobotLine line, final Stack<ParsingState> processingState) { final ParsingState state = stateHelper.getCurrentStatus(processingState); if (state == ParsingState.SETTING_TABLE_INSIDE) { removeTokenWithoutTextFromSimpleTableLine(line); } } public void fixOnlyPrettyAlignLinesInVariables(final RobotLine line, final Stack<ParsingState> processingState) { final ParsingState state = stateHelper.getCurrentStatus(processingState); if (state == ParsingState.VARIABLE_TABLE_INSIDE) { removeTokenWithoutTextFromSimpleTableLine(line); } } private void removeTokenWithoutTextFromSimpleTableLine(final RobotLine line) { boolean containsAnyValuableToken = false; final List<Integer> emptyStrings = new ArrayList<>(); final List<IRobotLineElement> lineElements = line.getLineElements(); final int length = lineElements.size(); for (int lineElementIndex = 0; lineElementIndex < length; lineElementIndex++) { final IRobotLineElement elem = lineElements.get(lineElementIndex); if (elem instanceof RobotToken) { final RobotToken rt = (RobotToken) elem; final List<IRobotTokenType> types = rt.getTypes(); for (final IRobotTokenType type : types) { if (type != RobotTokenType.UNKNOWN && type != RobotTokenType.PRETTY_ALIGN_SPACE) { containsAnyValuableToken = true; } } final String text = rt.getRaw().toString(); if (text != null && text.trim().length() > 0) { containsAnyValuableToken = true; } else if (!containsAnyValuableToken && types.contains(RobotTokenType.UNKNOWN)) { emptyStrings.add(lineElementIndex); } } } if (!containsAnyValuableToken) { Collections.sort(emptyStrings); final int emptiesSize = emptyStrings.size(); for (int index = emptiesSize - 1; index >= 0; index--) { lineElements.remove((int) emptyStrings.get(index)); } } } public void extractPrettyAlignWhitespaces(final RobotLine line, final RobotToken rt, final String rawText) { final boolean isNotPrettyAlign = !rt.getTypes().contains(RobotTokenType.PRETTY_ALIGN_SPACE); if (isNotPrettyAlign) { String correctedString = rawText; if (rawText.startsWith(" ")) { final RobotToken prettyLeftAlign = new RobotToken(); prettyLeftAlign.setStartOffset(rt.getStartOffset()); prettyLeftAlign.setLineNumber(rt.getLineNumber()); prettyLeftAlign.setStartColumn(rt.getStartColumn()); int lastBeginSpaceIndex = lastSpaceIndexLeft(correctedString); int numberOfSpacesLeft = lastBeginSpaceIndex + 1; prettyLeftAlign.setRaw(String.format("%" + numberOfSpacesLeft + "s", " ")); prettyLeftAlign.setText(String.format("%" + numberOfSpacesLeft + "s", " ")); prettyLeftAlign.setType(RobotTokenType.PRETTY_ALIGN_SPACE); line.addLineElementAt(line.getLineElements().size() - 1, prettyLeftAlign); rt.setStartColumn(rt.getStartColumn() + numberOfSpacesLeft); rt.setStartOffset(rt.getStartOffset() + numberOfSpacesLeft); correctedString = rawText.substring(numberOfSpacesLeft); rt.setText(correctedString); rt.setRaw(correctedString); } if (correctedString.endsWith(" ")) { final int theLongestTextLength = correctedString.length(); int lastEndSpaceIndex = lastSpaceIndexRight(correctedString); int numberOfSpacesRight = theLongestTextLength - lastEndSpaceIndex; final RobotToken prettyRightAlign = new RobotToken(); prettyRightAlign.setStartOffset(rt.getStartOffset() + correctedString.length() - numberOfSpacesRight); prettyRightAlign.setLineNumber(rt.getLineNumber()); prettyRightAlign.setStartColumn(rt.getStartColumn() + theLongestTextLength - numberOfSpacesRight); prettyRightAlign.setRaw(String.format("%" + numberOfSpacesRight + "s", " ")); prettyRightAlign.setText(String.format("%" + numberOfSpacesRight + "s", " ")); prettyRightAlign.setType(RobotTokenType.PRETTY_ALIGN_SPACE); line.addLineElement(prettyRightAlign); correctedString = correctedString.substring(0, correctedString.length() - numberOfSpacesRight); rt.setText(correctedString); rt.setRaw(correctedString); } } } public RobotToken applyPrettyAlignTokenIfIsValid(final RobotLine currentLine, final Stack<ParsingState> processingState, final RobotFileOutput robotFileOutput, final FilePosition fp, final String text, final String fileName, final RobotToken robotToken) { if (isOnlySpaces(text)) { boolean isPrettyAlign = false; final ParsingState currentStatus = stateHelper.getCurrentStatus(processingState); if (currentStatus == ParsingState.KEYWORD_TABLE_INSIDE || currentStatus == ParsingState.TEST_CASE_TABLE_INSIDE || currentStatus == ParsingState.TEST_CASE_DECLARATION || currentStatus == ParsingState.KEYWORD_DECLARATION) { isPrettyAlign = true; } if (isPrettyAlign) { robotToken.setType(RobotTokenType.PRETTY_ALIGN_SPACE); } } return robotToken; } private boolean isOnlySpaces(final String text) { return text != null && lastSpaceIndexLeft(text) == text.length(); } private int lastSpaceIndexLeft(final String text) { int index = -1; if (text != null && !text.isEmpty()) { char chars[] = text.toCharArray(); int length = chars.length; for (int charIndex = 0; charIndex < length; charIndex++) { char c = chars[charIndex]; if (c == ' ') { index = charIndex; } else { break; } } } return index; } private int lastSpaceIndexRight(final String text) { int index = -1; if (text != null && !text.isEmpty()) { char chars[] = text.toCharArray(); int length = chars.length; for (int charIndex = length - 1; charIndex >= 0; charIndex--) { char c = chars[charIndex]; if (c == ' ') { index = charIndex; } else { break; } } } return index; } }