/******************************************************************************* * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. All rights reserved. * This program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.ui.search; import java.lang.reflect.InvocationTargetException; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher; import org.eclipse.tcf.te.ui.interfaces.ISearchable; /** * The search engine which uses BFS(breadth-first search) algorithm * to search elements that matches a specified matcher. */ public class BreadthFirstSearcher extends AbstractSearcher{ // The queue to pre-populate the nodes to be matched private final Queue<TreePath> queue = new ConcurrentLinkedQueue<TreePath>(); /** * Create a breadth-first searcher with the specified viewer and a * matcher. * * @param viewer The tree viewer. * @param matcher The search matcher used match a single tree node. */ public BreadthFirstSearcher(TreeViewer viewer, ISearchable searchable){ super(viewer, searchable); } /* * (non-Javadoc) * @see org.eclipse.tcf.te.ui.interfaces.ITreeSearcher#setStartPath(org.eclipse.jface.viewers.TreePath) */ @Override public void setStartPath(TreePath path) { this.queue.clear(); Assert.isTrue(this.queue.offer(path)); } /** * Search the tree using a matcher using BFS algorithm. * * @param monitor The monitor reporting the progress. * @return The tree path whose leaf node satisfies the searching rule. */ @Override public TreePath searchNext(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException{ TreePath result = null; ISearchMatcher matcher = fSearchable.getMatcher(); while(queue != null && !queue.isEmpty() && result == null && !monitor.isCanceled()) { TreePath path = queue.poll(); Object element = path.getLastSegment(); Object[] children = getUpdatedChildren(element, monitor); if(children != null && children.length > 0) { for(Object child : children) { TreePath childPath = path.createChildPath(child); Assert.isTrue(queue.offer(childPath)); } } String elementText = fSearchable.getElementText(element); monitor.subTask(elementText); if(matcher.match(element)) { result = path; } } if(monitor.isCanceled()) { throw new InterruptedException(); } return result; } }