Ok, so I've checked in the initial run at a proposed Abdera 2.0... there are quite a few changes in this package so I thought it would be good to summarize things for those of you checking things out.
1. First off, all of the dependencies have been updated to the latest, greatest versions. In several cases (such as the upgrade to Apache HTTP Client 4.x) this meant making major changes to the code. In fact, the entire Client code component has been overhauled and improved. The basic API will still be familiar to those familiar with Abdera 1.x tho. 2. Second, the java package layout has been rearranged significantly. Because of the many non-backwards compatible changes that have been introduced, the base java package for abdera 2.0 is now org.apache.abdera2.*. With the exception of possible differences in configuration files, both the 1.x and 2.x versions can sit within the same classpath without conflicting. 3. Many of the "common" utility classes have been updated. For instance, org.apache.abdera.model.AtomDate has been moved to org.apache.abdera2.common.date.DateTime and has been expanded to support ISO8601 Duration and Intervals as well. The URI Template library has been overhauled to support the latest version of the URI Templates specification. The Lang tag implementation has been simplified. Language tag validation code has been removed. The language tag registry has grown significantly and the code just wasn't keeping pace with it so it was better, and more scalable just to remove the validation code. The new org.apache.abdera2.common.http.* package contains a number of utilities for working directly with various HTTP Header values.. these include EntityTags, Q-value qualified tokens (e.g. for content negotiation), custom Authentication headers, cache controls and web links (http://tools.ietf.org/html/rfc5988). 4. A very important change is that the NamedWriter and NamedParser mechanism has been revamped. In fact, the NamedWriter and NamedParser interfaces have been dropped completely and replaced with just Writer and Parser implementations that use the @Name annotation from org.apache.abdera2.common.anno.* package. The functionality for supporting named writers and parsers is still there, but if you've implemented a NamedWriter and NamedParser, then you'll have to port those over when moving to Abdera2 5. There is now a DefaultImplementation annotation that can be used with the classpath discovery mechanism for specifying the default implementation of an interface. 6. There is a new Selector interface that provides a mechanism of filtering requested lists. New methods have been added to the Feed Object Model API to support the use of selectors... For instance, entry.getLinks(new MySelector()) ... the Selector interface can greatly simplify the code necessary for iterating through a list of elements and can improve overall performance since the FOM method implementations will apply the selector internally when it is building the list to return, avoiding the need to iterate through the list multiple times. 7. There is an experimental new Pusher interface. This is essentially a pub/sub style interface for pushing objects (e.g. atom entries or activities) to a collection of listeners. It can, for instance, be used to implement a long-polling async servlet based on the new Servlet 3.0 asynchronous request support. An experimental long polling servlet has been included in the org.apache.abdera2.common.protocol.servlet.async package. The default implementation of the Pusher interface is based on a ConcurrentLinkedQueue and mechanisms from the java.util.concurrent.* package, but alternative implementations can be plugged in using the usual Abdera classpath discovery model. You could, for instance, back it up with a message queue for a more enterprisey implementation approach. 8. The Unicode stuff has been completely replaced with ICU4J. This should have happened a long time ago but I'd never gotten around to it. 9. An implementation of http://tools.ietf.org/html/rfc5987 has been added to the org.apache.abdera2.common.test.Codec class and has been made the default encoding for HTTP Headers that include non-ascii characters. Q and B Codec support is still included as a fallback. 10. ExtensionFactory implementations that extend from AbstractExtensionFactory have been simplified using Annotations. Whereas before you had to call a number of methods in the constructor to register the namespace and extension implementation classes handled by the ExtensionFactory, now you can use a number of simple annotations. For instance, @Namespace({"http://example.org/foo/ns"}) @Impls({@Impl(Foo.class)}) public final class MyExtensionFactory extends AbstractExtensionFactory {} @QName(value="foo", ns="http://example.org/foo/ns") public class Foo extends ElementWrapper { ... } And that's it... configuration of ExtensionFactory impls using classpath discovery remains unchanged. 11. The ExtensionFactoryMap implementation has been improved. Before, when an extension needed to be created, it would iterate through ALL of the extension factories until it found one that could create the extension, regardless of whether the extensionfactory was capable of handling extensions of that particular namespace. This caused a significant performance lag and really was a bug that should have been fixed a long time ago. Now it checks first to see if the extensionfactory is capable of handling the namespace before it attempts to create the element. 12. Performance in the FOMFactory implementation has been greatly improved by building an internal hashmap of QName to Constructor pairs. That is, whenever the factory needed to create an element, it would go through and check the qname of the element being created against each of the known core QNames. Each one of these was an equals(...) check that would be performed sequentially every time, causing poor linear performance as we were parsing. Obviously, when dealing with large amounts of elements, it was enough to really slow things down. So instead, when the FOMFactory class is created, a static mapping of QNames to the appropriate Constructor methods on their respective classes is created and cached in memory. When a request to create an element instance of received, we simply need to do a constant time lookup of the appropriate constructor, call newInstance(...) on it and off we go. The performance improvement is significant. 13. the ListParseFilter has been changed to a SetParseFilter... using Set internally for that just made more sense and generally improves performance. 14. The server code has undergone a major overhaul, primarily to support the addition of the Activity Streams component that I'll talk about in a minute. Basically, in Abdera 1.x, the server assumed the use of the Atom format throughout every layer. The Feed Object Model was baked in to nearly every class. In Abdera2, the core of the Abdera Server Framework has been abstracted out so as to not depend or assume any specific data format. This allows us, for instance, to create a publishing service for JSON Activity Streams that uses the Activity Streams format as a direct replacement for an Atom Feed. This essentially gives us an out of the box mechanism for working with Activity Streams the same way we work with Atompub 15. The major new addition to Abdera2 is the Activities Streams component. This is based entirely on the JSON Activity Streams specification and does not include support for the Atom-based Activities Streams specification (the Atom-based flavor can be added later within the extensions module if necessary). The activities module includes support for producing and consuming activity streams, provides a rich api for interacting with the various Activity Streams objects, include a Client and Server implementation based on the exact same model used for Atompub, and provides a number of utilities and extensions to the core spec. A rich set of examples are included. 16. I'm sure there are other things that I'm missing and haven't mentioned. Overall, there are a number of API changes throughout that I will continue to work on documenting. Example documentation will need to be updated. Things yet to be done... 1. I did not port any of the existing Adapters or the Spring module over to the new code. This is primarily because the dependencies for those have changed significantly as well and I'm just not an expert in each of those specific components. I'm also not sure which backend data storage mechanisms we should be primarily targeting right now. It would be great if we could get some others to start taking a look at those. 2. The Servlet 3.0 support is still highly experimental. The basic servlet works fine, but the async servlet stuff needs work and testing. Right now there's a bad memory leak in the default implementation that I haven't had a chance to track down yet. 3. Extensive testing and even more testing. I've run through all the test cases and have them working with a few minor exceptions for the async servlet stuff, but given how many changes have gone into this, it needs to be thoroughly put through it's paces.
