/* * Copyright 2016 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.rf.ide.core.testdata.model.table; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; 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.recognizer.RobotToken; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; public class RobotElementsComparatorWithPositionChangedPresave implements Comparator<IRobotLineElement> { private final Map<IRobotTokenType, Integer> typesToHierarchy = new LinkedHashMap<IRobotTokenType, Integer>(); private final Multimap<IRobotTokenType, IRobotLineElement> typeToTokens = ArrayListMultimap.create(); private final RobotTokenPositionComparator posComperator = new RobotTokenPositionComparator(); public void addPresaveSequenceForType(final IRobotTokenType type, final int hierarchyPoint, final List<? extends IRobotLineElement> elems) { typesToHierarchy.put(type, hierarchyPoint); typeToTokens.putAll(type, elems); } public Optional<IRobotTokenType> findType(final IRobotLineElement elem) { Optional<IRobotTokenType> type = Optional.empty(); for (final IRobotTokenType currentType : typeToTokens.keySet()) { final Collection<IRobotLineElement> list = typeToTokens.get(currentType); for (final IRobotLineElement e : list) { if (e == elem) { type = Optional.of(currentType); break; } } if (type.isPresent()) { break; } } return type; } public Multimap<IRobotLineElement, Integer> indexesOf(final Collection<IRobotLineElement> list, final IRobotLineElement... elements) { final List<IRobotLineElement> elems = new ArrayList<>(Arrays.asList(elements)); final Multimap<IRobotLineElement, Integer> found = ArrayListMultimap.create(); final int listSize = list.size(); for (int i = 0; i < listSize; i++) { for (final IRobotLineElement e : elems) { if (e == list.toArray()[i]) { found.put(e, i); } } } return found; } @Override public int compare(final IRobotLineElement o1, final IRobotLineElement o2) { int result = ECompareResult.EQUAL_TO.getValue(); final Optional<IRobotTokenType> o1TypeOP = findType(o1); final Optional<IRobotTokenType> o2TypeOP = findType(o2); final int posComperatorResult = posComperator.compare(o1, o2); if (o1TypeOP.isPresent() && o2TypeOP.isPresent()) { if (o1TypeOP.get() == o2TypeOP.get()) { final Multimap<IRobotLineElement, Integer> indexes = indexesOf(typeToTokens.get(o1TypeOP.get()), o1, o2); final Collection<Integer> o1PosInSequence = indexes.get(o1); final Collection<Integer> o2PosInSequence = indexes.get(o2); final Integer o1Index = o1PosInSequence.toArray(new Integer[o1PosInSequence.size()])[0]; final Integer o2Index = o2PosInSequence.toArray(new Integer[o2PosInSequence.size()])[0]; result = Integer.compare(o1Index, o2Index); } else { final Integer typeO1hierarchy = typesToHierarchy.get(o1TypeOP.get()); final Integer typeO2hierarchy = typesToHierarchy.get(o2TypeOP.get()); result = Integer.compare(typeO1hierarchy, typeO2hierarchy); if (posComperatorResult != ECompareResult.EQUAL_TO.getValue()) { if (isBothWithPositionSet(o1, o2)) { result = posComperatorResult; } } } } else if (!o1TypeOP.isPresent() && !o2TypeOP.isPresent()) { result = posComperatorResult; } else if (!o1TypeOP.isPresent()) { result = ECompareResult.LESS_THAN.getValue(); } else if (!o2TypeOP.isPresent()) { result = ECompareResult.GREATER_THAN.getValue(); } return result; } private boolean isBothWithPositionSet(final IRobotLineElement o1, final IRobotLineElement o2) { return !o1.getFilePosition().isNotSet() && !o2.getFilePosition().isNotSet(); } public List<RobotToken> getTokensInElement() { final List<RobotToken> tokens = new ArrayList<>(0); for (final IRobotLineElement rle : typeToTokens.values()) { if (rle instanceof RobotToken) { tokens.add((RobotToken) rle); } } return tokens; } }