wiki:NsAdapters

Background

The idea behind nsAdapter is to provide the Zope 3 component architecture style access to adapter in Java. After programming for Zope3/Plone for the past year I've come to really admire the flexibility and elegance that their implementation of the adapter pattern gives us. And, after  Martin Aspeli put the call out almost a year ago, and it has not yet been answered, I thought it was time to give it a go. How hard could it be.

You can register classes either directly, by scanning a package, or by creating a file, META-INF/adapters.txt, listing the packages containing adapters. This last method must be invoked by calling AdapterManager?.scan() during your applications initialisation.

The adapter works by matching the implemented interface, then the name, with the method signature you pass in. See below for examples of use.

To get this using Maven, add this repository:

http://projects.nigelsim.org/maven-snapshots/

and this dependency

<dependency>
   <groupId>org.nigelsim</groupId>
   <artifactId>adapters</artifactId>
   <version>0.1-SNAPSHOT</version>
</dependency>

Get code from Github:  http://github.com/nigelsim/nsadapters/tree/master

Example

From the test cases

Getting the adapter:

// Register an adapter manually
AdapterManager.getInstance().register(IPayment.class, Ransom.class,
                                RansomPayment.class);
// Point to an annotated adapter class
AdapterManager.getInstance().register(RansomPayment2.class);
// or scan the classpath for all adapters
AdapterManager.getInstance().scan();
Ransom ransom = new Ransom();
ransom.setCash(0);

IPayment payment = (IPayment) AdapterManager.getInstance().adapt(
        IPayment.class, ransom);
payment.pay();

An annotated adapter:

@Adapter(name="")
public class RansomPayment2 implements IPayment {

    private Ransom ransom;

    public RansomPayment2(Ransom ransom) {
        this.ransom = ransom;
    }

    public void pay() {
        ransom.setCash(200);
    }

}

Limitations

  • If you have an adapter for a class, it will not adapt subclasses of that class