Tuesday, August 21, 2007

Cygwin BASH wrapper for Maven deploy:deploy-file

I frequently use Maven's deploy:deploy-file mojo for building project-local repositories.

Many interesting 3rd-party Java libraries are not (yet) available from public Maven repositories (the otherwise excellent dev.java.net projects are particularly weak in this respect), but I want to use them in my project POM. What to do?

I store them with my project. This is not an ideal solution, but it is practical.

To help me deploying jars, sources and javadocs I wrote a simple BASH wrapper script for Cygwin (to run under Linux/UNIX requires a trivial change). Here is typical use:

$ mvn-file-deploy ~/IdeaProjects/Scratch/lib cool-library-1.0.4.jar org.cool.library:cool-library:1.0.4
$ mvn-file-deploy -S ~/IdeaProjects/Scratch/lib cool-library-1.0.4-sources.jar org.cool.library:cool-library:1.0.4
$ mvn-file-deploy -J ~/IdeaProjects/Scratch/lib cool-library-1.0.4-javadocs.jar org.cool.library:cool-library:1.0.4

And the script itself:

#!/bin/bash

function help()
{
    cat <<'EOH' | fmt
Usage: mvn-file-deploy [options] REPO_PATH FILE_PATH DESCRIPTOR [CLASSIFIER]

Use mvn-file-deploy as a helper for 'mvn deploy:deploy-file' when using Cygwin.

EOH
    cat <<'EOH'
Options:
  -h, --help          Print this help message
      --version       Print program version
  -S, --sources       Deploy sources
  -J, --javadocs      Deploy javadocs
  -q, --quiet         Do not print maven command
EOH
    cat <<'EOH' | fmt

Other options are passed to Maven.  (BROKEN)

Examples:

The most common use is to run it like this:

    $ mvn-file-deploy C:/my/project/lib C:/some/interesting.jar groupId:artifactId:version

Or if you use a classifier (e.g., jdk5):

But sometimes like this.

    $ mvn-file-deploy C:/my/project/lib C:/some/interesting.jar groupId:artifactId:version classifier

Report bugs to <binkley@alumni.rice.edu>.
EOH
}

function version()
{
    cat <<'EOV' | fmt
mvn-file-deploy 1.0
Copyright (C) 2007 JPMorganChase, Inc.  All rights reserved.
EOV
}

function fatal()
{
    echo "$0: $*" >&2
    exit 2
}

function usage() 
{
    cat <<'EOU' | fmt >&2
usage: mvn-file-deploy [options] REPO_PATH FILE_PATH DESCRIPTOR [CLASSIFIER]
EOU
}

eval set -- "$(getopt -o hJSq --long help,javadocs,sources,quiet,version -n "$0" -- "$@")"

declare -a maven_opts
declare -a args

for opt
do
    shift
    case "$opt" in
        -h|--help ) help ; exit 0 ;;
        -J|--javadocs ) classifier=-Dclassifier=javadocs ;;
        -S|--sources ) classifier=-Dclassifier=sources ;;
        --version ) version ; exit 0 ;;
        -q|--quiet ) quiet=t ; maven_opts=("${maven_opts[@]}" "$opt") ;;
        -- ) break ;;
        -* ) maven_opts=("${maven_opts[@]}" "$opt") ;;
    esac
done

case $# in
    3 ) repo_path="$1"
        file_path="$2"
        descriptor="$3" ;;
    4 ) repo_path="$1"
        file_path="$2"
        descriptor="$3"
        classifier=-Dclassifier="$4" ;;
    * ) usage ; exit 2 ;;
esac

(cd "$repo_path" 2>/dev/null) || \
    fatal "No such repository path: $repo_path"

repo_url="file://$(cygpath -am "$repo_path")"
file_path="$(cygpath -am "$file_path")"

[[ -r "$file_path" ]] || \
    fatal "No such artifact: $file_path"

triplet=($(echo $descriptor | tr : ' '))

