<commit_before>package org.jboss.reddeer.eclipse.jface.viewer.handler;

import java.util.Iterator;

import org.eclipse.swt.custom.StyleRange;
import org.jboss.reddeer.eclipse.jface.exception.JFaceLayerException;
import org.jboss.reddeer.swt.api.TreeItem;
import org.jboss.reddeer.swt.api.Tree;
import org.jboss.reddeer.swt.util.Display;
import org.jboss.reddeer.swt.util.ResultRunnable;
import org.jboss.reddeer.common.logging.Logger;

public class TreeViewerHandler {
	
	private final Logger logger = Logger.getLogger(this.getClass());
	private static TreeViewerHandler instance;
	
	public TreeViewerHandler() {
	}
	
	/**
	 * Returns instance of TreeViewerHandler class. If instance is not 
	 * existing yet, new instance is created and returned.
	 * 
	 * @return instance of class TreeViewerHandler
	 */
	public static TreeViewerHandler getInstance() {
		if (instance == null) {
			instance = new TreeViewerHandler();
		}
		return instance;
	}
	
	/**
	 * Gets {@link TreeItem} with specified name placed under 
	 * specified {@link Tree}.
	 * 
	 * @param tree tree where to find tree item
	 * @param name name of the tree item to find
	 * @return tree item with specified name placed under specified tree
	 */
	public TreeItem getTreeItem(Tree tree, String name) {
		Iterator<TreeItem> iterator = tree.getItems().iterator();
		while (iterator.hasNext()) {
			TreeItem item = iterator.next();
			if (getNonStyledText(item).equals(name)) {
				return item;
			}
		}
		
		throw new JFaceLayerException("There is no item with name " + name + " placed " +
				"under specified tree");
	}
	
	/**
	 * Gets {@link TreeItem} defined by specified path placed under 
	 * specified {@link Tree}.
	 * 
	 * @param tree tree where to find tree item
	 * @param path path to the tree item
	 * @return tree item placed under specified tree
	 */
	public TreeItem getTreeItem(Tree tree, String... path) {
		TreeItem item;
		
		TreeItem parentItem = getTreeItem(tree, path[0]);
		item = parentItem;
	
		if (path.length > 1) {
			String[] pathToItem = new String[path.length-1];
			System.arraycopy(path, 1, pathToItem, 0, path.length - 1);
			item = getTreeItem(parentItem, pathToItem);
		}
		
		return item;
	}
	
	
	/**
	 * Gets tree item specified by a name without decorators - styled text
	 * 
	 * @param treeItem parent item of desired item 
	 * @param name of desired item
	 * @return tree item with specified name
	 */
	public TreeItem getTreeItem(TreeItem treeItem, String name) {
		Iterator<TreeItem> iterator = treeItem.getItems().iterator();
		while (iterator.hasNext()) {
			TreeItem item = iterator.next();
			if (getNonStyledText(item).equals(name)) {
				logger.info("Tree item with non styled text " + name +
						" has been found");
				return item;
			}
		}
		
		throw new JFaceLayerException("Tree item with text "
				+ getNonStyledText(treeItem) + " (without decorators)"
				+ " has no tree item with text " + name + " (without decorators).");
	}
	
	/**
	 * Gets tree item specified by path without decorators.
	 * 
	 * @param treeItem
	 * @param path
	 * @return
	 */
	public TreeItem getTreeItem(TreeItem treeItem, String... path) {
		TreeItem item = treeItem;
		int index = 0;
		
		while (index < path.length - 1) {
			item = getTreeItem(item, path[index]);
			if (!item.isExpanded()) {
				item.expand();
			}
			index++;
		}
		
		return getTreeItem(item, path[index]);
	}
	
	private TreeItemTexts parseText(TreeItem item) {
		final org.eclipse.swt.widgets.TreeItem swtTreeItem = item.getSWTWidget();
		return Display.syncExec(new ResultRunnable<TreeViewerHandler.TreeItemTexts>() {

			@Override
			public TreeViewerHandler.TreeItemTexts run() {
				String nonStyledText = null;
				String[] styledTexts = null;
				StyleRange[] styleRanges = getStyleRanges(swtTreeItem);
				
				if (styleRanges == null) {
					// Everything is ok, there is no styled texts
					nonStyledText = swtTreeItem.getText().trim();
					styledTexts = null;
				} else {
					// Here it goes. There are some styled texts
					String rawText = swtTreeItem.getText();
					String[] tmpStyledTexts = new String[styleRanges.length];
					String tmpNonStyledText = null;
					int currentTextIndex = 0;
					int i = 0;
					
					for (StyleRange range: getStyleRanges(swtTreeItem)) {
						// At some point there is a non-styled text
						if (range.start > currentTextIndex) {
							tmpNonStyledText = rawText.substring(currentTextIndex, 
									range.start).trim();
						}
						
						tmpStyledTexts[i] = rawText.substring(range.start, range.start +
								range.length).trim();
						currentTextIndex = range.start + range.length + 1;
						i++;
					}
					
					if (tmpNonStyledText == null) {
						tmpNonStyledText = rawText.substring(currentTextIndex).trim();
					}
					
					nonStyledText = tmpNonStyledText;
					styledTexts = tmpStyledTexts;
				}
				
				return new TreeItemTexts(nonStyledText, styledTexts);
			}
		});
	}

