Package org.dru.clay.resolver

Source Code of org.dru.clay.resolver.DependencyResolverImpl

package org.dru.clay.resolver;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

import org.dru.clay.logger.Logger;
import org.dru.clay.logger.LoggerFactory;
import org.dru.clay.respository.Configuration;
import org.dru.clay.respository.Repository;
import org.dru.clay.respository.ResolveResult;
import org.dru.clay.respository.artifact.Artifact;
import org.dru.clay.respository.artifact.Group;
import org.dru.clay.respository.artifact.Module;
import org.dru.clay.respository.artifact.UnresolvedArtifact;
import org.dru.clay.respository.dependency.Dependency;
import org.dru.clay.respository.transport.Transport;

public class DependencyResolverImpl implements DependencyResolver {
  private static final int RESOLVE_THREAD_COUNT = 5;

  private final Logger logger = LoggerFactory.getLogger(DependencyResolverImpl.class);

  private final Repository repository;
  private final Transport transport;
  private final DirectoryLayout layout;

  private final Object lock = new Object();
  private int count;
 
  final Set<Artifact> visitedArtifacts = new HashSet<Artifact>();
  final Queue<ConfigurationContext> resolveQueue = new LinkedBlockingDeque<ConfigurationContext>();
  final List<File> downloadedFiles = new ArrayList<File>();
 
  ExecutorService executorService = null;

  public DependencyResolverImpl(Repository repository, Transport transport) {
    this.repository = repository;
    this.transport = transport;
    this.layout = new FlatDirectoryLayout();
  }
 
  @Override
  public void begin() {
    if (executorService != null) {
      executorService.shutdownNow();
    }
    downloadedFiles.clear();
    executorService = Executors.newFixedThreadPool(RESOLVE_THREAD_COUNT);
  }

  @Override
  public Collection<File> end() {
    try {
      synchronized (lock) {
        while (count > 0) {
          lock.wait(0L);
        }
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
      // TODO: All list might not have been downloaded.
    } finally {
      visitedArtifacts.clear();
      resolveQueue.clear();
      count = 0;
     
      executorService.shutdownNow();
      transport.cleanup();
    }
   
    return downloadedFiles;
  }

  @Override
  public void resolve(final File directory, String configuration, Collection<Dependency> dependencies) {
    filterDependencies(Collections.singleton(configuration), dependencies, resolveQueue);

    while (resolveQueue.peek() != null) {
      final ConfigurationContext context = resolveQueue.poll();
      final Dependency dependency = context.getDependency();
      final Group group = dependency.getGroup();
      final UnresolvedArtifact unresolved = dependency.getArtifact();

      final Artifact resolveArtifact = repository.lookup(transport, group, unresolved);

      logger.info("Resolved %s -> %s", unresolved, resolveArtifact);

      // TODO: Handle version conflicts
      if (visitedArtifacts.contains(resolveArtifact)) {
        // artifact already visited
        continue;
      }
      visitedArtifacts.add(resolveArtifact);

      final Module resolveModule = new Module(group, resolveArtifact);
      final ResolveResult resolveResult = repository.resolve(transport, resolveModule);

      for (Configuration config : resolveResult.getConfigurations()) {
        if (!context.getConfigurations().contains(config.getName())) {
          // the configuration isn't used in this resolve
          continue;
        }

        synchronized (lock) {
          count += config.getArtifacts().size();
        }

        for (final Artifact artifact : config.getArtifacts()) {
          System.out.println("Downloading " + artifact); // TODO: fix

          executorService.submit(new Runnable() {
            @Override
            public void run() {
              final File destination = layout.file(directory, resolveModule, artifact);
              try {
                destination.getParentFile().mkdirs();
                repository.get(transport, resolveModule, artifact, destination);
              } finally {
                synchronized (lock) {
                  downloadedFiles.add(destination);
                  count--;
                  lock.notify();
                }
              }
            }
          });
        }
      }

      filterDependencies(context.getConfigurations(), resolveResult.getDependencies(), resolveQueue);
    }
  }

  private void filterDependencies(Set<String> configs, Collection<Dependency> dependencies, final Queue<ConfigurationContext> resolveQueue) {
    for (Dependency dependency : dependencies) {
      for (String configuration : configs) {
        final Set<String> configurations = dependency.getMapping().transform(configuration);
        if (configurations.isEmpty()) {
          // the dependency is not part of the current configuration
          break;
        }
        resolveQueue.add(new ConfigurationContext(dependency, configurations));
      }
    }
  }
}
TOP

Related Classes of org.dru.clay.resolver.DependencyResolverImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.