Skip to content

View Metadata Handling

Carl Harris edited this page Jul 12, 2018 · 8 revisions

Prospecto views can include arbitrary metadata values. A metadata value is produced by a MetadataHandler, when generating a view from a template. When a view is applied to update a model, metadata values that are present in the view can be consumed by the same handler.

Specifying Literal Metadata

Sometimes, you just want to include a simple literal metadata value in your view. For this purpose, the template builder includes a view meta method overloads that define a simple metadata value. It's easy to use in a view template.

ViewTemplate MY_TEMPLATE = ViewTemplateBuilderProducer
    .object(MyModel.class)
        .meta("myMetaValue", "some metadata value")
        .end()
    .build();

Underneath the covers, Prospecto uses the LiteralMetadataHandler included in the API module to "produce" literal metadata values in a view.

This example uses a literal string as a value, but any instance of a [coercible value type] (Value-Type-Conversion#value-type-coercion) can be used as a literal metadata value.

Using Custom Metadata Handlers

Usually, metadata isn't just a simple literal value, but is instead derived using the model context, view context, or both. The template builder also includes several overloads for the meta method that allow you to specify a MetadataHandler.

ViewTemplate MY_TEMPLATE = ViewTemplateBuilderProducer
    .object(MyModel.class)
        .meta("myMetaValue", MyMetadataHandler.class,
            "someHandlerProperty", "someHandlerPropertyValue",
            "someOtherHandlerProperty", 42)
        .end()
    .build();

As shown in the example, you can specify a class literal to identify the handler type, and you can specify arbitrary name-value pairs for configuration properties that will be injected into the handler after it is created. Additionally, any @PostConstruct methods on the handler class will be invoked after the instance has been created and configuration properties have been injected.

You can also simply refer to an existing MetadataHandler instance. In this case, it is assumed that the handler is fully initialized.

Your MetadataHandler implements two methods; one to produce a value when a view is generated, the other to consume a value when a view is applied to update a model.

public interface MetadataHandler {

  Object produceValue(MetaNode node, Object parentModel, ViewContext context)
      throws Exception;

  void consumeValue(MetaNode node, Object parentModel, Object value,
      ViewContext context) throws Exception;
}

The MetaNode instance is the template node itself. It is immutable, but you might associate attributes with it that influence the handler's behavior. The parentModel is an instance of the model type associated with the parent view node. Each handler method also gets a reference to the view context, into which you can place other objects needed in the handler implementation.

You might use properties of the parent model object to derive the metadata value in produceValue. Or your consumeValue implementation might set properties of the model that aren't handled directly by Prospecto when a view is applied to update the model.