	// Should be run inside Display.syncExec method - in parseText method<commit_msg>Tree item styled text containing styled white spaces fixed (fixes #722)<commit_after>package org.jboss.reddeer.eclipse.jface.viewer.handler;

import java.util.Iterator;

import org.eclipse.swt.custom.StyleRange;
import org.jboss.reddeer.eclipse.jface.exception.JFaceLayerException;
import org.jboss.reddeer.swt.api.TreeItem;
import org.jboss.reddeer.swt.api.Tree;
import org.jboss.reddeer.swt.util.Display;
import org.jboss.reddeer.swt.util.ResultRunnable;
import org.jboss.reddeer.common.logging.Logger;

public class TreeViewerHandler {
	
	private final Logger logger = Logger.getLogger(this.getClass());
	private static TreeViewerHandler instance;
	
	public TreeViewerHandler() {
	}
	
	/**
	 * Returns instance of TreeViewerHandler class. If instance is not 
	 * existing yet, new instance is created and returned.
	 * 
	 * @return instance of class TreeViewerHandler
	 */
	public static TreeViewerHandler getInstance() {
		if (instance == null) {
			instance = new TreeViewerHandler();
		}
		return instance;
	}
	
	/**
	 * Gets {@link TreeItem} with specified name placed under 
	 * specified {@link Tree}.
	 * 
	 * @param tree tree where to find tree item
	 * @param name name of the tree item to find
	 * @return tree item with specified name placed under specified tree
	 */
	public TreeItem getTreeItem(Tree tree, String name) {
		Iterator<TreeItem> iterator = tree.getItems().iterator();
		while (iterator.hasNext()) {
			TreeItem item = iterator.next();
			if (getNonStyledText(item).equals(name)) {
				return item;
			}
		}
		
		throw new JFaceLayerException("There is no item with name " + name + " placed " +
				"under specified tree");
	}
	
	/**
	 * Gets {@link TreeItem} defined by specified path placed under 
	 * specified {@link Tree}.
	 * 
	 * @param tree tree where to find tree item
	 * @param path path to the tree item
	 * @return tree item placed under specified tree
	 */
	public TreeItem getTreeItem(Tree tree, String... path) {
		TreeItem item;
		
		TreeItem parentItem = getTreeItem(tree, path[0]);
		item = parentItem;
	
		if (path.length > 1) {
			String[] pathToItem = new String[path.length-1];
			System.arraycopy(path, 1, pathToItem, 0, path.length - 1);
			item = getTreeItem(parentItem, pathToItem);
		}
		
		return item;
	}
	
	
	/**
	 * Gets tree item specified by a name without decorators - styled text
	 * 
	 * @param treeItem parent item of desired item 
	 * @param name of desired item
	 * @return tree item with specified name
	 */
	public TreeItem getTreeItem(TreeItem treeItem, String name) {
		Iterator<TreeItem> iterator = treeItem.getItems().iterator();
		while (iterator.hasNext()) {
			TreeItem item = iterator.next();
			if (getNonStyledText(item).equals(name)) {
				logger.info("Tree item with non styled text " + name +
						" has been found");
				return item;
			}
		}
		
		throw new JFaceLayerException("Tree item with text "
				+ getNonStyledText(treeItem) + " (without decorators)"
				+ " has no tree item with text " + name + " (without decorators).");
	}
	
	/**
	 * Gets tree item specified by path without decorators.
	 * 
	 * @param treeItem
	 * @param path
	 * @return
	 */
	public TreeItem getTreeItem(TreeItem treeItem, String... path) {
		TreeItem item = treeItem;
		int index = 0;
		
		while (index < path.length - 1) {
			item = getTreeItem(item, path[index]);
			if (!item.isExpanded()) {
				item.expand();
			}
			index++;
		}
		
		return getTreeItem(item, path[index]);
	}
	
	private TreeItemTexts parseText(TreeItem item) {
		final org.eclipse.swt.widgets.TreeItem swtTreeItem = item.getSWTWidget();
		return Display.syncExec(new ResultRunnable<TreeViewerHandler.TreeItemTexts>() {

			@Override
			public TreeViewerHandler.TreeItemTexts run() {
				String nonStyledText = null;
				String[] styledTexts = null;
				StyleRange[] styleRanges = getStyleRanges(swtTreeItem);
				
				if (styleRanges == null) {
					// Everything is ok, there is no styled texts
					nonStyledText = swtTreeItem.getText().trim();
					styledTexts = null;
				} else {
					// Here it goes. There are some styled texts
					String rawText = swtTreeItem.getText();
					String[] tmpStyledTexts = new String[styleRanges.length];
					String tmpNonStyledText = null;
					int currentTextIndex = 0;
					int i = 0;
					
					for (StyleRange range: getStyleRanges(swtTreeItem)) {
						// At some point there is a non-styled text
						if (range.start > currentTextIndex) {
							tmpNonStyledText = rawText.substring(currentTextIndex, 
									range.start).trim();
						}
						
						tmpStyledTexts[i] = rawText.substring(range.start, range.start +
								range.length).trim();
						currentTextIndex = range.start + range.length;
						i++;
					}
					
					if (tmpNonStyledText == null) {
						tmpNonStyledText = rawText.substring(currentTextIndex).trim();
					}
					
					nonStyledText = tmpNonStyledText;
					styledTexts = tmpStyledTexts;
				}
				
				return new TreeItemTexts(nonStyledText, styledTexts);
			}
		});
	}

	// Should be run inside Display.syncExec method - in parseText method
{'fraction_non_alphanumeric': 0.10766785856177989, 'fraction_numerical': 0.0023837902264600714, 'mean_word_length': 3.261108760050783, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4447256', 'n_tokens_mistral': 3750, 'n_tokens_neox': 3023, 'n_words': 864}