/* * Copyright (c) 2015 the original author or authors. * 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: * Etienne Studer & Donát Csikós (Gradle Inc.) - initial API and implementation and initial documentation */ package org.eclipse.buildship.ui.view.task; import java.util.List; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterables; import com.gradleware.tooling.toolingmodel.OmniEclipseProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.buildship.ui.util.nodeselection.NodeSelection; /** * Contains the logic that determines the state of the actions of the {@link TaskView} for a given * selection. */ public final class TaskViewActionStateRules { private TaskViewActionStateRules() { } /** * Determines whether actions related to task execution should be visible or hidden. * * @param nodeSelection the node selection based on which to make the decision * @return {@code true} if actions related to task execution should be visible */ public static boolean taskScopedTaskExecutionActionsVisibleFor(NodeSelection nodeSelection) { // short-circuit in case the selection is empty if (nodeSelection.isEmpty()) { return false; } // show action if all selected nodes are task nodes (even if they are task nodes of // different types) return nodeSelection.hasAllNodesOfType(TaskNode.class); } /** * Determines whether the actions related to task execution should be enabled or disabled. * * @param nodeSelection the node selection based on which to make the decision * @return {@code true} if actions related to task execution should be enabled */ public static boolean taskScopedTaskExecutionActionsEnabledFor(NodeSelection nodeSelection) { // short-circuit in case the selection is empty if (nodeSelection.isEmpty()) { return false; } // execution is enabled only if no tasks from included builds are selected and each task is from the same project List<?> elements = nodeSelection.toList(); List<TaskNode> taskNodes = FluentIterable.from(elements).filter(TaskNode.class).toList(); if (elements.size() != taskNodes.size() || hasMultipleOrIncludedParentProject(taskNodes)) { return false; } // if project tasks are selected only then the execution should be permitted List<ProjectTaskNode> projectNodes = FluentIterable.from(elements).filter(ProjectTaskNode.class).toList(); if (projectNodes.size() == taskNodes.size()) { return true; } // if task selectors are selected only then the execution should be permitted if the root project can be found List<TaskSelectorNode> taskSelectorNodes = FluentIterable.from(elements).filter(TaskSelectorNode.class).toList(); if (taskSelectorNodes.size() == taskNodes.size()) { return canFindRootProjects(taskSelectorNodes); } // as a default disable the execution return false; } private static boolean hasMultipleOrIncludedParentProject(List<TaskNode> nodes) { Preconditions.checkArgument(!nodes.isEmpty()); final ProjectNode firstParent = nodes.get(0).getParentProjectNode(); if (firstParent.isIncludedProject()) { return true; } return Iterables.any(nodes, new Predicate<TaskNode>() { @Override public boolean apply(TaskNode node) { return !node.getParentProjectNode().equals(firstParent); } }); } //see https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:initialization private static boolean canFindRootProjects(List<TaskSelectorNode> nodes) { return Iterables.all(nodes, new Predicate<TaskNode>() { @Override public boolean apply(TaskNode node) { OmniEclipseProject project = node.getParentProjectNode().getEclipseProject(); Path projectPath = new Path(project.getProjectDirectory().getPath()); IPath masterPath = projectPath.removeLastSegments(1).append("master"); Path rootPath = new Path(project.getRoot().getProjectDirectory().getPath()); return rootPath.isPrefixOf(projectPath) || rootPath.equals(masterPath); } }); } /** * Determines whether the project-scoped actions related to task execution should be visible or hidden. * * @param nodeSelection the node selection based on which to make the decision * @return {@code true} if project-scoped actions related to task execution should be visible */ @SuppressWarnings("SimplifiableIfStatement") public static boolean projectScopedTaskExecutionActionsVisibleFor(NodeSelection nodeSelection) { // short-circuit in case the selection is empty if (nodeSelection.isEmpty()) { return false; } return nodeSelection.hasAllNodesOfType(ProjectNode.class); } /** * Determines whether the project-scoped actions related to task execution should be enabled or disabled. * * @param nodeSelection the node selection based on which to make the decision * @return {@code true} if project-scoped actions related to task execution should be enabled */ @SuppressWarnings("SimplifiableIfStatement") public static boolean projectScopedTaskExecutionActionsEnabledFor(NodeSelection nodeSelection) { // short-circuit in case the selection is empty if (nodeSelection.isEmpty()) { return false; } return nodeSelection.hasAllNodesOfType(ProjectNode.class) && nodeSelection.isSingleSelection() && !nodeSelection.getFirstElement(ProjectNode.class).isIncludedProject(); } }