/******************************************************************************* * Copyright (c) 2004, 2010 BREDEX GmbH. * 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.client.ui.rcp.search.query; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jubula.client.core.model.ExecObjContPO; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.IPersistentObject; import org.eclipse.jubula.client.core.model.IProjectPO; import org.eclipse.jubula.client.core.model.SpecObjContPO; import org.eclipse.jubula.client.core.persistence.GeneralStorage; import org.eclipse.jubula.client.core.persistence.IExecPersistable; import org.eclipse.jubula.client.core.persistence.ISpecPersistable; import org.eclipse.jubula.client.core.utils.ITreeNodeOperation; import org.eclipse.jubula.client.core.utils.ITreeTraverserContext; import org.eclipse.jubula.client.core.utils.TreeTraverser; import org.eclipse.jubula.client.ui.rcp.controllers.MultipleTCBTracker; import org.eclipse.jubula.client.ui.rcp.search.data.SearchOptions; import org.eclipse.jubula.client.ui.rcp.search.data.TestSuiteBrowserWrapper; import org.eclipse.jubula.client.ui.rcp.search.data.TreeViewSelectionRetriever; import org.eclipse.jubula.client.ui.rcp.search.data.TypeName; import org.eclipse.jubula.client.ui.rcp.views.TestCaseBrowser; /** * @author BREDEX GmbH * @created April 29, 2013 */ public abstract class AbstractTraverserQuery extends AbstractStringQuery implements ITreeNodeOperation<INodePO> { /** * @param searchData The search options. * @param viewId The view Id to open. */ protected AbstractTraverserQuery(SearchOptions searchData, String viewId) { super(searchData, viewId); } /** * Traverse the whole project or all selected nodes including all children * using the {@link TreeTraverser}. The method {@link #operate(INodePO)} * is called on every visited node. */ protected void traverse() { boolean searchInCurrentSelection = getSearchOptions() .hasNodesToBeSelected(); if (searchInCurrentSelection) { // search in Test Suite Browser if (getSearchOptions().isSearchingInTestSuiteBrowser()) { traverseStructuredSelection( TreeViewSelectionRetriever.getStructuredSelection( TestSuiteBrowserWrapper.getInstance())); } // search in Test Case Browser if (getSearchOptions().isSearchingInTestCaseBrowser()) { traverseTestCaseBrowsers(); } } else { IProjectPO activeProject = GeneralStorage.getInstance() .getProject(); TreeTraverser tt = new TreeTraverser( activeProject, this, true, true); tt.traverse(true); } } /** * Traverse all selected nodes in all Test Case Browsers. */ private void traverseTestCaseBrowsers() { List<TestCaseBrowser> tcbs = new ArrayList<TestCaseBrowser>(); MultipleTCBTracker tracker = MultipleTCBTracker.getInstance(); if (getSearchOptions().isSearchinInTestCaseBrowsersAll()) { tcbs = tracker.getOpenTCBs(); } else { TestCaseBrowser masterTCB = tracker.getMainTCB(); if (masterTCB != null) { tcbs.add(masterTCB); } } traverseTestCaseBrowserList(tcbs); } /** * Traverse all selected nodes in the given list of Test Case Browsers. * @param tcbs The list of Test Case Browsers. */ private void traverseTestCaseBrowserList(List<TestCaseBrowser> tcbs) { for (TestCaseBrowser tcb: tcbs) { traverseStructuredSelection( TreeViewSelectionRetriever.getStructuredSelection(tcb)); } } /** * Search in structured selection by using {@link TreeTraverser} * to search in selected nodes including there children. * @param structuredSelection The structured selection. */ private void traverseStructuredSelection(IStructuredSelection structuredSelection) { if (structuredSelection != null) { @SuppressWarnings("unchecked") List<IPersistentObject> selectionList = structuredSelection.toList(); for (IPersistentObject node: selectionList) { traversePersistentObject(node); } } } /** * @param node The persistent object starting for traversing. */ private void traversePersistentObject(IPersistentObject node) { if (node instanceof ExecObjContPO) { // root node of TSB List<IExecPersistable> specList = ((ExecObjContPO) node).getExecObjList(); for (IExecPersistable spec: specList) { traverseNodePO(spec); } } else if (node instanceof SpecObjContPO) { // root node of TCB List<ISpecPersistable> specList = ((SpecObjContPO) node).getSpecObjList(); for (ISpecPersistable spec: specList) { traverseNodePO(spec); } } else if (node instanceof INodePO) { traverseNodePO((INodePO) node); } } /** * @param node * The node starting the {@link TreeTraverser}. */ private void traverseNodePO(INodePO node) { TreeTraverser tt = new TreeTraverser(node, this); tt.traverse(true); } /** * @param node The node for type check. * @return True, if the given node has a selected type, otherwise false. */ protected boolean matchingSearchType(INodePO node) { for (TypeName type: getSearchOptions().getSelectedSearchableTypes()) { if (type.getType().equals(node.getClass())) { return true; } } return false; } /** * {@inheritDoc} */ public boolean operate(ITreeTraverserContext<INodePO> ctx, INodePO parent, INodePO node, boolean alreadyVisited) { if (alreadyVisited) { return false; // do not search in children, if node has been visited } if (getSearchOptions().isSearchingInReusedProjects() // parent == null, if node is root of search || parent == null // parent and node have to be in the same project || node.getParentProjectId() .equals(getSearchOptions().getProject().getId()) ) { IProgressMonitor monitor = getMonitor(); monitor.worked(1); return operate(node) && !monitor.isCanceled(); // search in children } return false; } /** * {@inheritDoc} */ public void postOperate(ITreeTraverserContext<INodePO> ctx, INodePO parent, INodePO node, boolean alreadyVisited) { // do nothing } /** * Notification method on traversing the current node. * @param node The current node operating on. * @return True, if children has to be visited. */ protected abstract boolean operate(INodePO node); }