/* * 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.setting.library; import java.util.List; import java.util.Stack; import org.rf.ide.core.testdata.mapping.table.ElementsUtility; import org.rf.ide.core.testdata.mapping.table.ParsingStateHelper; import org.rf.ide.core.testdata.model.RobotFileOutput; import org.rf.ide.core.testdata.model.table.setting.LibraryAlias; import org.rf.ide.core.testdata.model.table.setting.LibraryImport; import org.rf.ide.core.testdata.text.read.ParsingState; import org.rf.ide.core.testdata.text.read.recognizer.ATokenRecognizer; import org.rf.ide.core.testdata.text.read.recognizer.RobotToken; import org.rf.ide.core.testdata.text.read.recognizer.RobotTokenType; import org.rf.ide.core.testdata.text.read.recognizer.settings.LibraryAliasRecognizer; import com.google.common.annotations.VisibleForTesting; public class LibraryAliasFixer { private final ElementsUtility utility; private final ParsingStateHelper parsingStateHelper; public LibraryAliasFixer(final ElementsUtility utility, final ParsingStateHelper parsingStateHelper) { this.utility = utility; this.parsingStateHelper = parsingStateHelper; } public void checkAndFixLine(final RobotFileOutput robotFileOutput, final Stack<ParsingState> processingState) { ParsingState state = parsingStateHelper.findNearestNotCommentState(processingState); if (state == ParsingState.SETTING_LIBRARY_IMPORT_ALIAS) { LibraryImport lib = utility.findNearestLibraryImport(robotFileOutput); applyFixes(robotFileOutput, lib, null, processingState); } else if (state == ParsingState.SETTING_LIBRARY_ARGUMENTS) { LibraryImport lib = utility.findNearestLibraryImport(robotFileOutput); List<RobotToken> arguments = lib.getArguments(); int argumentsSize = arguments.size(); if (argumentsSize >= 2) { RobotToken argumentPossibleAlias = arguments.get(argumentsSize - 2); ATokenRecognizer rec = new LibraryAliasRecognizer(); if (rec.hasNext(argumentPossibleAlias.getText(), argumentPossibleAlias.getLineNumber(), argumentPossibleAlias.getStartColumn())) { argumentPossibleAlias.setType(RobotTokenType.SETTING_LIBRARY_ALIAS); LibraryAlias alias = new LibraryAlias(argumentPossibleAlias); RobotToken aliasValue = arguments.get(argumentsSize - 1); aliasValue.setType(RobotTokenType.SETTING_LIBRARY_ALIAS_VALUE); alias.setLibraryAlias(aliasValue); lib.setAlias(alias); lib.removeArgument(argumentsSize - 1); lib.removeArgument(argumentsSize - 2); replaceArgumentsByAliasDeclaration(processingState); } } } } @VisibleForTesting protected void replaceArgumentsByAliasDeclaration(final Stack<ParsingState> processingState) { int removedArguments = 0; for (int i = processingState.size() - 1; i >= 0; i--) { ParsingState state = processingState.get(i); if (state == ParsingState.SETTING_LIBRARY_ARGUMENTS) { if (removedArguments == 0) { // it is value processingState.set(i, ParsingState.SETTING_LIBRARY_IMPORT_ALIAS_VALUE); removedArguments++; } else if (removedArguments == 1) { // it is alias processingState.set(i, ParsingState.SETTING_LIBRARY_IMPORT_ALIAS); break; } } } } public void applyFixes(final RobotFileOutput robotFileOutput, final LibraryImport lib, final RobotToken additionalToken, final Stack<ParsingState> processingState) { LibraryAlias alias = lib.getAlias(); if (additionalToken == null) { // end of line if (alias.isPresent()) { if (alias.getLibraryAlias() == null) { // FIXME: add info that WITH NAME do not have any aliases so // will be get as argument RobotToken aliasToken = alias.getLibraryAliasDeclaration(); aliasToken.setType(RobotTokenType.SETTING_LIBRARY_ARGUMENT); aliasToken.getTypes().add(RobotTokenType.SETTING_LIBRARY_ALIAS); lib.addArgument(aliasToken); lib.setAlias(new LibraryAlias(null)); removeLibraryAliasState(processingState); } } } else { // case when we check if we have alias value if (alias.isPresent()) { RobotToken libraryAlias = alias.getLibraryAlias(); ATokenRecognizer rec = new LibraryAliasRecognizer(); if (rec.hasNext(libraryAlias.getText(), libraryAlias.getLineNumber(), libraryAlias.getStartColumn())) { // alias value has WITH NAME case and we have additional // argument case: WITH NAME (lib argument) WITH NAME p RobotToken aliasDeclared = alias.getLibraryAliasDeclaration(); aliasDeclared.setType(RobotTokenType.SETTING_LIBRARY_ARGUMENT); aliasDeclared.getTypes().add(RobotTokenType.SETTING_LIBRARY_ALIAS); lib.addArgument(aliasDeclared); libraryAlias.setType(RobotTokenType.SETTING_LIBRARY_ALIAS); LibraryAlias correctedAlias = new LibraryAlias(libraryAlias); additionalToken.setType(RobotTokenType.SETTING_LIBRARY_ALIAS_VALUE); correctedAlias.setLibraryAlias(additionalToken); lib.setAlias(correctedAlias); } else { // case when we have already correct alias and we get // additional value for alias RobotToken libraryAliasDeclaration = alias.getLibraryAliasDeclaration(); libraryAliasDeclaration.setType(RobotTokenType.SETTING_LIBRARY_ARGUMENT); lib.addArgument(libraryAliasDeclaration); libraryAlias.setType(RobotTokenType.SETTING_LIBRARY_ARGUMENT); lib.addArgument(libraryAlias); additionalToken.setType(RobotTokenType.SETTING_LIBRARY_ARGUMENT); lib.addArgument(additionalToken); cleanAliasAndValueFromState(processingState); processingState.push(ParsingState.SETTING_LIBRARY_ARGUMENTS); } } } } @VisibleForTesting protected void cleanAliasAndValueFromState(final Stack<ParsingState> processingState) { removeLibraryAliasValueState(processingState); removeLibraryAliasState(processingState); } @VisibleForTesting protected void removeLibraryAliasValueState(Stack<ParsingState> processingState) { for (int i = processingState.size() - 1; i >= 0; i--) { ParsingState state = processingState.get(i); if (state == ParsingState.SETTING_LIBRARY_IMPORT_ALIAS_VALUE) { processingState.remove(i); } else { break; } } } @VisibleForTesting protected void removeLibraryAliasState(Stack<ParsingState> processingState) { for (int i = processingState.size() - 1; i >= 0; i--) { ParsingState state = processingState.get(i); if (state == ParsingState.SETTING_LIBRARY_IMPORT_ALIAS) { processingState.remove(i); } else { break; } } } }