/* * 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.text.read.separators; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; 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 org.rf.ide.core.testdata.text.read.recognizer.RobotTokenType; import org.rf.ide.core.testdata.text.read.separators.Separator.SeparatorType; public abstract class ALineSeparator { private final AtomicBoolean wasInitialized = new AtomicBoolean(false); private int prevElementIndex = -1; private int elementIndex = -1; protected final int lineNumber; protected final String line; private final List<IRobotLineElement> lineElements = new ArrayList<>(); protected ALineSeparator(final int lineNumber, final String line) { this.lineNumber = lineNumber; this.line = line; } private void init() { synchronized (this) { if (!wasInitialized.get()) { wasInitialized.set(true); int lastColumnProcessed = 0; final int textLength = line.length(); if (textLength > 0) { while(lastColumnProcessed < textLength) { if (hasNextSeparator()) { final Separator currentSeparator = nextSeparator(); final int startColumn = currentSeparator.getStartColumn(); final int remainingData = startColumn - lastColumnProcessed; final String rawText = line.substring( lastColumnProcessed, startColumn); if (remainingData > 0 || !lineElements.isEmpty()) { final RobotToken token = new RobotToken(); token.setLineNumber(lineNumber); token.setRaw(rawText); token.setText(rawText); token.setStartColumn(lastColumnProcessed); token.setType(RobotTokenType.UNKNOWN); lineElements.add(token); } lineElements.add(currentSeparator); lastColumnProcessed = currentSeparator .getEndColumn(); } else { final String rawText = line .substring(lastColumnProcessed); final RobotToken token = new RobotToken(); token.setLineNumber(lineNumber); token.setRaw(rawText); token.setText(rawText); token.setStartColumn(lastColumnProcessed); token.setType(RobotTokenType.UNKNOWN); lineElements.add(token); lastColumnProcessed = textLength; } } } } } } protected abstract Separator nextSeparator(); public Separator next() { init(); updateIndex(); Separator found = null; if (elementIndex > prevElementIndex) { found = (Separator) lineElements.get(elementIndex); } prevElementIndex = elementIndex; return found; } protected abstract boolean hasNextSeparator(); public boolean hasNext() { init(); updateIndex(); return (elementIndex > prevElementIndex); } private void updateIndex() { final int elementsSize = lineElements.size(); if (prevElementIndex < elementsSize && elementIndex <= prevElementIndex) { for (int index = elementIndex + 1; index < elementsSize; index++) { if (isSeparator(lineElements.get(index))) { elementIndex = index; break; } } } } private boolean isSeparator(final IRobotLineElement elem) { boolean result = false; final List<IRobotTokenType> types = elem.getTypes(); for (final IRobotTokenType type : types) { if (type == SeparatorType.PIPE || type == SeparatorType.TABULATOR_OR_DOUBLE_SPACE) { result = true; break; } } return result; } public abstract SeparatorType getProducedType(); public List<IRobotLineElement> getSplittedLine() { init(); return Collections.unmodifiableList(lineElements); } public int getPreviousElementIndex() { return prevElementIndex; } public int getCurrentElementIndex() { return elementIndex; } public int getLineNumber() { return lineNumber; } public String getLine() { return line; } }