Basics - 3.2

This section describes basics of Slice - it gives an overview of how Slice works and how it uses dependency injection to build and provide models.

Overview

The above figure depicts a simplified model of working:

  1. Component (JSP script) uses <slice:lookup> tag to fetch a required model of data (in form of a Java object).
  2. The <slice:lookup> tag uses Guice Injector to get the requested model.
  3. Injector finds a binding to a given class, creates an object of the class and returns it to the tag. Injector is created and configured by an activator of the bundle when the bundle was starting.
  4. Tag exposes returned model (object) to the JSP script.
  5. JSP script uses the model to render its view.

<slice:lookup>

The <slice:lookup> tag (described in details at lookup) is an entry point from JSP to Slice. Take a look at a simple JSP:

<slice:lookup var="model" type="<%=com.cognifide.myapp.TextModel.class%>" />
<p>${model.text}</p>

In this example <slice:lookup> gets TextModel and saves it in model variable (1 line), so that it can be used to output the value of text field (2 line).

The tag uses injector to fetch ModelProvider object which then is used for providing the actual object of the requested class using the resource of the actual component.

ModelProvider

ModelProvider (described in details at ModelProvider) is a core interface in Slice and is used for providing objects (models). Its functionality is very similar to injector's getInstance(); however it is extended by a resource, so that object fields can be mapped using specified resource (or path). A simple use of ModelProvider:

ModelProvider modelProvider = injector.getInstance(ModelProvider.class);
TextModel model = modelProvider.get(TextModel.class, request.getResource());

ModelProvider is accessible through injector (line 1). The whole magic is done in line 2. modelProvider#get takes two parameters:

  • class - class of an object we want to have
  • resource - JCR resource which will be read and mapped to object fields.

In order to map an object from specified resource, the object must be annotated by @SliceResource annotation.

@SliceResource

The @SliceResource annotation is used for marking classes which should be mapped from current resource by built-in object-resource Mapper. An example class looks like this:

@SliceResource
public class TextModel {
 
    @JcrProperty
    private String text;
 
    public String getText() {
        return text;
    }
}

Fields annotated by @JcrProperty will be mapped with corresponding properties from current resource. This way, once modelProvider#get method has been called (as in example above), the returned object is mapped and its text field stores a value of the current resource's text property.

Summary

The three subsections above described very briefly core mechanisms of Slice. To sum it up, take a look at the image below which put all these things together.