Merge tag 'v2.3.28' into testing
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / api / a2 / A2Branch.java
diff --git a/org.argeo.init/src/org/argeo/api/a2/A2Branch.java b/org.argeo.init/src/org/argeo/api/a2/A2Branch.java
new file mode 100644 (file)
index 0000000..0b4ef36
--- /dev/null
@@ -0,0 +1,93 @@
+package org.argeo.api.a2;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.osgi.framework.Version;
+
+/**
+ * A logical linear sequence of versions of a given {@link A2Component}. This is
+ * typically a combination of major and minor version, indicating backward
+ * compatibility.
+ */
+public class A2Branch implements Comparable<A2Branch> {
+       private final static Logger logger = System.getLogger(A2Branch.class.getName());
+
+       private final A2Component component;
+       private final String id;
+
+       final SortedMap<Version, A2Module> modules = Collections.synchronizedSortedMap(new TreeMap<>());
+
+       public A2Branch(A2Component component, String id) {
+               this.component = component;
+               this.id = id;
+               component.branches.put(id, this);
+       }
+
+       public Iterable<A2Module> listModules(Object filter) {
+               return modules.values();
+       }
+
+       A2Module getOrAddModule(Version version, Object locator) {
+               if (modules.containsKey(version)) {
+                       A2Module res = modules.get(version);
+                       if (!res.getLocator().equals(locator)) {
+                               logger.log(Level.TRACE,
+                                               () -> "Inconsistent locator " + locator + " (registered: " + res.getLocator() + ")");
+                       }
+                       return res;
+               } else
+                       return new A2Module(this, version, locator);
+       }
+
+       public A2Module last() {
+               return modules.get(modules.lastKey());
+       }
+
+       public A2Module first() {
+               return modules.get(modules.firstKey());
+       }
+
+       public A2Component getComponent() {
+               return component;
+       }
+
+       public String getId() {
+               return id;
+       }
+
+       @Override
+       public int compareTo(A2Branch o) {
+               return id.compareTo(id);
+       }
+
+       @Override
+       public int hashCode() {
+               return id.hashCode();
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof A2Branch) {
+                       A2Branch o = (A2Branch) obj;
+                       return component.equals(o.component) && id.equals(o.id);
+               } else
+                       return false;
+       }
+
+       @Override
+       public String toString() {
+               return getCoordinates();
+       }
+
+       public String getCoordinates() {
+               return component + ":" + id;
+       }
+
+       static String versionToBranchId(Version version) {
+               return version.getMajor() + "." + version.getMinor();
+       }
+}