(( 3 == ${#triplet[*]} )) || \
    fatal "Descriptor not groupId:artifactId:version format: $descriptor"

packaging=-Dpackaging="${file_path##*.}"

[[ -n "$quiet" ]] ||
    echo mvn "${maven_opts[@]}" deploy:deploy-file -Durl="$repo_url" \
        -DrepositoryId=project -Dfile="$file_path" -DgroupId=${triplet[0]} \
        -DartifactId=${triplet[1]} -Dversion=${triplet[2]} \
        $packaging $classifier
exec mvn "${maven_opts[@]}" deploy:deploy-file -Durl="$repo_url" \
    -DrepositoryId=project -Dfile="$file_path" -DgroupId=${triplet[0]} \
    -DartifactId=${triplet[1]} -Dversion=${triplet[2]} \
    $packaging $classifier

Sunday, August 19, 2007

Recursive "toString"

Sometimes for debugging I want to dump an object recursively. That is, I'd like to see not just an Apache Commons Lang-style toString, but a recursive version which descends fields to display their inner bits as well.

Rather than complain, I coded my own. Enjoy!

public static String recursiveToString(final Object o) {
    final StringBuilder buffer = new StringBuilder();

    recursiveToString(new StringBuilder(), o, buffer,
            new HashSet<Object>());

    return buffer.toString();
}

private static void recursiveToString(final StringBuilder prefix,
        final Object o, final StringBuilder buffer,
        final Set<Object> seen) {
    if (null == o) {
        buffer.append("null\n");
        return;
    }

    // Mark back references with angle brackets
    if (seen.contains(o)) {
        buffer.append('<');
        objectToString(o, buffer);
        buffer.append(">\n");
        return;
    }

    seen.add(o);

    objectToString(o, buffer);

    // TODO: More clever to see if protection domain is in the JDK
    if (shouldNotRecurse(o, o.getClass().getPackage().getName())) {
        buffer.append('=');
        buffer.append(o);
        buffer.append('\n');
        return;
    }

    buffer.append("={");
    buffer.append('\n');

    final StringBuilder fieldPrefix = new StringBuilder(prefix);
    fieldPrefix.append("  ");

    for (final Field field : o.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        buffer.append(fieldPrefix);
        buffer.append(field.getName());
        buffer.append('(');
        buffer.append(Modifier.toString(field.getModifiers()));
        buffer.append(")=");

        try {
            recursiveToString(fieldPrefix, field.get(o), buffer, seen);
        } catch (final IllegalAccessException e) {
            buffer.append("? (");
            buffer.append(e.getMessage());
            buffer.append(')');
        }
    }

    buffer.append(prefix);
    buffer.append("}\n");
}

private static boolean shouldNotRecurse(final Object o,
        final String packageName) {
    try {
        return (packageName.startsWith("java.") || packageName
                .startsWith("javax.")) && !Object.class
                .getMethod("toString")
                .equals(o.getClass().getMethod("toString"));
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    }
}

private static void objectToString(final Object o,
        final StringBuilder buffer) {
    buffer.append(o.getClass().getName());
    buffer.append('@');
    buffer.append(Integer.toHexString(System.identityHashCode(o)));
}

Luboš Motl answers some physics questions

Wow! I miss physics sometimes.

Wednesday, July 25, 2007

Monday, July 09, 2007

More with Java enums: simulating inheritance

One drawback to the Java enum is the lack of inheritance. Java uses inheritance for many reasons, one of which is implementation inheritance. (In C++ you would use private inheritance for the same reason.)

To recapture implementation inheritance with enums, use the visitor pattern:

class Convert {
    public interface Vivid {
        char character();
    }

    public static <E extends Enum<E> & Vivid> E from(
            E[] values, char character) {
        for (E e : values)
            if (e.character() == character)
                return e;

        throw new IllegalArgumentException("Boring: " + character);
    }
}

enum Men implements Convert.Vivid {
    OLIVIER('L'), WAYNE('J');

    private final char character;

    Men(char character) {
        this.character = character;
    }

    public char character() {
        return character;
    }

    public static Men valueOf(char character) {
        return Convert.from(values(), character);
    }
}

The implementation of valueOf(char):Men is handled in Convert and can be reused in other enum classes.

Thursday, June 14, 2007

Download web pages in BASH

BASH is quite amazing. From Bhaskar V. Karambelkar comes Bash shell tricks and this gem (with some small corrections):

function headers()
{
    server=$1
    port=${2:-80}
    exec 5<>/dev/tcp/$server/$port
    echo -ne "HEAD / HTTP/1.0\r\nHost: $server:$port\r\n\r\n" >&5
    cat <&5
    exec 5<&-;
}

I work behind a corporate firewall, so I need web proxy settings. No problem, BASH is still amazing:

function webget()
{
    declare -a parts
    parts=($(echo $1 | tr / ' '))
    protocol=${parts[0]}
    server=${parts[1]}
    path=$(echo $1 | sed "s,$protocol//$server,,")

    exec 5<>/dev/tcp/$http_proxy_server/$http_proxy_port
    echo -ne "GET $path HTTP/1.0\r\nHost: $server\r\n\r\n" >&5
    cat <&5
    exec 5<&-;
}

Usage is obvious:

$ webget http://www.ccil.org/jargon/
# Out pops the top page for Jargon File Resources

UPDATE: Also useful for talking to SMTP (email) servers:

$ exec 5<>/dev/tcp/localhost/smtp
$ read -u 5 line
$ echo $line
220 my.full.host.name ESMTP ...
$ echo QUIT >&5
$ read -u 5 line
$ echo $line
221 2.0.0 my.full.host.name closing connection

This also shows that BASH knows to map the SMTP service to port 25.

Monday, June 11, 2007

Excellent advice on Java exceptions

Excellent advice on avoiding exception anti-patterns in Java from Tim McCune, Exception-Handling Antipatterns. Particularly noxious are the anti-patterns which swallow exceptions.

Quick trivial quiz.

  1. Does this code compile?
  2. If it compiles, what happens at runtime?
try {
    throw null;
} catch (final Throwable t) {
    System.out.println("t = " + t);
}

Before you chuckle too hard, recall that this is a perfectly valid C++ program, if contrived, and prints Something integral: 0:

#include <iostream>

int
main(const int argc, const char *argv[])
{
  try {
    throw 0;
  } catch (const int i) {
    std::cout << "Something integral: " << i << std::endl;
  } catch (...) {
    std::cout << "Something exceptional." << std::endl;
  }
}

UPDATE: I fixed the title.

Friday, June 08, 2007

Style, taste, sensibilities in coding

Chris Aston has an eminently sensible post on programming in the small (not his words[*]), Coding Against the Grain, on some coding style and taste points that have been part of my habits nearly as long as I have programmed.

He emphasizes balance and clarity and cautions against turning objects into stand-ins for global variables: the function is given its due.

To elaborate on his points, I often treat objects as small bundles of encapsulated state with public methods that tie private fields to private functions. A simple example illustrates:

class UsefulExample {
    private int count;

    public String repeatMessage(String message) {
        return repeatMessage(message, count);
    }

    static String repeatMessage(String message,
            int count) {
        StringBuilder builder = new StringBuilder(message);

        for (int i = 1; i < count; ++i)
            builder.append(' ').append(message);

        return builder.toString();
    }
}

This example is not very interseting, but it makes it easy to list benefits:

  • Testing the functions independent of the encapsulated state is easy.
  • Changing the algorithm of functions does not affect public methods.
  • If the functions are common across classes, refactoring them out to a common utility class is simple.
  • Design changes in the encapsulated state do not impact functions.

In effect, the I have decoupled encapsulated state within the object from implementation algorithms within the functions, and use public methods to connect them together.

This is carrying a common design pattern from "programming in the large" into "programming in the small", with the same advantages. The decoupling of state from algorithm is an old idea [PDF].

More on programming in the small

Ivan Moore has a delightful series of posts on Programming in the Small well worth reading.

The all-dancing, all-singing LockSmith plugin for IntelliJ

I've never been willing to pay for IntelliJ plugins, but LockSmith from the very clever Sixth & Red River may change my mind.

This is a list of features which made me look twice:

  • Split Lock
  • Merge Locks
  • Make Class Thread-Safe
  • Convert Field to Atomic
  • Convert Field to ThreadLocal
  • Lock Call-Sites of Method
  • Convert Simple Lock to Read-Write Lock
  • Convert Read-Write Lock to Simple Lock
  • Convert Synchronization Field to Lock
  • Split Critical Section
  • Shrink Critical Section
  • Merge Critical Sections

Fortunately, I work for an excellent employer, and may be able to wrangle a group bulk license for my team for LockSmith and other wonderful plugins.

Friday, May 04, 2007

Getting more from streams in Bash

A handy trick in Bash is to split a stream to process it in more than one way without saving a temporary copy:

# Make 3 a copy of 1 (stdout)
exec 3>&1
result="$(command to generate stream \
    | tee /dev/fd/3 \
    | command to process stream)"
# Now work with $result
# The original stream also went to the console

The actual case I worked with this morning was a very simple demonstration:

#!/bin/bash

exec 3>&1

echo -e "Bob is my friend.\nFred is my friend, too." \
    | tee /dev/fd/3 \
    | cut -f1 -d' ' >&2

Which simply prints:

Bob is my friend.
Fred is my friend.

to stdout and to stderr it prints:

Bob
Fred

That most excellent Erlang short

There is a short making the rounds, Erlang: The Movie. It is witty, indirect and informative. And subtly hilarious.

As programming language propaganda goes, this is highly effective: I really want to go out and try Erlang after watching. Nicely done.

Wednesday, May 02, 2007

Increasing log4j verbosity

To programmatically increase log4j verbosity, a simple code snippet does the trick:

final Logger rootLogger = Logger.getRootLogger();

rootLogger.setLevel(Level.toLevel(
        rootLogger.getLevel().toInt() + 1,
        Level.ALL));

I use this to handle the -verbose command-line switch. Repeating the switch keeps increasing my program's verbosity.

Naturally there are wrinkles with a complex log4j configuration, but the idiom remains.

Tuesday, May 01, 2007

Subversion best practices, branching

A useful link on Subversion, Subversion Best Practices. Really nice are the links into the Red Bean book filling out each point.

What I am looking for at the moment is a good discussion on using Subversion to fork a project. I have internal libraries at work which are not ameniable to multiple teams working on them. My best option is to fork the code and merge back in fixes from the original.

This looks like a good start on this kind of branching. I like the example shell scripts for automating portions of the process.

Thursday, April 12, 2007

Good temporary files in Ant

I was reading this nice post on unsigning jars with Ant when this line caught my eye:

<tempfile destdir="${java.io.tmpdir}"
          prefix="unsign-"
          property="temp.file"/>

I was struck by an Aha! moment—using ${java.io.tmpdir} is clearly the Right Thing for creating temporary files in Java. Why not also in Ant?

Wednesday, April 11, 2007

The fallacy of soft coding

Today's Worse Than Failure has a brilliant post on soft coding.

It begins with a strong exposition answering "what is soft coding?" — the example business method is just about ideal for what a business method should be. I wish I could hire him!

The moral is simple: don't be a soft coder; in some respects it is worse than hard coding.

Most used tool

What is the most used tool in my daily work life? The Java compiler? IntelliJ IDEA? Perl?

Actually it is Mark Edgar's PuTTYcyg, a PuTTY patch for Cygwin terminal. This runs BASH from Cygwin inside a PuTTY xterm-ish window, making my daily work on Windows rather more productive.

You see, I'm a command-line sort of guy. And BASH is indispensable to my habits; hence Cygwin. And the default DOS box terminal is lame.

Using PuTTYcyg is a cinch. Download, unpack and add a shortcut to your desktop for C:\puttycyg-20070320\putty.exe - (or wherever you unpack to; the important part is the trailing solo hyphen). I usually change the icon to the Cygwin one (%SystemDrive%\cygwin\cygwin.ico, YMMV).

Tuesday, April 03, 2007

Google's excellent code coloring

This looks like fun:

<html>
<head>
<title>Example</title>
<link href="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<h1>C</h1>
<pre class="prettyprint">void
main(char* argv[])
{
    printf("Hello, Bob.\n");
}</pre>
<h1>Java</h1>
<pre class="prettyprint">public class Main {
    public static void main(final String[] args) {
        System.out.println("Hello, Bob.");
    }
}</pre>
<h1>Shell</h1>
<pre class="prettyprint">echo "Hello, Bob."</pre>
</body>
</html>

Friday, March 23, 2007

Writing JUnit 4 parameterized tests with varargs data

One of the many excellent new features of JUnit 4 is parameterized tests. These are data-driven tests where a test case runs repeatedly against a collection of test data, as if each run were its own test case.

A standard example:

@RunWith(Parameterized.class)
public class ExampleDataDrivenTest {
    public static final class Data {
        private final String name;

        public Data(final String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    private final List<Data> data;

    public ExampleDataDrivenTest(final Data datum1, final Data datum2) {
        System.out.println("ExampleDataDrivenTest");

        this.data = asList(datum1, datum2);
    }

    @Test
    public void dumpData() {
        for (final Data datum : data)
            System.out.println("datum = " + datum);
    }

    @Parameters
    public static Collection<Data[]> data() {
        final Data[][] data = new Data[][]{
                {new Data("apple"), new Data("core")}};

        return asList(data);
    }
}

This produces:

ExampleDataDrivenTest
datum = apple
datum = core

This works great for a fixed number of test data, but I want to test a variable number of data. The change is straight-forward once you recall that the varargs Java language feature is implemented as an array:

@RunWith(Parameterized.class)
public class ExampleDataDrivenTest {
    public static final class Data {
        private final String name;

        public Data(final String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    private final List<Data> data;

    public ExampleDataDrivenTest(final Data... data) {
        System.out.println("ExampleDataDrivenTest");

        this.data = asList(data);
    }

    @Test
    public void dumpData() {
        for (final Data datum : data)
            System.out.println("datum = " + datum);
    }

    @Parameters
    public static Collection<Data[][]> data() {
        final Data[][][] data = new Data[][][]{
                {{new Data("apple"), new Data("core")}}};

        return asList(data);
    }
}

Reflect on the constructor and you see:

public ExampleDataDrivenTest(ExampleDataDrivenTest$Data[])

This makes the change more obvious.

I can now write my annotated parameters as:

    @Parameters
    public static Collection<Data[][]> data() {
        final Data[][][] data = new Data[][][]{{{ /* no data */ }},
                {{new Data("apple"), new Data("core")}},
                {{new Data("baltimore")}}};

        return asList(data);
    }

To produce:

ExampleDataDrivenTest
ExampleDataDrivenTest
datum = apple
datum = core
ExampleDataDrivenTest
datum = baltimore

Saturday, March 10, 2007

Storing jars in a Maven project

One of the sweetest things about Maven is that depedencies are stored external to your sources: if you depend on Apache Commons Lang 2.3, for example, then you can stick this in the dependencies section of your pom.xml and stop worrying:

<depedency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.3</version>
</dependency>

But what do you do when your dependency is not available in a public Maven repository? For example, the library is too new to be widely available, or is proprietary like the Oracle JDBC driver?

One tack is to establish an internal repository and refer to that in your pom.xml. But sometimes that is not practical, perhaps because of corporate network use restrictions, or for very small projects.

Before Maven, common practice was to stash dependencies into a directory named lib/ or similar underneath the root of your project sources. When no other solution presents itself, you can follow that practice but keep using Maven.

In your pom.xml, add this top-level section:

<repositories>
    <repository>
        <id>project</id>
        <name>Project Maven Repository</name>
        <layout>default</layout>
        <url>file:///./lib</url>
    </repository>
</repositories>

This establishes the lib/ directory underneath your project as a Maven repository relative to your project root. Now you can stash dependencies there, store them with the rest of your project resources, but keep using Maven.

A little bit more

Often I have to re-lookup the documentation on deploy:deploy-file so that I can put a dependency in an internal repository or in the project repository as described above. Here is a magic incantation example:

$ cd /PATH-TO-guice-1.0-DOWNLOAD
# Checkout the SVN 1.0 tag sources to src/
# Note -- need to use the -Dversion=1.0 switch
# because pom says 1.0-RC2 in spite of tag.  Then:
$ mvn deploy:deploy-file \
    -Durl=file://C:/FULL-PROJECT-PATH/lib \
    -DrepositoryId=project -Dfile=guice-1.0.jar \
    -DpomFile=src/pom.xml -Dversion=1.0
# Pack up the javadocs and sources into jars, then:
$ mvn deploy:deploy-file \
    -Durl=file://C:/FULL-PROJECT-PATH/lib \
    -DrepositoryId=project \
    -Dfile=guice-1.0-javadocs.jar \
    -DpomFile=src/pom.xml -Dversion=1.0 \
    -Dclassifier=javadocs
$ mvn deploy:deploy-file \
    -Durl=file://C:/FULL-PROJECT-PATH/lib \
    -DrepositoryId=project \
    -Dfile=guice-1.0-sources.jar \
    -DpomFile=src/pom.xml -Dversion=1.0 \
    -Dclassifier=sources

I now have the splediferous Guice 1.0 dependency in my project repository, and can use it in my pom.xml with:

<depedency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>1.0</version>
</dependency>

Saturday, February 17, 2007

A TreeList implementation

Following up on my previous post for a tree list collection in Java, here is an implementation in two parts.

First is an abstract base for tree lists along the lines of AbstractSequentialList, but with an important difference.

For the standard Collection classes, the elements of the collection are the only objects under consideration, and all elements are explicitly manipulated by calls to the collection: addition, ordering and removal. In contrast, TreeList considers both the elements themselves—the values—and the nodes which refer to those elements.

Because of this dual life, Treelist must manipulate nodes implicitly to shadow elements manipulated explicitly. And to preserve proper typing, TreeList must have a way to create nodes beyond what is possible presently with straight-forward generics.

Why? To permit subclassing of TreeList classes. Unfortunately, that effort is the cause of the several TODO markers in the sample code. Soon, I think, I will revisit this point with Gafter's Gadget.

(Yes, the repeated reference around the same material is intentional. Gafter was rather inspired for his idea, and it points to a near certain improvement in the language for Java 7.)

Problems aside, this code illustrates the good design of the Java Collections and relies heavily on the extension points provided for collection implementors.

Without further ado:

/**
* {@code LinkedTreeList} is a linked node implementation of {@code TreeList}
* using an array list of children.  It does not support mixing nodes between it
* and other implementations of {@code TreeList}.
* <p/>
* It a <em>sequential list</em>, not a random-access one.  Although it supports
* all list operations, {@code LinkedTreeList} performs similarly to {@link
* LinkedList} rather than {@link ArrayList}.  For example, {@link #size()} is
* an <em>O(N)</em> operation rather than <em>O(1)</em>.  In constrast,
* insertion and deletion are very efficient.
*
* @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
* @todo How to make extension type-safe w/o hosing generics syntax?
*/
public abstract class AbstractTreeList<E, C extends AbstractTreeList<E, C>>
       extends AbstractSequentialList<E>
       implements com.jpmorgan.eggplant.util.TreeList<E> {
   private final List<C> children = new ArrayList<C>();

   private C parent;
   private E value;

   protected AbstractTreeList(final E rootValue) {
       this(null, rootValue);
   }

   protected AbstractTreeList(final C parent, final E value) {
       setParent(parent);
       setValue(value);
   }

   protected AbstractTreeList(final C parent, final int index, final E value) {
       setParent(parent, index);
       setValue(value);
   }

   /**
    * @todo Smell.
    */
   protected abstract C newInstance(final C parent, final E value);

   /**
    * @todo Smell.
    */
   protected abstract C newInstance(final C parent, final int index,
           final E value);

   // TreeList

   public boolean isRoot() {
       return null == parent;
   }

   public C getParent() {
       if (isRoot())
           throw new NoSuchElementException();

       return parent;
   }

   public boolean isLeaf() {
       return children.isEmpty();
   }

   public List<TreeList<E>> children() {
       // TODO: How to avoid wonky cast?
       return (List) new Children();
   }

   public TreeList<E> addChild(final E value) {
       return newInstance(self(), value);
   }

   public TreeList<E> addChild(final int index, final E value) {
       return newInstance(self(), index, value);
   }

   /**
    * @todo Merge with {@link Children#remove}.
    */
   public void removeChild(final TreeList<E> child) {
       if (!(child instanceof AbstractTreeList))
           throw new NoSuchElementException();

       ((C) child).setParent(null);
   }

   public TreeList<E> removeChild(final int index) {
       return children().remove(index);
   }

   public boolean removeAllChildren(final Collection<TreeList<E>> c) {
       return children().removeAll(c);
   }

   public boolean retainAllChildren(final Collection<TreeList<E>> c) {
       return children().retainAll(c);
   }

   public E getValue() {
       return value;
   }

   public void setValue(final E value) {
       this.value = value;
   }

   // AbstractSequentialList

   @Override
   public ListIterator<E> listIterator(final int index) {
       if (0 > index)
           throw new IndexOutOfBoundsException();

       final RootValueListIterator lit = new RootValueListIterator();

       for (int i = 0; i < index; ++i)
           if (lit.hasNext())
               lit.next();
           else
               throw new IndexOutOfBoundsException();

       return lit;
   }

   // AbstractCollection

   @Override
   public int size() {
       final ListIterator<E> lit = listIterator();

       while (lit.hasNext())
           lit.next();

       return lit.nextIndex();
   }

   private C self() {
       return (C) this;
   }

   private void adopt(final C parent, final Adopter<C> adopter) {
       if (this.parent == parent)
           return;

       if (this == parent)
           throw new IllegalArgumentException();

       if (null != this.parent)
           siblings().remove(this);

       if (null != (this.parent = parent))
           adopter.adopt(self());
   }

   private List<C> siblings() {
       return parent.children;
   }

   private void setParent(final C parent) {
       adopt(parent, new Adopter<C>() {
           public void adopt(final C child) {
               siblings().add(self());
           }
       });
   }

   private void setParent(final C parent, final int index) {
       adopt(parent, new Adopter<C>() {
           public void adopt(final C child) {
               siblings().add(index, self());
           }
       });
   }

   private interface Adopter<C> {
       void adopt(final C child);
   }

   private class RootValueListIterator
           implements ListIterator<E> {
       private final List<ListIterator<C>> previousNodeIts
               = new ArrayList<ListIterator<C>>();
       private ListIterator<C> currentNodeIt = (ListIterator<C>) singletonList(
               AbstractTreeList.this).listIterator();
       private ListIterator<C> nextNodeIt = (ListIterator<C>) children()
               .listIterator();
       private C currentNode = (C) AbstractTreeList.this;

       private int index;

       public boolean hasNext() {
           return currentNodeIt.hasNext() || nextNodeIt.hasNext();
       }

       public E next() {
           ++index;

           if (currentNodeIt.hasNext())
               return (currentNode = currentNodeIt.next()).getValue();

           if (!nextNodeIt.hasNext())
               throw new NoSuchElementException();

           previousNodeIts.add(currentNodeIt);
           currentNodeIt = nextNodeIt;

           if (!currentNodeIt.hasNext())
               throw new NoSuchElementException();

           currentNode = currentNodeIt.next();
           nextNodeIt = (ListIterator<C>) currentNode.children().listIterator();

           return currentNode.getValue();
       }

       public boolean hasPrevious() {
           return currentNodeIt.hasPrevious()
                   || !previousNodeIts.isEmpty() && previousNodeIts
                   .get(previousNodeIts.size() - 1).hasPrevious();
       }

       public E previous() {
           --index;

           if (currentNodeIt.hasPrevious())
               return (currentNode = currentNodeIt.previous()).getValue();

           if (previousNodeIts.isEmpty())
               throw new NoSuchElementException();

           nextNodeIt = currentNodeIt;
           currentNodeIt = previousNodeIts.remove(previousNodeIts.size() - 1);

           if (!currentNodeIt.hasPrevious())
               throw new NoSuchElementException();

           return (currentNode = currentNodeIt.previous()).getValue();
       }

       public int nextIndex() {
           return index;
       }

       public int previousIndex() {
           return index - 1;
       }

       public void remove() {
           final C remove = currentNode;

           // TODO: Testing, thinking, testing!
           if (hasPrevious()) {
               previous();
               remove.setParent(null);
               if (hasNext())
                   next();
           } else if (hasNext()) {
               next();
               remove.setParent(null);
               if (hasPrevious())
                   previous();
           } else {
               throw new UnsupportedOperationException(
                       "Cannot remove only node.");
           }

           // For fail-fast iterators - see {@link #modCount}.
           ++modCount;
       }

       public void set(final E o) {
           currentNode.setValue(o);
       }

       public void add(final E o) {
           currentNode.addChild(0, o);

           // For fail-fast iterators - see {@link #modCount}.
           ++modCount;
       }
   }

   private class Children
           extends AbstractList<C> {
       @Override
       public C get(final int index) {
           return children.get(index);
       }

       @Override
       public int size() {
           return children.size();
       }

       @Override
       public void add(final int index, final C element) {
           if (null == element)
               throw new NullPointerException();
           if (children.contains(element))
               throw new IllegalArgumentException();

           element.setParent(self(), index);
       }

       @Override
       public C set(final int index, final C element) {
           if (null == element)
               throw new NullPointerException();
           if (children.contains(element))
               throw new IllegalArgumentException();

           final C oldChild = get(index);

           oldChild.setParent(null);
           element.setParent(self(), index);

           return oldChild;
       }

       @Override
       public C remove(final int index) {
           final C child = get(index);

           child.setParent(null);

           return child;
       }
   }
}

Finally is a concrete class putting it all together:

/**
* {@code LinkedTreeList} is a linked node implementation of {@code TreeList}
* using an array list of children.  It does not support mixing nodes between it
* and other implementations of {@code TreeList}.
* <p/>
* It a <em>sequential list</em>, not a random-access one.  Although it supports
* all list operations, {@code LinkedTreeList} performs similarly to {@link
* LinkedList} rather than {@link ArrayList}.  For example, {@link #size()} is
* an <em>O(N)</em> operation rather than <em>O(1)</em>.  In constrast,
* insertion and deletion are very efficient.
*
* @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
* @todo How to make extension type-safe w/o hosing generics syntax?
*/
public class LinkedTreeList<E>
       extends AbstractTreeList<E, LinkedTreeList<E>> {
   public LinkedTreeList(final E rootValue) {
       super(rootValue);
   }

   protected LinkedTreeList(final LinkedTreeList<E> parent, final E value) {
       super(parent, value);
   }

   protected LinkedTreeList(final LinkedTreeList<E> parent, final int index,
           final E value) {
       super(parent, index, value);
   }

   @Override
   protected LinkedTreeList<E> newInstance(final LinkedTreeList<E> self,
           final E value) {
       return new LinkedTreeList<E>(self, value);
   }

   @Override
   protected LinkedTreeList<E> newInstance(final LinkedTreeList<E> self,
           final int index, final E value) {
       return new LinkedTreeList<E>(self, index, value);
   }
}

Saturday, February 10, 2007

TreeList, a Java collection

One hole in the Java collection classes is no tree. I have seen in production code in a prior job in non-UI software developers choose to use Swing JTree as a replacement collection for a tree data structure.

Rather than take that tortured path, here is a straight-forward tree interface:

/**
* {@code TreeList} is a list with left-to-right, depth-first traversal over a
* tree.  There is no limitation to the number of child nodes for a given node.
* <p/>
* Ordinary {@code List} operations behave as if they were operation on a list
* of node values.  For example, given a any tree list node, say
* <var>node</var>, then {@code node.getValue()} and {@code node.get(0)} are the
* same object.
*
* @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
*/
public interface TreeList<E>
       extends List<E> {
   /**
    * Checks if this node is a root node, this is, has no parent.
    *
    * @return {@code true} if a root node
    */
   boolean isRoot();

   /**
    * Gets the parent of this node or throw {@code NoSuchElementException} if
    * this is a root node, hence, never {@code null}.
    *
    * @return the node parent, if any
    *
    * @throws NoSuchElementException if this is a root node
    * @see #isRoot()
    */
   TreeList<E> getParent();

   /**
    * Checks if this node is a leaf node, that is, has no children.
    *
    * @return {@code true} if a leaf node
    */
   boolean isLeaf();

   /**
    * Gets the list of child nodes or an empty list if none, hence, never
    * {@code null}.
    * <p/>
    * The list is read-write.  Changes to the list are reflected in the tree.
    *
    * @return the child nodes, if any, or the empty list
    */
   List<TreeList<E>> children();

   /**
    * Adds a child node to this node with the given <var>value</var> to the end
    * of the list of children.  The new node has this node as its parent.
    *
    * @param value the new child node value
    *
    * @return the child node
    */
   TreeList<E> addChild(final E value);

   /**
    * Adds a child node to this node with the given <var>value</var> to the
    * <var>index</var> position in the list of children.  The new node has this
    * node as its parent.
    *
    * @param index the new child position, 0-based
    * @param value the new child node value
    *
    * @return the child node
    *
    * @throws IndexOutOfBoundsException if <var>index</var> is negative or
    * larger than the count of children of this node
    */
   TreeList<E> addChild(final int index, final E value);

   /**
    * Removes the given <var>child</var> node from this node.
    *
    * @param child the child node to remove
    *
    * @throws NoSuchElementException if <var>child</var> is not a child of this
    * node
    */
   void removeChild(final TreeList<E> child);

   /**
    * Removes the child node at the given <var>index</var> position from this
    * node, and returns it.  Afterwards, the returned node is a <em>root
    * node</em>.
    *
    * @param index the child position, 0-based
    *
    * @return the removed node
    *
    * @throws IndexOutOfBoundsException if <var>index</var> is negative or
    * larger than the count of children of this node
    */
   TreeList<E> removeChild(final int index);

   /**
    * Removes the children nodes in the given collection, <var>c</var>.
    *
    * @param c the child nodes to remove
    *
    * @return {@code true} if the tree changed as a result of this call
    */
   boolean removeAllChildren(final Collection<TreeList<E>> c);

   /**
    * Removes all but the children nodes in the given collection,
    * <var>c</var>.
    *
    * @param c the child nodes to retain
    *
    * @return {@code true} if the tree changed as a result of this call
    */
   boolean retainAllChildren(final Collection<TreeList<E>> c);

   /**
    * Gets the value of this node.  Ordinary {@code List} operations behave as
    * if they were operation on a list of node values.
    *
    * @return the node value
    */
   E getValue();

   /**
    * Sets the value of this node to the given <var>value</var>.   Ordinary
    * {@code List} operations behave as if they were operation on a list of
    * node values.
    *
    * @param value the new value
    */
   void setValue(final E value);
}

An implementation to follow in a later post.

Thursday, February 01, 2007

Outstanding post on closures

Neal Gafter, a co-author of the closure proposal, has just posted an outstanding entry on closures.

In it he describes not just what is happening for Java, but the history of closures, touching on LISP, Scheme and Smalltalk. A tour de force of a technical blog post.

Thursday, January 18, 2007

Controlling a blocking queue in Java

Recently I needed a blocking queue in Java in which I could pause the reader side. Normal behavior is for queue.take() to block so that a reader only runs when there are elements in the queue to process. What I wanted was for there to also be a throttle, so I could pause reading even when there were elements to process. It is not difficult, in fact, to make such a queue in which either end might be paused or stopped, and resumed or restarted:

public class LinkedControllableBlockingQueue<E>
        extends LinkedBlockingQueue<E>
        implements ControllableBlockingQueue<E> {
    // Read side
    private final Lock readLock = new ReentrantLock();
    private final Condition resumed = readLock.newCondition();
    private final AtomicReference<Thread> pausingThread
            = new AtomicReference<Thread>();

    // Write side
    private final Lock writeLock = new ReentrantLock();
    private final Condition restarted = writeLock.newCondition();
    // Begin started
    private final AtomicReference<Thread> startingThread
            = new AtomicReference<Thread>(currentThread());

    // Controllable

    public boolean isStarted() {
        return null != startingThread.get();
    }

    public boolean isPaused() {
        return null != pausingThread.get();
    }

    public void start() {
        if (!startingThread.compareAndSet(null, currentThread()))
            throw new IllegalStateException("Already started");

        writeLock.lock();
        try {
            restarted.signalAll();
        } finally {
            writeLock.unlock();
        }
    }

    public void pause() {
        if (!pausingThread.compareAndSet(null, currentThread()))
            throw new IllegalStateException("Already paused");
    }

    public void resume() {
        if (!pausingThread.compareAndSet(currentThread(), null))
            throw new IllegalStateException("Not paused by current thread");

        readLock.lock();
        try {
            resumed.signalAll();
        } finally {
            readLock.unlock();
        }
    }

    public void stop() {
        if (!startingThread.compareAndSet(currentThread(), null))
            throw new IllegalStateException("Not started by current thread");
    }

    // LinkedBlockingQueue

    // Read side

    @Override
    public E take()
            throws InterruptedException {
        readLock.lock();
        try {
            while (isPaused())
                resumed.await();
        } finally {
            readLock.unlock();
        }

        return super.take();
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Time spent <em>paused</em> is subtracted from <var>timeout</var>.  That
     * is, the total time spent in {@code poll} is the same for the pausing and
     * non-pausing versions of {@code LinkedBlockingQueue} for a given
     * <var>timeout</var> and <var>unit</var>.
     */
    @Override
    public E poll(final long timeout, final TimeUnit unit)
            throws InterruptedException {
        long nanos = unit.toNanos(timeout);

        readLock.lock();
        try {
            while (isPaused())
                if (0 >= (nanos = resumed.awaitNanos(nanos)))
                    return null;
        } finally {
            readLock.unlock();
        }

        return super.poll(nanos, NANOSECONDS);
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Returns {@code null} if paused.
     */
    @Override
    public E poll() {
        readLock.lock();
        try {
            if (isPaused())
                return null;
        } finally {
            readLock.unlock();
        }

        return super.poll();
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Returns {@code null} if interrupted while paused.
     */
    @Override
    public E peek() {
        readLock.lock();
        try {
            while (isPaused())
                resumed.await();
        } catch (final InterruptedException e) {
            return null;
        } finally {
            readLock.unlock();
        }

        return super.peek();
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Returns {@code false} if interrupted while paused.
     */
    @Override
    public boolean remove(final Object o) {
        readLock.lock();
        try {
            while (isPaused())
                resumed.await();
        } catch (final InterruptedException e) {
            return false;
        } finally {
            readLock.unlock();
        }

        return super.remove(o);
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Also throws {@code NoSuchElementException} if interrupted while paused.
     */
    @Override
    public E remove() {
        readLock.lock();
        try {
            while (isPaused())
                resumed.await();
        } catch (final InterruptedException e) {
            throw new NoSuchElementException(e.getMessage());
        } finally {
            readLock.unlock();
        }

        return super.remove();
    }

    // Write side

    @Override
    public void put(final E o)
            throws InterruptedException {
        writeLock.lock();
        try {
            while (!isStarted())
                restarted.await();
        } finally {
            writeLock.unlock();
        }

        super.put(o);
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Time spent <em>stopped</em> is subtracted from <var>timeout</var>.  That
     * is, the total time spent in {@code offer} is the same for the stopping
     * and non-stopping versions of {@code LinkedBlockingQueue} for a given
     * <var>timeout</var> and <var>unit</var>.
     */
    @Override
    public boolean offer(final E o, final long timeout, final TimeUnit unit)
            throws InterruptedException {
        long nanos = unit.toNanos(timeout);

        writeLock.lock();
        try {
            while (!isStarted())
                if (0 >= (nanos = restarted.awaitNanos(nanos)))
                    return false;
        } finally {
            writeLock.unlock();
        }

        return super.offer(o, nanos, NANOSECONDS);
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Also returns {@code false} if interrupted while stopped.
     */
    @Override
    public boolean offer(final E o) {
        writeLock.lock();
        try {
            while (!isStarted())
                restarted.await();
        } catch (final InterruptedException e) {
            return false;
        } finally {
            writeLock.unlock();
        }

        return super.offer(o);
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Also returns {@code false} if stopped.
     */
    @Override
    public boolean add(final E o) {
        return isStarted() && super.add(o);
    }
}