/* * 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.model.table.exec.descs.ast; import java.util.List; import org.rf.ide.core.testdata.model.table.exec.descs.TextPosition; public class VariableStructureExtractor { public Container buildStructureTree(final String text) { Container mainContainer = new Container(null); if (text != null) { Container currentContainer = mainContainer; char[] textChars = text.toCharArray(); int textLength = textChars.length; for (int charIndex = 0; charIndex < textLength; charIndex++) { char currentChar = textChars[charIndex]; ContainerElementType type = ContainerElementType .getTypeFor(currentChar); ContainerElement element = new ContainerElement( new TextPosition(text, charIndex, charIndex), type); if (type.shouldOpenNewContainer()) { Container newContainer = new Container(currentContainer); currentContainer.addElement(newContainer); currentContainer = newContainer; currentContainer.addElement(element); } else if (shouldCloseContainer(type)) { Container matchingContainer = findNearestContainerToClose( type, currentContainer); if (matchingContainer == null) { currentContainer.addElement(element); } else { matchingContainer.addElement(element); closeContainer(matchingContainer); currentContainer = matchingContainer.getParent(); } } else { boolean wasMerged = false; List<IContainerElement> elements = currentContainer .getElements(); if (!elements.isEmpty()) { IContainerElement lastElement = elements.get(elements .size() - 1); ContainerElementType lastType = lastElement.getType(); if (lastType != null && lastType.canBeMerged() && type == lastType) { if (lastElement instanceof ContainerElement) { ContainerElement contElement = (ContainerElement) lastElement; contElement.increaseEndPosition(); wasMerged = true; } } } if (!wasMerged) { currentContainer.addElement(element); } } } } return mainContainer; } private void closeContainer(final Container container) { if (container != null) { for (IContainerElement contElem : container.getElements()) { if (contElem.isComplex()) { Container cont = (Container) contElem; if (cont.isOpenForModification()) { closeContainer(cont); } } } container.closeForModification(); } } private Container findNearestContainerToClose( final ContainerElementType type, final Container currentContainer) { Container cont = null; if (currentContainer != null) { if (currentContainer.isOpenForModification()) { for (IContainerElement contElement : currentContainer .getElements()) { if (contElement.isComplex()) { cont = findNearestContainerToClose(type, (Container) contElement); if (cont != null) { break; } } } if (cont == null) { if (!currentContainer.getElements().isEmpty()) { if (type == ContainerElementType .getCloseContainerType(currentContainer .getElements().get(0).getType())) { cont = currentContainer; } } } } } return cont; } private boolean shouldCloseContainer(ContainerElementType type) { return type.getCloseContainer() != null; } }