Uploaded image for project: 'Commons Collections'
  1. Commons Collections
  2. COLLECTIONS-476

Collection wrappers to for unmodifiable / nonnull-safe collections

    XMLWordPrintableJSON

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Minor
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: List, Set
    • Labels:
      None

      Description

      Would it be possible to add something like this to commons lang? Commons collection looks like it's pretty much dead, and the only alternative for this kind of stuff is Google's horribly designed and massively confusing Guava library.

      Below are a couple of quick and dirty (untested) examples of the kind of wrappers I'm talking about. Note the isLocked/locked methods and the viewBlacklist method. Using these methods, it's easy for a component receiving a list/set to identify that it's currently unmodifiable and that the collection restricts certain values (e.g. null? maybe others?).

      public final class LockableBlacklistableList<T> implements List<T> {
      
          private boolean locked;
          private List<T> list;
          private Set<T> blacklist;
      
          public LockableBlacklistableList(List<T> backingList, T... blacklist) {
              if (backingList == null) {
                  throw new NullPointerException();
              }
      
              if (!backingList.isEmpty()) {
                  throw new IllegalArgumentException();
              }
              this.blacklist = new HashSet<>(Arrays.asList(blacklist));
              this.list = backingList;
          }
      
          public void lock() {
              locked = true;
          }
      
          public boolean isLocked() {
              return locked;
          }
      
          public Set<T> viewBlacklist() {
              return Collections.unmodifiableSet(blacklist);
          }
      
          @Override
          public int size() {
              return list.size();
          }
      
          @Override
          public boolean isEmpty() {
              return list.isEmpty();
          }
      
          @Override
          public boolean contains(Object o) {
              return list.contains(o);
          }
      
          @Override
          public Iterator<T> iterator() {
              final Iterator<T> it = list.iterator();
              return new Iterator<T>() {
                  @Override
                  public boolean hasNext() {
                      return it.hasNext();
                  }
      
                  @Override
                  public T next() {
                      return it.next();
                  }
      
                  @Override
                  public void remove() {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      it.remove();
                  }
              };
          }
      
          @Override
          public Object[] toArray() {
              return list.toArray();
          }
      
          @Override
          public <T> T[] toArray(T[] a) {
              return list.toArray(a);
          }
      
          @Override
          public boolean add(T e) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return list.add(e);
          }
      
          @Override
          public boolean remove(Object o) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return list.remove(o);
          }
      
          @Override
          public boolean containsAll(Collection<?> c) {
              return list.containsAll(c);
          }
      
          @Override
          public boolean addAll(Collection<? extends T> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              for (T item : c) {
                  if (blacklist.contains(item)) {
                      throw new IllegalArgumentException();
                  }
              }
              return list.addAll(c);
          }
      
          @Override
          public boolean addAll(int index, Collection<? extends T> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              for (T item : c) {
                  if (blacklist.contains(item)) {
                      throw new IllegalArgumentException();
                  }
              }
              return list.addAll(index, c);
          }
      
          @Override
          public boolean removeAll(Collection<?> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return list.removeAll(c);
          }
      
          @Override
          public boolean retainAll(Collection<?> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return list.retainAll(c);
          }
      
          @Override
          public void clear() {
              if (locked) {
                  throw new IllegalStateException();
              }
              list.clear();
          }
      
          @Override
          public boolean equals(Object o) {
              return list.equals(o);
          }
      
          @Override
          public int hashCode() {
              return list.hashCode();
          }
      
          @Override
          public T get(int index) {
              return list.get(index);
          }
      
          @Override
          public T set(int index, T element) {
              if (locked) {
                  throw new IllegalStateException();
              }
              if (blacklist.contains(element)) {
                  throw new IllegalArgumentException();
              }
              return list.set(index, element);
          }
      
          @Override
          public void add(int index, T element) {
              if (locked) {
                  throw new IllegalStateException();
              }
              if (blacklist.contains(element)) {
                  throw new IllegalArgumentException();
              }
              list.add(index, element);
          }
      
          @Override
          public T remove(int index) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return list.remove(index);
          }
      
          @Override
          public int indexOf(Object o) {
              return list.indexOf(o);
          }
      
          @Override
          public int lastIndexOf(Object o) {
              return list.lastIndexOf(o);
          }
      
          @Override
          public ListIterator<T> listIterator() {
              final ListIterator<T> backingListIt = list.listIterator();
              return new ListIterator<T>() {
                  @Override
                  public boolean hasNext() {
                      return backingListIt.hasNext();
                  }
      
                  @Override
                  public T next() {
                      return backingListIt.next();
                  }
      
                  @Override
                  public boolean hasPrevious() {
                      return backingListIt.hasPrevious();
                  }
      
                  @Override
                  public T previous() {
                      return backingListIt.previous();
                  }
      
                  @Override
                  public int nextIndex() {
                      return backingListIt.nextIndex();
                  }
      
                  @Override
                  public int previousIndex() {
                      return backingListIt.previousIndex();
                  }
      
                  @Override
                  public void remove() {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      backingListIt.remove();
                  }
      
                  @Override
                  public void set(T e) {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      if (blacklist.contains(e)) {
                          throw new IllegalArgumentException();
                      }
                      backingListIt.set(e);
                  }
      
                  @Override
                  public void add(T e) {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      if (blacklist.contains(e)) {
                          throw new IllegalArgumentException();
                      }
                      backingListIt.add(e);
                  }
              };
          }
      
          @Override
          public ListIterator<T> listIterator(int index) {
              final ListIterator<T> backingListIt = list.listIterator(index);
              return new ListIterator<T>() {
                  @Override
                  public boolean hasNext() {
                      return backingListIt.hasNext();
                  }
      
                  @Override
                  public T next() {
                      return backingListIt.next();
                  }
      
                  @Override
                  public boolean hasPrevious() {
                      return backingListIt.hasPrevious();
                  }
      
                  @Override
                  public T previous() {
                      return backingListIt.previous();
                  }
      
                  @Override
                  public int nextIndex() {
                      return backingListIt.nextIndex();
                  }
      
                  @Override
                  public int previousIndex() {
                      return backingListIt.previousIndex();
                  }
      
                  @Override
                  public void remove() {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      backingListIt.remove();
                  }
      
                  @Override
                  public void set(T e) {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      if (blacklist.contains(e)) {
                          throw new IllegalArgumentException();
                      }
                      backingListIt.set(e);
                  }
      
                  @Override
                  public void add(T e) {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      if (blacklist.contains(e)) {
                          throw new IllegalArgumentException();
                      }
                      backingListIt.add(e);
                  }
              };
          }
      
          @Override
          public List<T> subList(int fromIndex, int toIndex) {
              LockableBlacklistableList<T> ret = new LockableBlacklistableList<>(
                      list.subList(fromIndex, toIndex));
              ret.locked = locked;
              ret.blacklist = blacklist;
              return ret;
          }
      }
      
      public final class LockableBlacklistableSet<T> implements Set<T> {
          private boolean locked;
          private Set<T> set;
          private Set<T> blacklist;
      
          public LockableBlacklistableSet(Set<T> backingSet, T... blacklist) {
              if (backingSet == null) {
                  throw new NullPointerException();
              }
      
              if (!backingSet.isEmpty()) {
                  throw new IllegalArgumentException();
              }
              this.blacklist = new HashSet<>(Arrays.asList(blacklist));
              this.set = backingSet;
          }
          
          public void lock() {
              locked = true;
          }
      
          public boolean isLocked() {
              return locked;
          }
      
          public Set<T> viewBlacklist() {
              return Collections.unmodifiableSet(blacklist);
          }
      
          public int size() {
              return set.size();
          }
      
          public boolean isEmpty() {
              return set.isEmpty();
          }
      
          public boolean contains(Object o) {
              return set.contains(o);
          }
      
          public Iterator<T> iterator() {
              final Iterator<T> it = set.iterator();
              return new Iterator<T>() {
                  @Override
                  public boolean hasNext() {
                      return it.hasNext();
                  }
      
                  @Override
                  public T next() {
                      return it.next();
                  }
      
                  @Override
                  public void remove() {
                      if (locked) {
                          throw new IllegalStateException();
                      }
                      it.remove();
                  }
              };
          }
      
          public Object[] toArray() {
              return set.toArray();
          }
      
          public <T> T[] toArray(T[] a) {
              return set.toArray(a);
          }
      
          public boolean add(T e) {
              if (locked) {
                  throw new IllegalStateException();
              }
              if (blacklist.contains(item)) {
                  throw new IllegalArgumentException();
              }
              return set.add(e);
          }
      
          public boolean remove(Object o) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return set.remove(o);
          }
      
          public boolean containsAll(Collection<?> c) {
              return set.containsAll(c);
          }
      
          public boolean addAll(Collection<? extends T> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              for (T item : c) {
                  if (blacklist.contains(item)) {
                      throw new IllegalArgumentException();
                  }
              }
              return set.addAll(c);
          }
      
          public boolean retainAll(Collection<?> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return set.retainAll(c);
          }
      
          public boolean removeAll(Collection<?> c) {
              if (locked) {
                  throw new IllegalStateException();
              }
              return set.removeAll(c);
          }
      
          public void clear() {
              if (locked) {
                  throw new IllegalStateException();
              }
              set.clear();
          }
      
          public boolean equals(Object o) {
              return set.equals(o);
          }
      
          public int hashCode() {
              return set.hashCode();
          }
      }
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              offbynull offbynull
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: