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

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

The newest version!
package org.openlca.git.repo;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.jgit.lib.ObjectId;
import org.openlca.core.model.Version;
import org.openlca.core.model.descriptors.RootDescriptor;
import org.openlca.git.model.Entry;
import org.openlca.git.model.Entry.EntryType;
import org.openlca.git.util.TypedRefId;
import org.openlca.git.util.TypedRefIdMap;
import org.openlca.jsonld.Json;
import org.openlca.util.Strings;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class HeadIndex {

	private static final int VERSION = 1;
	private static final String FILE_NAME = "head.index";
	private final OlcaRepository repo;
	private Map map = new HashMap<>();
	private Map> subPaths = new HashMap<>();
	private Map metaInfo = new HashMap<>();
	private TypedRefIdMap pathsByRef = new TypedRefIdMap<>();

	private HeadIndex(OlcaRepository repo) {
		this.repo = repo;
		load();
		fillUp();
	}

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

	public ObjectId getObjectId(String path) {
		var entry = map.get(path);
		if (entry == null)
			return ObjectId.zeroId();
		return entry.objectId;
	}

	public boolean contains(String path) {
		return map.containsKey(path);
	}

	public Set getSubPaths(String path) {
		return subPaths.getOrDefault(path, new HashSet<>());
	}

	public String getPath(TypedRefId typedRefId) {
		return pathsByRef.get(typedRefId);
	}

	public boolean isSameVersion(String path, RootDescriptor d) {
		var info = metaInfo.get(path);
		if (info == null)
			return false;
		return info.matches(d);
	}

	private void load() {
		metaInfo.clear();
		var file = new File(repo.dir, FILE_NAME);
		if (!file.exists())
			return;
		var o = Json.readObject(file).orElse(null);
		if (o == null) {
			file.delete();
			return;
		}
		var indexVersion = Json.getInt(o, "version").orElse(0);
		if (indexVersion != VERSION) {
			file.delete();
			return;
		}
		var array = Json.getArray(o, "metaInfo");
		if (array.isEmpty())
			return;
		for (var e : array) {
			if (!e.isJsonObject())
				continue;
			var obj = e.getAsJsonObject();
			var path = Json.getString(obj, "p");
			if (Strings.nullOrEmpty(path))
				continue;
			var version = Json.getLong(obj, "v", 0);
			var lastChange = Json.getLong(obj, "l", 0);
			metaInfo.put(path, new MetaInfo(version, lastChange));
		}
	}

	public void reload() {
		metaInfo.clear();
		fillUp();
	}

	private void fillUp() {
		try {
			subPaths.clear();
			pathsByRef.clear();
			map = repo.entries.find().recursive().asMap();
			var changed = false;
			for (var entry : map.values()) {
				var path = entry.path;
				var parent = path.contains("/")
						? path.substring(0, path.lastIndexOf("/"))
						: "";
				subPaths.computeIfAbsent(parent, k -> new HashSet<>()).add(path);
				if (entry.typeOfEntry != EntryType.DATASET)
					continue;
				pathsByRef.put(entry, entry.path);
				if (metaInfo.containsKey(entry.path))
					continue;
				metaInfo.put(entry.path, new MetaInfo(repo.datasets.getVersionAndLastChange(entry)));
				changed = true;
			}
			if (!changed)
				return;
			store();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	private void store() {
		var o = new JsonObject();
		o.addProperty("version", VERSION);
		var array = new JsonArray();
		for (var path : metaInfo.keySet()) {
			var obj = new JsonObject();
			obj.addProperty("p", path);
			var value = metaInfo.get(path);
			obj.addProperty("v", value.version);
			obj.addProperty("l", value.lastChange);
			array.add(obj);
		}
		o.add("metaInfo", array);
		Json.write(o, new File(repo.dir, FILE_NAME));
	}

	private static class MetaInfo {

		private final long version;
		private final long lastChange;

		private MetaInfo(Map info) {
			this(getVersion(info), getLastChange(info));
		}

		private MetaInfo(long version, long lastChange) {
			this.version = version;
			this.lastChange = lastChange;
		}

		private boolean matches(RootDescriptor d) {
			return d.version == version
					&& d.lastChange == lastChange;
		}

		private static long getVersion(Map meta) {
			var version = meta.get("version");
			if (version == null)
				return 0;
			return Version.fromString(version.toString()).getValue();
		}

		private static long getLastChange(Map meta) {
			var lastChange = meta.get("lastChange");
			if (lastChange == null)
				return 0;
			var date = Json.parseDate(lastChange.toString());
			return date != null
					? date.getTime()
					: 0;
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy