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

org.openlca.git.repo.Entries Maven / Gradle / Ivy

There is a newer version: 2.2.1
Show newest version
package org.openlca.git.repo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.openlca.git.model.Entry;
import org.openlca.git.model.Entry.EntryType;
import org.openlca.git.util.GitUtil;
import org.openlca.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Entries {

	private static final Logger log = LoggerFactory.getLogger(Entries.class);
	private final OlcaRepository repo;

	static Entries of(OlcaRepository repo) {
		return new Entries(repo);
	}

	private Entries(OlcaRepository repo) {
		this.repo = repo;
	}

	public Find find() {
		return new Find();
	}

	public void iterate(Consumer consumer) {
		var head = repo.commits.head();
		if (head == null)
			return;
		iterate(head.id, consumer);
	}

	public void iterate(String commitId, Consumer consumer) {
		iterate(commitId, null, consumer);
	}

	public void iterate(String commitId, String path, Consumer consumer) {
		new Iterate().commit(commitId).path(path).recursive().call(consumer);
	}

	public Entry get(String path, String commitId) {
		try {
			var commit = repo.commits.getRev(commitId);
			if (commit == null)
				return null;
			var objectId = repo.getObjectId(commit, path);
			return new Entry(path, commitId, objectId);
		} catch (IOException e) {
			log.error("Error finding sub tree for " + path);
			return null;
		}
	}

	public class Find {

		private final Iterate iterate = new Iterate();

		public Find path(String path) {
			iterate.path(path);
			return this;
		}

		public Find commit(String commitId) {
			iterate.commit(commitId);
			return this;
		}

		public Find recursive() {
			iterate.recursive();
			return this;
		}

		public List all() {
			var entries = new ArrayList();
			iterate.call(entries::add);
			return entries;
		}

		public long count() {
			var count = new AtomicLong(0);
			iterate.call(e -> count.incrementAndGet());
			return count.get();
		}

		public boolean contains(String path) {
			var value = new AtomicBoolean(false);
			iterate.call(e -> {
				if (e.path.endsWith("/" + path)) {
					value.set(true);
				}
			});
			return value.get();
		}

		public Map asMap() {
			var map = new HashMap();
			iterate.call(entry -> {
				// TODO how to avoid duplicate keys or handle them better
				if (map.containsKey(entry.path))
					return;
				map.put(entry.path, entry);
			});
			return map;
		}

	}

	private class Iterate {

		private String path;
		private String commitId;
		private boolean recursive;

		private Iterate path(String path) {
			this.path = path;
			return this;
		}

		private Iterate commit(String commitId) {
			this.commitId = commitId;
			return this;
		}

		private Iterate recursive() {
			this.recursive = true;
			return this;
		}

		private void call(Consumer consumer) {
			try {
				var commit = repo.commits.getRev(commitId);
				if (commit == null)
					return;
				var treeId = Strings.nullOrEmpty(path)
						? commit.getTree().getId()
						: repo.getSubTreeId(commit.getTree().getId(), path);
				if (treeId.equals(ObjectId.zeroId()))
					return;
				call(treeId, commit, path, consumer);
			} catch (IOException e) {
				log.error("Error walking commit " + commitId, e);
			}
		}

		private void call(ObjectId treeId, RevCommit commit, String path, Consumer consumer) throws IOException {
			try (var walk = new TreeWalk(repo)) {
				walk.addTree(treeId);
				walk.setRecursive(false);
				var filter = KnownFilesFilter.createForPath(path);
				walk.setFilter(filter);
				while (walk.next()) {
					var name = GitUtil.decode(walk.getNameString());
					var id = walk.getObjectId(0);
					var fullPath = Strings.nullOrEmpty(path) ? name : path + "/" + name;
					var entry = new Entry(fullPath, commit.getName(), id);
					consumer.accept(entry);
					if (recursive && entry.typeOfEntry != EntryType.DATASET) {
						call(id, commit, fullPath, consumer);
					}
				}
			}
		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy