Thursday, August 26, 2010

More uses for Iterables

Iterable is one of my favorite interfaces in Java. I love the for-each construct:

for (final Type item : iterableOfItems)
    doSomethingWith(item);

Notice what cannot go wrong:

  1. I cannot run off the end, or forget to go far enough (no off-by-one bugs)
  2. I cannot forget to call hasNext() before calling next() (iterator misuse)
  3. I cannot make the wrong cast or pick the wrong container type

I could go on. It is also concise and conveys programmer intention clearly, both wonderful virtues.

How can I make more use of Iterable?

Here is an example of transforming input into Iterable. First the base class:

public abstract class ResourceIterable<T, R extends Closeable>
        implements Closeable, Iterable<T> {
    private final R resource;

    private volatile boolean closed;

    protected ResourceIterable(final R resource) {
        this.resource = resource;
    }

    protected final R resource() {
        return resource;
    }

    protected abstract T getNext()
            throws IOException;

    @Override
    public final void close()
            throws IOException {
        closed = true;
        resource.close();
    }

    @Override
    public final Iterator<T> iterator() {
        return new Iterator<T>() {
            private T next;

            @Override
            public boolean hasNext() {
                try {
                    next = getNext();
                    return null != next;
                } catch (final EOFException ignored) {
                    next = null;
                    return false;
                } catch (final IOException e) {
                    next = null;
                    if (closed)
                        return false;
                    throw new UndeclaredThrowableException(e);
                }
            }

            @Override
            public T next() {
                if (null == next)
                    throw new NoSuchElementException();
                return next;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}

And a sample using class:

public class LineIterable
        extends ResourceIterable {
    public AmpsResponseIterable(final BufferedReader reader) {
        super(reader);
    }

    @Override
    protected String getNext()
            throws IOException {
        return resource().readLine();
    }
}

The example is trivial (my actual uses are hiding sophisticated readers of data structures from network connections) but clear:

for (final String line : new LineIterable(someBufferedReader))
    process(line);

However, all use of Iterable is similarly trivial: that's the point if it. The complexity is in extracting objects from the input (though not in this example).

I prefer hard-to-write-easy-to-use code when I make libraries; easy-to-write-hard-to-use just feels lazy (the wrong kind of lazy).

Guice moving to Maven

It's not new news, but it was new to me: Maven is switching to Guice to wire itself and plugins. From Sonatype:

  1. From Plexus to Guice (#1): Why Guice?
  2. From Plexus to Guice (#2): The Guice/Plexus Bridge and Custom Bean Injection
  3. From Plexus to Guice (#3): Creating a Guice Bean Extension Layer

The plugin framework is named spice inject and glancing through it's straight-forward glue between Guice and OSGi within a Maven object domain.

It looks very clean. Nice.

Tuesday, August 24, 2010

Large-scale refactoring

Vikas Hazrati has a nice post on large-scale refactoring on InfoQ. I'm a strangler. You?

Have tools, will code

Thanks to the benevolent JetBrains, I now have an OSS license for IntelliJ IDEA to develop an Android app. I first started using IDEA at ThoughtWorks where it quickly became my favorite development tool.

And thanks to Turbine, I have my data.lotro.com developer key! So I am ready to start an LOTRO Android App. And I've already been getting encouraging words from the LOTRO forums. Go, community!

Friday, August 13, 2010

Nexus out, Android in

My dreams of a Nexus One came to naught. But...

I now have an excellent Samsung Galaxy S with Android 2.1, and I asked JetBrains for an open-source license for their Android plugin to IntelliJ IDEA. I have plans brewing!