We released JBoss DNA 0.1 about two weeks ago, and we’ve been getting some good feedback. One of the suggestions was to make it even easier for sequencer implementations to work with paths and property values. The work we’ve been doing on the federation engine (in particular, the SPI) dovetails nicely with this, so today some of those federation changes were rolled into the trunk.
The idea of the SPI is to define the interfaces that are needed by the various extensions, saving those extensions from having to depend on the implementations (or even on other Maven projects the implementations might require). This also keeps things simple, as the SPI is should be small-ish in size and easier to learn.
Well, one of the things that the federation engine, connectors, and sequencers all need (or at least can benefit from) is a simple set of factories for creating property values, qualified names, and paths. JCR has a lot of semantics in correctly building and working with qualified names and paths, as well as some funky rules for property type conversions. The DNA SPI centralizes all this functionality behind a simple set of value factories.
Each value factory has methods for creating values from all the different types, and the factory does the conversion (or throws an exception if the conversion is undefined; e.g., creating a date from a boolean). We’re also using Java 5 generics, so a single interface defines everything:
public interface ValueFactory<T> { PropertyType getPropertyType(); T create( String value ); T create( String value, TextEncoder decoder ); T create( int value ); T create( long value ); T create( boolean value ); T create( float value ); T create( double value ); T create( BigDecimal value ); T create( Calendar value ); T create( Date value ); T create( Name value ); T create( Path value ); T create( Reference value ); T create( URI value ); T create( byte[] value ); T create( InputStream stream, int approximateLength ); T create( Reader reader, int approximateLength ); T create( Object value ); }
All of the code create
methods throw ValueFormatException
(which is a runtime exception) – this was left off here for readability.
Then, the ValueFactories
interface defines a way to obtain factories:
public interface ValueFactories extends Iterable<ValueFactory<?>> { ValueFactory<?> getValueFactory( PropertyType type ); ValueFactory<?> getValueFactory( Object prototype ); ValueFactory<String> getStringFactory(); ValueFactory<Binary> getBinaryFactory(); ValueFactory<Long> getLongFactory(); ValueFactory<Double> getDoubleFactory(); ValueFactory<BigDecimal> getDecimalFactory(); DateTimeFactory getDateFactory(); ValueFactory<Boolean> getBooleanFactory(); NameFactory getNameFactory(); ValueFactory<Reference> getReferenceFactory(); PathFactory getPathFactory(); ValueFactory<URI> getUriFactory(); ValueFactory<Object> getObjectFactory(); }
A few of the factories have their own interfaces that extend ValueFactory<T>
, adding convenience methods specific to that type. PathFactory
for example adds quite a few methods for different ways of creating paths.
As for sequencers, the SequencerOutput
interface has been modified with a new method to obtain the ValueFactories
reference, and another to set the property given the node path as a Path
and property name as a Name
. So not only is it much easier to build and work with paths, it’s also much easier to create the correct types. Check out the latest code in our SVN repository. (This change is backward compatible, so you’re sequencers wouldn’t need to change.)
Oh, one more thing: Java’s Date
classes and the Calendar
class are crap. (Alex is right.) They’re mutable, painful to use, and buggy. The JBoss DNA SPI created its own DateTime
interface, which wraps Joda-Time’s DateTime and which can be replaced by whatever JSR-310 comes up with.
Filed under: features, jcr, repository