This page was moved to https://cwiki.apache.org/confluence/display/CAUSEWAY/CustomValueTypes
Click in the link above if you are not automatically redirected in 10 seconds.


First, a bit of history.

Back in the Naked Objects days we defined ValueSemanticsProvider as an interface that provides the metadata about built-in and potentially custom value types as well.  This interface is defined as:

public interface ValueSemanticsProvider<T> {

    Parser<T> getParser();
    EncoderDecoder<T> getEncoderDecoder();
    DefaultsProvider<T> getDefaultsProvider();
    boolean isImmutable();
    boolean isEqualByContent();

}

This dates from the days when the framework pretty much did everything: the UI was its own widget set, persistence was also home-grown, and there was also client/server support:

  • the Parser class was used in the UI to read from widgets into the target value type
  • the EncoderDecoder was used to serialize the state of the value, either to the persistence store or also for networking (client/server support)
  • the DefaultsProvider was also used in core (and apparent in the UI) to initialize values to a known state - eg a date would default to today's date, rather than null, say.

This class does still exist pretty much unchanged, though its exact purpose is no longer quite so clear cut, primarily because we now have 3rd party libraries for the UI and persistence, and we have dropped the client/server stuff:

Put together, I am pretty sure that Parser, EncoderDecoder and DefaultsProvider are no longer used anywhere.  And the immutable and equalByContent possibly never were used, they were more "for future use".

The current state

In the meantime, as v1.x has evolved, there have been a number of new features that ideally need to be flexible enough to support custom value types

  • With isis-core-schema and its ValueType enum, we have a built-in list of value types that we support, but because this is an enum, there's no way to add in new value types (except by releasing a new version of the framework with an updated enum).
  • For Joerg's new RO client, he could use some additional mime/types for values such as Markup and AsciiDoc that are basically just text/html .
  • We've thought for a long time about being able to teach the viewers about new value types, so that they can transparently handle them.

Realistically, I think this is going to be "horses for courses": each third party library (viewer or persistence) will have its own way of teaching it about the value type. 

Proposal: Use VSP for simple value types (single fields)

But what we might be able to do is define some common semantics in an updated version of the VSP interface, and then have an Isis-provided implementation of the appropriate SPI that can leverage this additional metadata.

For example, considering the Wicket viewer - my suspicion is that its IConverter can do a lot of the work (and we already implement this for some of our built-ins).  We could therefore have a ConverterThatUsesValueSemanticsProvider which uses the VSP to do the conversion etc.  Perhaps this will require keeping Parser and EncoderDecoder as our own internal SPIs, and then bridge across to them.

Similarly, for DN, for the SPIs to be implemented (JavaTypeMapping and ColumnMapping), we could perhaps have JavaTypeMappingThatUsesValueSemanticsProvider and ColumnMappingThatUsesValueSemanticsProvider.

For the RO viewer, which is home grown (as per the RO spec), we would need to invent some sort of SPI.  I imagine that this SPI would require mime types to be part of the mix.

As and when we integrate other viewers (eg Vaadin) or persistence stores (eg EclipseLink/Hibernate), then they will undoubtedly have their own SPIs similarly.  So again, it should be SomeSpiThatUsesValueSemanticsProvider.

Proposal: don't bother for Value types with multiple fields

The above general purpose idea will suffice for simple value types, basically wrappers around a single string or number, but something more sophisticated will be required for values that constitute multiple fields, such as an Interval (from, to) or a Coordinate (x,y) or an ImaginaryNumber (real, complex).

For the Wicket viewer, presumably the input of these values would require two separate fields, and might be rendered as two fields or perhaps as a single field (eg "5+3i" for a complex number)

For DN, I see that SingleFieldMultiMapping inherits from JavaTypeMapping, so I hope that a value could be stored into separate columns, but again some more metadata will be required.

My suspicion is that this will become really difficult to accomplish in a fully generic way.  Therefore, for more complex value types we should simply structure the extensions module to have the appropriate submodules for those integrations that exist.

In other words, if I look at the valuetypes/coordinate directory, for example, it would look something like:

valuetypes/coordinate/

    applib/     - defines the value type itself

    wicket/     - module to link to if using the value type in Wicket

    restful/    - module to link to if using the value type in any actions or properties of domain objects exposed via the RO viewer

    vaadin/   - module to link to if using the value type in Vaadin

    datanucleus/   - if using JDO/DN

    hibernate/   - if using JPA/hibernate

    schema/   - if wanting to use the value type in schema  (still not sure about this one, and that ValueType enum)








  • No labels

1 Comment

  1. Some discussion from #slack channel:


    Andi Huber  12:31

    sticking with the complex number example, I think all we need for a generic solution is to support a typed Tuple, where the types are those the schema providesDan Haywood  12:32

    Maybe so ... though it makes sense to me to tackle the lower hanging fruit of single scalars first. After that, perhaps the way to generalize into a typed Tuple will be obvious.

    Andi Huber  12:32

    a complex number would then map onto a Tuple<BigDecimal, BigDecimal>

    12:33
    we could also render such tuples in a generic way

    Dan Haywood  12:34

    Well, we would want some control over the rendering. It could be that they are all just shown as a single scalar string, with the Parser class (or similar) responsible for returning that string

    12:34
    eg "2+3i" or "[30.23, 40.54]" or "20/1/2009 to 23/1/2009"

    12:35
    Perhaps that's the more common use case than rendering the constituent parts of the value type separately

    Andi Huber  12:35

    or simple as 2 big_decimals, which we already know how to render (somehow grouped together with a tilte or so)

    Dan Haywood  12:36

    Well, maybe, but there's no obvious answer that fits all cases. And so the VSP will end up being quite a complicated thing if we want to fully generify this in all cases.

    12:37
    (eg consider a value type that is for a graph structure, say)

    Andi Huber  12:39

    I agree, yet I do have at least 2 custom types where this tuple approach would perfectly fit

    Dan Haywood  12:40

    So, we should get there bit-by-bit, tackling progressively more complicated value types. If we can find a sensible generic approach, that's great, but I'd rather get there gradually


    new messages


    Andi Huber  12:41

    yep