/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import org.gradle.api.artifacts.result.ArtifactResult
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.specs.Specs
import org.gradle.jvm.JvmLibrary
import org.gradle.api.component.Artifact
import org.gradle.language.base.artifact.SourcesArtifact
import org.gradle.language.java.artifact.JavadocArtifact
import org.gradle.tooling.model.Task
apply plugin: 'groovy'

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.10'
}

task downloadDependencies << {
     Set ids = new HashSet();
     project.configurations.testCompile.incoming.resolutionResult.allDependencies.each() {
        if (it instanceof ResolvedDependencyResult) {
            if (it.requested instanceof ModuleComponentSelector) {
                ids.add(it.selected.id)
            }
        }         
     }
     org.gradle.api.internal.artifacts.result.DefaultArtifactResolutionResult result = project.dependencies.createArtifactResolutionQuery()
    .forComponents(ids)
    .withArtifacts(JvmLibrary, SourcesArtifact, JavadocArtifact)
    .execute()
    Collection coll = result.resolvedComponents
    for(def o: coll) {
        def sources = o.getArtifacts(SourcesArtifact)
        sources.each() {
            if (it instanceof ResolvedArtifactResult) {
                println it.file
            }
        }

    }
}
