These are several additions that I feel might be useful to the Commons Lang
Project. Please feel free to provide feedback, and if there is enough
interest in any of them I will create JIRA entries, code them, and provide
patches.

Expand Validate to include more specific, human readable validation for
commonly validated paramter values (so isTrue() isn't needed as often).
Include new Validate methods:

   - isFile(File file)
   - throws an IllegalArgumentException stating "The file " + file + " is
      not a regular file" when the provided file is not a regular file
      (File.isFile()).
      - isFile(File file, String message)
      - throws an IllegalArgumentException stating (message + file) when the
      provided file is not a regular file (File.isFile()).
   - isDirectory(File directory)
      - throws an IllegalArgumentException stating "The file " + file + " is
      not a directory" when the provided file is not a directory
      (File.isDirectory()).
      - isDirectory(File directory, String message)
      - throws an IllegalArgumentException stating (message + file) when the
      provided file is not a directory (File.isDirectory()).
   - isReadable(File file)
      - throws an IllegalArgumentException stating "The file " + file + "
      cannot be read" when the provided file  is unreadable (File.canRead()).
   - isReadable(File file, String message)
      - throws an IllegalArgumentException stating (message + file) when the
      provided file  is unreadable (File.canRead()).
   - isWritable(File file)
      - throws an IllegalArgumentException stating "The file " + file + "
      cannot be written to" when the provided file  is unwritable
      (File.canWrite()).
   - isWritable(File file, String message)
      - throws an IllegalArgumentException stating (message + file) when the
      provided file  is unwritable (File.canWrite()).
   - fileExists(File file)
      - throws an IllegalArgumentException stating "The file " + file + "
      does not exist" when the provided file does not exist (File.exists()).
   - fileExists(File file, String message)
      - throws an IllegalArgumentException stating (message + file) when the
      provided file does not exist (File.exists()).
   - matchesPattern(String string, String pattern)
      - throws an IllegalArgumentException stating ("The string " + string +
      " does not match the pattern "  + pattern) when the provided
string does not
      match the regular expression pattern.
      - matchesPattern(String string, String pattern, String message)
      - throws an IllegalArgumentException stating (message + string) when
      the provided string does not match the regular expression pattern.
   - matchesPattern(String string, Pattern pattern)
      - throws an IllegalArgumentException stating ("The string " + string +
      " does not match the pattern "  + pattern) when the provided
string does not
      match the regular expression pattern.
   - matchesPattern(String string, Pattern pattern, String message)
      - throws an IllegalArgumentException stating (message + string) when
      the provided string does not match the regular expression pattern.
   - inRange(Comparable<T> start, Comparable<T> end, Comparable<T> value)
      - throws an IllegalArgumentException stating ("The value " + value + "
      is not in the specified range of " + start + " to " + end) when
the provided
      value does not fall between the two comparable values.
      - inRange(Comparable<T> start, Comparable<T> end, Comparable<T> value,
   String message)
      - throws an IllegalArgumentException stating (message + value) when
      the provided value does not fall between the two comparable values.
   - sizeInRange(int minSize, int maxSize, T[] array, String message)
      - throws an IllegalArgumentException stating (message + value) when
      the length of the provided array does not fall between the minimum and
      maximum size values (inclusive).
   - sizeInRange(int minSize, int maxSize, Collection<?> collection, String
   message)
      - throws an IllegalArgumentException stating (message + value) when
      the length of the provided collection does not fall between the
minimum and
      maximum size values (inclusive).
   - sizeInRange(int minSize, int maxSize, Map<?, ?> map, String message)
      - throws an IllegalArgumentException stating (message + value) when
      the length of the provided map does not fall between the minimum
and maximum
      size values (inclusive).
   - sizeInRange(int minSize, int maxSize, String string, String message)
      - throws an IllegalArgumentException stating (message + value) when
      the length of the provided string does not fall between the minimum and
      maximum size values (inclusive).


I would also like to propose some support be added to Lang for basic event
handling. This would be based on the way that PropertyChangeSupport can be
used to add and remove listeners and post events.

Add interface EventSupport<L extends EventListener>

   - addListener(L listener)
   - The signature for the method that can add a listener of some subtype of
      EventListener
      - removeListener(L listener)
   - The signature for the method that can remove a listener of some subtype
      of EventListener


Add class AbstractEventSupport implements EventSupport<L>, Iterable<L>

   - AbstractEventSupport(Object eventSource)
   - Constructs a new AbstractEventSupport object and associates it with the
      object that will be used as the source of all events (much like
      PropertyChangeSupport).
      - addListener(L)
   - An implementation that adds a listener to an internal collection.
      - removeListener(L)
   - An implementation that removes a listener from an internal collection.
      - iterator()
   - Returns an iterator over the attached listeners.
      - getSource()
   - Returns a reference to the source object of all events.


The best way to describe this would be to demonstrate an example of how it
can be used.

public class ButtonPressedEventSupport extends
AbstractEventSupport<ButtonPressedListener> {

    public ButtonPressedEventSupport(Object source) { super(source); }

    public void fireButtonPressed(Button button) {
        ButtonPressedEvent bpe = new ButtonPressedEvent(getSource(),
button);
        for (ButtonPressedListener listener : this)
        {
            listener.buttonPressed(bpe);
        }
    }
}

public class MyWindow implements EventSupport<ButtonPressedListener> {
     private final ButtonPressedEventSupport buttonPressedEventSupport;

     public MyWindow { buttonPressedEventSupport = new
ButtonPressedEventSupport(this); }

     public void addListener(ButtonPressedListener listener) {
buttonPressedEventSupport.addListener(listener); }

     public void removeListener(ButtonPressedListener listener) {
buttonPressedEventSupport.removeListener(listener); }

     ...

    private void onDetectButtonPressed(Button button) {
        buttonPressedEventSupport.fireButtonPressed(button);
    }
}

I haven't compiled the above code. It's just an example of how these classes
could be used so that you're not constantly rewriting the code and
interfaces for adding and removing listeners, and it provides a fairly easy
method of creating methods to fire events.

So, anyone have thoughts or opinions on these proposed features?

-Michael Wooten

Reply via email to