Use local copy of latest bndlib code for pre-release testing purposes
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1347815 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java b/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java
new file mode 100644
index 0000000..ec7aec6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java
@@ -0,0 +1,42 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+/**
+ * Simple facade for enumerators so they can be used in for loops.
+ *
+ * @param <T>
+ */
+public class EnumerationIterator<T> implements Iterable<T>, Iterator<T> {
+
+ public static <T> EnumerationIterator<T> iterator(Enumeration<T> e) {
+ return new EnumerationIterator<T>(e);
+ }
+
+ final Enumeration<T> enumerator;
+ volatile boolean done = false;
+
+ public EnumerationIterator(Enumeration<T> e) {
+ enumerator = e;
+ }
+
+ public synchronized Iterator<T> iterator() {
+ if (done)
+ throw new IllegalStateException("Can only be used once");
+ done = true;
+ return this;
+
+ }
+
+ public boolean hasNext() {
+ return enumerator.hasMoreElements();
+ }
+
+ public T next() {
+ return enumerator.nextElement();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("Does not support removes");
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java b/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
new file mode 100644
index 0000000..4c4f558
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
@@ -0,0 +1,31 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class ExtList<T> extends ArrayList<T> {
+ private static final long serialVersionUID = 1L;
+
+ public ExtList(T ... ts) {
+ super(ts.length);
+ for (T t : ts){
+ add(t);
+ }
+ }
+
+ public String join() {
+ return join(",");
+ }
+
+ public String join(String del) {
+ StringBuilder sb = new StringBuilder();
+ String d= "";
+ for ( T t : this) {
+ sb.append(d);
+ d=del;
+ if ( t != null)
+ sb.append(t.toString());
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java b/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java
new file mode 100644
index 0000000..cb96d16
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java
@@ -0,0 +1,12 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class IteratorList<T> extends ArrayList<T> {
+ private static final long serialVersionUID = 1L;
+
+ public IteratorList(Iterator<T> i){
+ while(i.hasNext())
+ add(i.next());
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java b/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java
new file mode 100644
index 0000000..a04ab36
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java
@@ -0,0 +1,54 @@
+package aQute.lib.collections;
+
+import java.io.*;
+import java.util.*;
+
+public class LineCollection implements Iterator<String>, Closeable {
+ final BufferedReader reader;
+ String next;
+
+ public LineCollection(InputStream in) throws IOException {
+ this(new InputStreamReader(in, "UTF8"));
+ }
+
+ public LineCollection(File in) throws IOException {
+ this(new InputStreamReader( new FileInputStream(in),"UTF-8"));
+ }
+
+ public LineCollection(Reader reader) throws IOException {
+ this(new BufferedReader(reader));
+ }
+
+ public LineCollection(BufferedReader reader) throws IOException {
+ this.reader = reader;
+ next = reader.readLine();
+ }
+
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ public String next() {
+ if (next == null)
+ throw new IllegalStateException("Iterator has finished");
+ try {
+ String result = next;
+ next = reader.readLine();
+ if (next == null)
+ reader.close();
+ return result;
+ } catch (Exception e) {
+ // ignore
+ return null;
+ }
+ }
+
+ public void remove() {
+ if (next == null)
+ throw new UnsupportedOperationException("Cannot remove");
+ }
+
+ public void close() throws IOException {
+ reader.close();
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/Logic.java b/bundleplugin/src/main/java/aQute/lib/collections/Logic.java
new file mode 100644
index 0000000..75322dd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/Logic.java
@@ -0,0 +1,22 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class Logic {
+
+ public static <T> Collection<T> retain( Collection<T> first, Collection<T> ... sets) {
+ Set<T> result = new HashSet<T>(first);
+ for ( Collection<T> set : sets ) {
+ result.retainAll(set);
+ }
+ return result;
+ }
+
+ public static <T> Collection<T> remove( Collection<T> first, Collection<T> ... sets) {
+ Set<T> result = new HashSet<T>(first);
+ for ( Collection<T> set : sets ) {
+ result.removeAll(set);
+ }
+ return result;
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
new file mode 100644
index 0000000..fcf28ac
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
@@ -0,0 +1,155 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class MultiMap<K,V> extends HashMap<K,List<V>> {
+ private static final long serialVersionUID = 1L;
+ final boolean noduplicates;
+ final Class<?> keyClass;
+ final Class<?> valueClass;
+
+ final Set<V> EMPTY = Collections.emptySet();
+
+ public MultiMap() {
+ noduplicates = false;
+ keyClass = Object.class;
+ valueClass = Object.class;
+ }
+
+ public MultiMap(Class<K> keyClass, Class<V> valueClass, boolean noduplicates ) {
+ this.noduplicates = noduplicates;
+ this.keyClass = keyClass;
+ this.valueClass = valueClass;
+ }
+
+ @SuppressWarnings("unchecked") public boolean add( K key, V value ) {
+ assert keyClass.isInstance(key);
+ assert valueClass.isInstance(value);
+
+ List<V> set = get(key);
+ if ( set == null) {
+ set=new ArrayList<V>();
+ if ( valueClass != Object.class) {
+ set = Collections.checkedList(set, (Class<V>)valueClass);
+ }
+ put(key,set);
+ }else {
+ if (noduplicates) {
+ if ( set.contains(value))
+ return false;
+ }
+ }
+ return set.add(value);
+ }
+
+ @SuppressWarnings("unchecked") public boolean addAll( K key, Collection<? extends V> value ) {
+ assert keyClass.isInstance(key);
+ List<V> set = get(key);
+ if ( set == null) {
+ set=new ArrayList<V>();
+ if ( valueClass != Object.class) {
+ set = Collections.checkedList(set, (Class<V>)valueClass);
+ }
+ put(key,set);
+ } else
+ if ( noduplicates) {
+ boolean r=false;
+ for ( V v : value) {
+ assert valueClass.isInstance(v);
+ if ( !set.contains(value))
+ r|=set.add(v);
+ }
+ return r;
+ }
+ return set.addAll(value);
+ }
+
+ public boolean remove( K key, V value ) {
+ assert keyClass.isInstance(key);
+ assert valueClass.isInstance(value);
+
+ List<V> set = get(key);
+ if ( set == null) {
+ return false;
+ }
+ boolean result = set.remove(value);
+ if ( set.isEmpty())
+ remove(key);
+ return result;
+ }
+
+ public boolean removeAll( K key, Collection<V> value ) {
+ assert keyClass.isInstance(key);
+ List<V> set = get(key);
+ if ( set == null) {
+ return false;
+ }
+ boolean result = set.removeAll(value);
+ if ( set.isEmpty())
+ remove(key);
+ return result;
+ }
+
+ public Iterator<V> iterate(K key) {
+ assert keyClass.isInstance(key);
+ List<V> set = get(key);
+ if ( set == null)
+ return EMPTY.iterator();
+ return set.iterator();
+ }
+
+ public Iterator<V> all() {
+ return new Iterator<V>() {
+ Iterator<List<V>> master = values().iterator();
+ Iterator<V> current = null;
+
+ public boolean hasNext() {
+ if ( current == null || !current.hasNext()) {
+ if ( master.hasNext()) {
+ current = master.next().iterator();
+ return current.hasNext();
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public V next() {
+ return current.next();
+ }
+
+ public void remove() {
+ current.remove();
+ }
+
+ };
+ }
+
+ public Map<K,V> flatten() {
+ Map<K,V> map = new LinkedHashMap<K,V>();
+ for ( Map.Entry<K, List<V>> entry : entrySet()) {
+ List<V> v = entry.getValue();
+ if ( v == null || v.isEmpty())
+ continue;
+
+ map.put(entry.getKey(), v.get(0));
+ }
+ return map;
+ }
+
+ public MultiMap<V,K> transpose() {
+ MultiMap<V,K> inverted = new MultiMap<V,K>();
+ for ( Map.Entry<K, List<V>> entry : entrySet()) {
+ K key = entry.getKey();
+
+ List<V> value = entry.getValue();
+ if ( value == null)
+ continue;
+
+ for ( V v : value)
+ inverted.add(v, key);
+ }
+
+ return inverted;
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java b/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java
new file mode 100644
index 0000000..220d875
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java
@@ -0,0 +1,423 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+/**
+ * An immutbale list that sorts objects by their natural order or through a
+ * comparator. It has convenient methods/constructors to create it from
+ * collections and iterators.
+ *
+ * Why not maintain the lists in their sorted form? Well, TreeMaps are quite
+ * expensive ... I once profiled bnd and was shocked how much memory the Jar
+ * class took due to the TreeMaps. I could not easily change it unfortunately.
+ * The other reason is that Parameters uses a LinkedHashMap because the
+ * preferred order should be the declaration order. However, sometimes you need
+ * to sort the keys by name.
+ *
+ * Last, and most important reason, is that sometimes you do not know what
+ * collection you have or it is not available in a sort ordering (MultiMap for
+ * example) ... I found myself sorting these things over and over again and
+ * decided to just make an immutable SortedList that is easy to slice and dice
+ *
+ * @param <T>
+ */
+@SuppressWarnings("unchecked") public class SortedList<T> implements SortedSet<T>, List<T> {
+ static SortedList<?> empty = new SortedList<Object>();
+
+ final T[] list;
+ final int start;
+ final int end;
+ final Comparator<T> cmp;
+ Class<?> type;
+ static Comparator<Object> comparator = //
+
+ new Comparator<Object>() {
+ public int compare(Object o1, Object o2) {
+
+ if (o1 == o2)
+ return 0;
+
+ if (o1.equals(o2))
+ return 0;
+
+ return ((Comparable<Object>) o1).compareTo(o2);
+ }
+ };
+
+ class It implements ListIterator<T> {
+ int n;
+
+ private It(int n) {
+ this.n = n;
+ }
+
+ public boolean hasNext() {
+ return n < end;
+ }
+
+ public T next() throws NoSuchElementException {
+ if (!hasNext()) {
+ throw new NoSuchElementException("");
+ }
+ return list[n++];
+ }
+
+ public boolean hasPrevious() {
+ return n > start;
+ }
+
+ public T previous() {
+ return get(n - 1);
+ }
+
+ public int nextIndex() {
+ return (n + 1 - start);
+ }
+
+ public int previousIndex() {
+ return (n - 1) - start;
+ }
+
+ @Deprecated public void remove() {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ @Deprecated public void set(T e) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ @Deprecated public void add(T e) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+ }
+
+ public SortedList(Collection<? extends Comparable<?>> x) {
+ this((Collection<T>) x, 0, x.size(), (Comparator<T>) comparator);
+ }
+
+ public SortedList(Collection<T> x, Comparator<T> cmp) {
+ this(x, 0, x.size(), cmp);
+ }
+
+ @SuppressWarnings("cast")
+ public SortedList(T... x) {
+ this((T[]) x.clone(), 0, x.length, (Comparator<T>) comparator);
+ }
+
+ @SuppressWarnings("cast")
+ public SortedList(Comparator<T> cmp, T... x) {
+ this((T[]) x.clone(), 0, x.length, cmp);
+ }
+
+ private SortedList(SortedList<T> other, int start, int end) {
+ this.list = other.list;
+ this.cmp = other.cmp;
+ this.start = start;
+ this.end = end;
+ }
+
+ public SortedList(T[] x, int start, int end, Comparator<T> comparator2) {
+ if (start > end) {
+ int tmp = start;
+ start = end;
+ end = tmp;
+ }
+ if (start < 0 || start >= x.length)
+ throw new IllegalArgumentException("Start is not in list");
+
+ if (end < 0 || end > x.length)
+ throw new IllegalArgumentException("End is not in list");
+
+ this.list = x.clone();
+ Arrays.sort(this.list, start, end, comparator2);
+ this.start = start;
+ this.end = end;
+ this.cmp = comparator2;
+ }
+
+ public SortedList(Collection<? extends T> x, int start, int end, Comparator<T> cmp) {
+ if (start > end) {
+ int tmp = start;
+ start = end;
+ end = tmp;
+ }
+ if (start < 0 || start > x.size())
+ throw new IllegalArgumentException("Start is not in list");
+
+ if (end < 0 || end > x.size())
+ throw new IllegalArgumentException("End is not in list");
+
+ this.list = (T[]) x.toArray();
+ Arrays.sort(this.list, start, end, cmp);
+ this.start = start;
+ this.end = end;
+ this.cmp = cmp;
+ }
+
+ private SortedList() {
+ list = null;
+ start = 0;
+ end = 0;
+ cmp = null;
+ }
+
+ public int size() {
+ return end - start;
+ }
+
+ public boolean isEmpty() {
+ return start == end;
+ }
+
+ @SuppressWarnings("cast")
+ public boolean contains(Object o) {
+ assert type != null & type.isInstance(o);
+ return indexOf((T) o) >= 0;
+ }
+
+ public Iterator<T> iterator() {
+ return new It(start);
+ }
+
+ public Object[] toArray() {
+ return list.clone();
+ }
+
+ @SuppressWarnings("hiding") public <T> T[] toArray(T[] a) {
+ if (a == null || a.length < list.length) {
+ return (T[]) list.clone();
+ }
+ System.arraycopy(list, 0, a, 0, list.length);
+ return a;
+ }
+
+ public boolean add(T e) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ if (c.isEmpty())
+ return true;
+
+ if (isEmpty())
+ return false;
+
+ // TODO take advantage of sorted nature for this
+
+ for (Object el : c) {
+ if (!contains(el))
+ return false;
+ }
+ return false;
+ }
+
+ public boolean addAll(Collection<? extends T> c) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public boolean retainAll(Collection<?> c) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public boolean removeAll(Collection<?> c) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public Comparator<? super T> comparator() {
+ return cmp;
+ }
+
+ public boolean isSubSet() {
+ return start > 0 && end < list.length;
+ }
+
+ public SortedList<T> subSet(T fromElement, T toElement) {
+ int start = indexOf(fromElement);
+ int end = indexOf(toElement);
+ if (isSubSet() && (start < 0 || end < 0))
+ throw new IllegalArgumentException("This list is a subset");
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end = list.length;
+
+ return subList(start, end);
+ }
+
+ public int indexOf(Object o) {
+ assert type != null && type.isInstance(o);
+
+ int n = Arrays.binarySearch(list, (T) o, cmp);
+ if (n >= start && n < end)
+ return n - start;
+
+ return -1;
+ }
+
+ public SortedList<T> headSet(T toElement) {
+ int i = indexOf(toElement);
+ if (i < 0) {
+ if (isSubSet())
+ throw new IllegalArgumentException("This list is a subset");
+ i = end;
+ }
+
+ if (i == end)
+ return this;
+
+ return subList(0, i);
+ }
+
+ public SortedSet<T> tailSet(T fromElement) {
+ int i = indexOf(fromElement);
+ if (i < 0) {
+ if (isSubSet())
+ throw new IllegalArgumentException("This list is a subset");
+ i = start;
+ }
+
+ return subList(i, end);
+ }
+
+ public T first() {
+ if (isEmpty())
+ throw new NoSuchElementException("first");
+ return get(0);
+ }
+
+ public T last() {
+ if (isEmpty())
+ throw new NoSuchElementException("last");
+ return get(end - 1);
+ }
+
+ @Deprecated public boolean addAll(int index, Collection<? extends T> c) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public T get(int index) {
+ return list[index + start];
+ }
+
+ @Deprecated public T set(int index, T element) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ @Deprecated public void add(int index, T element) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ @Deprecated public T remove(int index) {
+ throw new UnsupportedOperationException("Immutable");
+ }
+
+ public int lastIndexOf(Object o) {
+ int n = indexOf(o);
+ if (n < 0)
+ return -1;
+
+ while (cmp.compare(list[n], (T) o) == 0)
+ n++;
+
+ return n;
+ }
+
+ public ListIterator<T> listIterator() {
+ return new It(start);
+ }
+
+ public ListIterator<T> listIterator(int index) {
+ return new It(index + start);
+ }
+
+ public SortedList<T> subList(int fromIndex, int toIndex) {
+ fromIndex += start;
+ toIndex += start;
+
+ if (toIndex < fromIndex) {
+ int tmp = toIndex;
+ toIndex = fromIndex;
+ fromIndex = tmp;
+ }
+
+ toIndex = Math.max(0, toIndex);
+ toIndex = Math.min(toIndex, end);
+ fromIndex = Math.max(0, fromIndex);
+ fromIndex = Math.min(fromIndex, end);
+ if (fromIndex == start && toIndex == end)
+ return this;
+
+ return new SortedList<T>(this, fromIndex, toIndex);
+ }
+
+ @Deprecated public boolean equals(Object other) {
+ return super.equals(other);
+ }
+
+ @Deprecated public int hashCode() {
+ return super.hashCode();
+ }
+
+ public boolean isEqual(SortedList<T> list) {
+ if (size() != list.size())
+ return false;
+
+ for (int as = start, bs = list.start, al = size(); as < al && bs < al; as++, bs++) {
+ if (comparator.compare(this.list[as], this.list[bs]) != 0)
+ return false;
+ }
+ return true;
+ }
+
+ public Class<?> getType() {
+ return type;
+ }
+
+ public void setType(Class<?> type) {
+ this.type = type;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+ String del = "";
+ for (T s : list) {
+ sb.append(del);
+ sb.append(s);
+ del = ", ";
+ }
+
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public boolean hasDuplicates() {
+ if (list.length < 2)
+ return false;
+
+ T prev = list[0];
+ for (int i = 1; i < list.length; i++) {
+ if (prev.equals(list[i]))
+ return true;
+ }
+ return false;
+ }
+
+ public static <T extends Comparable<?>> SortedList<T> fromIterator(Iterator<T> it) {
+ IteratorList<T> l = new IteratorList<T>(it);
+ return new SortedList<T>(l);
+ }
+
+ public static <T> SortedList<T> fromIterator(Iterator<T> it, Comparator<T> cmp) {
+ IteratorList<T> l = new IteratorList<T>(it);
+ return new SortedList<T>(l, cmp);
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/packageinfo b/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
@@ -0,0 +1 @@
+version 1.1