/*
* Copyright 2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.api.internal.tasks;
import org.gradle.api.Buildable;
import org.gradle.api.Task;
import org.gradle.api.tasks.TaskDependency;
import org.gradle.internal.graph.CachingDirectedGraphWalker;
import org.gradle.internal.graph.DirectedGraph;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;
/**
* <p>A {@link TaskDependencyResolveContext} which caches the dependencies for each {@link
* org.gradle.api.tasks.TaskDependency} and {@link org.gradle.api.Buildable} instance during traversal of task
* dependencies.</p>
*
* <p>Supported types:</p> <ul>
*
* <li>{@link org.gradle.api.Task}</li>
*
* <li>{@link org.gradle.api.tasks.TaskDependency}</li>
*
* <li>{@link org.gradle.api.internal.tasks.TaskDependencyInternal}</li>
*
* <li>{@link org.gradle.api.Buildable}</li>
*
* </ul>
*/
public class CachingTaskDependencyResolveContext implements TaskDependencyResolveContext, TaskDependency {
private final LinkedList<Object> queue = new LinkedList<Object>();
private final CachingDirectedGraphWalker<Object, Task> walker = new CachingDirectedGraphWalker<Object, Task>(
new TaskGraphImpl());
private Task task;
public Set<? extends Task> getDependencies(Task task) {
add(task.getTaskDependencies());
return resolve(task);
}
public Task getTask() {
return task;
}
public Set<Task> resolve(Task task) {
this.task = task;
try {
return doResolve();
} catch (Exception e) {
throw new TaskDependencyResolveException(String.format("Could not determine the dependencies of %s.", task), e);
} finally {
queue.clear();
this.task = null;
}
}
private Set<Task> doResolve() {
walker.add(queue);
return walker.findValues();
}
public void add(Object dependency) {
queue.add(dependency);
}
private class TaskGraphImpl implements DirectedGraph<Object, Task> {
public void getNodeValues(Object node, Collection<? super Task> values, Collection<? super Object> connectedNodes) {
if (node instanceof TaskDependencyContainer) {
TaskDependencyContainer taskDependency = (TaskDependencyContainer) node;
queue.clear();
taskDependency.visitDependencies(CachingTaskDependencyResolveContext.this);
connectedNodes.addAll(queue);
} else if (node instanceof Buildable) {
Buildable buildable = (Buildable) node;
connectedNodes.add(buildable.getBuildDependencies());
} else if (node instanceof TaskDependency) {
TaskDependency dependency = (TaskDependency) node;
values.addAll(dependency.getDependencies(task));
} else if (node instanceof Task) {
values.add((Task) node);
} else {
throw new IllegalArgumentException(String.format("Cannot resolve object of unknown type %s to a Task.",
node.getClass().getSimpleName()));
}
}
}
}