All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.sourced.engine.iterator.RepositoryIterator.scala Maven / Gradle / Ivy

The newest version!
package tech.sourced.engine.iterator

import org.eclipse.jgit.lib.Repository
import tech.sourced.engine.util.{CompiledFilter, Filters}

/**
  * Iterator that will return rows of repositories in a repository.
  *
  * @param repositoryPath path of the given repository
  * @param finalColumns   final columns that must be in the resultant row
  * @param repo           repository to get the data from
  * @param filters        filters for the iterator
  */
class RepositoryIterator(repositoryPath: String,
                         finalColumns: Array[String],
                         repo: Repository,
                         filters: Seq[CompiledFilter],
                         skipReadErrors: Boolean)
  extends ChainableIterator[String](
    finalColumns,
    null,
    filters,
    repo,
    skipReadErrors
  ) {

  // since this iterator does not override getFilters method of RootedRepository
  // we can cache here the matching cases, because they are not going to change.
  private val matchingFilters = Filters(filters)

  /** @inheritdoc*/
  override protected def loadIterator(filters: Seq[CompiledFilter]): Iterator[String] =
    RepositoryIterator.loadIterator(repo, matchingFilters)

  /** @inheritdoc*/
  override protected def mapColumns(id: String): RawRow = {
    val c = repo.getConfig
    val remote = RootedRepo.getRepositoryRemote(repo, id)
    val urls = remote.map(r => c.getStringList("remote", r, "url"))
      .orElse(Some(Array[String]())).get
    val isFork = remote.map(r => c.getBoolean("remote", r, "isfork", false))
      .orElse(Some(false)).get

    Map[String, Any](
      "id" -> id,
      "urls" -> urls,
      "is_fork" -> isFork,
      "repository_path" -> repositoryPath
    )
  }
}

object RepositoryIterator {

  import scala.collection.JavaConverters._

  /**
    * Returns an iterator of references.
    *
    * @param repo    repository to get the data from
    * @param filters filters to skip some rows. The only supported filters at the iterator
    *                level are by repository id. The key of said filters
    *                are controlled by the parameter `repoKey`.
    * @param repoKey name of the repository id filter key
    * @return the iterator
    */
  def loadIterator(repo: Repository,
                   filters: Filters,
                   repoKey: String = "id"): Iterator[String] = {
    // If there's any non-remote reference, it will show up here, thus
    // making the local repository appear. If we only take into account
    // the remotes the result will be different from the one returned by
    // the reference iterator.
    // This makes us process this twice in a chained reference iterator
    // scenario, even though the result would be correct without this,
    // but it's needed for correctness when the table is asked independently.
    val refRepos = repo.getAllRefs.asScala.keys
      .map(ref => RootedRepo.parseRef(repo, ref)._1)

    val repos = repo.getConfig.getSubsections("remote").asScala.toIterator
      .map(RootedRepo.getRepositoryId(repo, _).get) ++ refRepos

    val iter = repos.toList.distinct.toIterator

    val filterKeys = Seq("id", repoKey)
    if (filters.hasFilters(filterKeys: _*)) {
      iter.filter(filters.matches(filterKeys, _))
    } else {
      iter
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy