+ /*
+ * COLLECTIONS
+ */
+ /**
+ * Convert a comma-separated separated {@link String} or a {@link String} array
+ * to a {@link List} of {@link String}, trimming them. Useful to quickly
+ * interpret OSGi services properties.
+ *
+ * @return a {@link List} containing the trimmed {@link String}s, or an empty
+ * {@link List} if the argument was <code>null</code>.
+ */
+ public static List<String> toStringList(Object value) {
+ List<String> values = new ArrayList<>();
+ if (value == null)
+ return values;
+ String[] arr;
+ if (value instanceof String) {
+ arr = ((String) value).split(",");
+ } else if (value instanceof String[]) {
+ arr = (String[]) value;
+ } else {
+ throw new IllegalArgumentException("Unsupported value type " + value.getClass());
+ }
+ for (String str : arr) {
+ values.add(str.trim());
+ }
+ return values;
+ }
+
+ /** Size of an {@link Iterable}, optimised if it is a {@link Collection}. */
+ public static int size(Iterable<?> iterable) {
+ if (iterable instanceof Collection)
+ return ((Collection<?>) iterable).size();
+
+ int size = 0;
+ for (Iterator<?> it = iterable.iterator(); it.hasNext(); size++)
+ it.next();
+ return size;
+ }
+
+ public static <T> T getAt(Iterable<T> iterable, int index) {
+ if (iterable instanceof List) {
+ List<T> lst = ((List<T>) iterable);
+ if (index >= lst.size())
+ throw new IllegalArgumentException("Index " + index + " is not available (size is " + lst.size() + ")");
+ return lst.get(index);
+ }
+ int i = 0;
+ for (Iterator<T> it = iterable.iterator(); it.hasNext(); i++) {
+ if (i == index)
+ return it.next();
+ else
+ it.next();
+ }
+ throw new IllegalArgumentException("Index " + index + " is not available (size is " + i + ")");
+ }
+