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;
}
}

view raw
Inject
hosted with ❤ by GitHub

  • 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.

@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;
}
}

view raw
Optional-Required
hosted with ❤ by GitHub

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;
}
}

view raw
Optional-Required
hosted with ❤ by GitHub

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)

view raw
Model-Resource
hosted with ❤ by GitHub

  •  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;

view raw
Default
hosted with ❤ by GitHub

    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;

view raw
Named
hosted with ❤ by GitHub

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;
}

view raw
Via
hosted with ❤ by GitHub

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;
}

view raw
Self
hosted with ❤ by GitHub

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;
}

view raw
currentStyle
hosted with ❤ by GitHub

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;
}

view raw
OSGi Service
hosted with ❤ by GitHub

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 )

Connecting to %s