Sling Model annotations

Creating a Sling Model

Annotation used:

  • @Model: declares a bean as Sling Model.
  • @Inject: Injects resource property into a class variable.
  • @PostConstruct: declares the function which would initialize the bean after deriving information based on business logic. The function is called after the all injections have completed.

Example:

@Model(adaptables = Resource.class)

public class ContactUsModel {

	private String mailAddress;

	private String phoneNumber;

	@Inject
	protected String title;

	@Inject
	protected String officeCode;

	@PostConstruct
	protected void init() {
		// Business logic to transform injected values and assign to bean variables
		// Example: Resolve mailAddress/phoneNumber applicable for the user's region, based on officeCode
	}

	public String getMailAddress(){
		return mailAddress;
	}

	public String getPhoneNumber(){
		return phoneNumber;
	}
}
  • In the above example, ‘adaptables = Resource.class’ maps the sling model against a Sling Resource.
  • The @Inject would inject ‘contacts’ property from the resource into ‘contacts’ class variable. The property value injection occurs after adapting the Resource into Value Map.

 

Optional/Required fields

@Model annotation provides ‘defaultInjectionStrategy’ attribute to indicate if the injected fields in a sling model should be required/optional.

Injection strategy on class level:
  • Use ‘defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL’ to mark all injected fields as optional
  • Use ‘defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED’ to mark all injected fields as required. Its also the default configuration, if ‘defaultInjectionStrategy’ is not specified.
Injection strategy on Field level:
  • @Required / @Optional annotations can be used to selectively mark fields as required/optional.

Example:

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ContactUsModel {

	private String mailAddress;

	private String phoneNumber;

	@Inject
	@Required
	protected String title;

	@Inject
	protected String officeCode;

	@PostConstruct
	protected void init() {
		// Business logic to transform the Injected values and assign to bean Variables
		// Example: Resolve mailAddress/phoneNumber applicable for the user's region, based on officeCode
	}

	public String getMailAddress(){
		return mailAddress;
	}

	public String getPhoneNumber(){
		return phoneNumber;
	}
}

Adapt Model from Resource / SlingHttpServletRequest

A Models can be adapted both Resource / SlingHttpServletRequest. This depends upon the fields required to be injected.

  • If only resource properties are required, prefer using:
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
  •  If Sling Objects (eg. currentStyle, currentPage, xssApi etc) are also required, prefer adapting to SlingHttpServletRequest.
@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

Default Value

@Default allows to specify default value for fields (including arrays).
Example:
@Inject @Default(values="Contact Us")
private String title;

@Inject @Default(intValues={1,2,3,4})
private int[] integers;

Refer to link, to use attribute names matching with the field’s type.

Alternate field name

Use @Named if the field name is different from the property name

@Inject @Named("jcr:created")
private String created;

Via

To inject field based on JavaBean property of the adaptable. Use with ‘SlingHttpServletRequest’ to inject property value from the resource.
@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ContactUsModel {
    @Inject @Via("resource")
    private String title;
}

Self

Inject adaptable object to a field.
@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ContactUsModel {
    //Accessing the resource that is adapted to ContactusModel
    @Self
    protected Resource resource;
}

Additional Notes

Design Object

The Design object can be accessed on adapting model to Resource / SlingHttpServletRequest

Injecting currentStyle object

Used when the Sling Model is adapted from SlingHttpServletRequest. Example:

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategyzOPTIONAL)
public class ContactUsModel {
@Inject
private Style currentStyle;
}
Fetch currentStyle object from Resource

Used when the Sling Model is adapted from Resource. Example:

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ContactUsModel {
   private Style currentStyle;
   private Designer designer;

   @PostConstruct
   protected void init() {

       // Getting the currentStyle from the Designer.class
       designer = this.resourceResolver.adaptTo(Designer.class);
       if (designer != null) {
           currentStyle = designer.getStyle(resource);
       }
    }
}

Inject OSGi Services

OSGi services can be injected via @Inject. The annotation could be used while adapting to both Resource and SlingHttpServletRequest

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategyzOPTIONAL)
public class ContactUsModel {

    @Inject
    private ResourceResolver resourceResolver;
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s