@Documented @Target(value={FIELD,ANNOTATION_TYPE}) @Retention(value=RUNTIME) public @interface Reference
Marks a field as containing a reference, i.e. a path to another resource.
Example: The property "searchPage" contains the path
"/content/mysite/de/search" (a String value). without the @Reference
annotation,
the property could be mapped like so:
@ResourceModel
("my/resource/type")
public class MyModel {
private String searchPage;
...
}
However, if one wants to obtain a model representing the referenced search
page, e.g. "SearchPage", one would have to obtain a
ResourceResolver
, get the
Resource
using the "searchPage"
property value, check for null and finally
adapt
the
Resource
to the "SearchPage" model:
@ResourceModel
("my/resource/type") public class MyModel { private String searchPage; @This
private Resource resource; public SearchPage getSearchPage() { SearchPage page = null; if (!isBlank(this.searchPage)) { Resource pageResource = this.resource.getResourceResolver().get(this.searchPage); if (pageResource != null) { page = pageResource.adaptTo(SearchPage.class); } } return page; } }
This boilerplate code is no longer necessary when using the @Reference
annotation:
@ResourceModel
("my/resource/type") public class MyModel { @Reference
private SearchPage searchPage; }
This will automatically
get
the Resource
denoted by the string
value "searchPage" and
adapt it
to the
"SearchPage" model. One can also use this annotation in conjunction with the @
Path
annotation:
... @Path
("some:searchPagePath") @Reference
private SearchPage searchPage;
However, Reference
is unnecessary if Path
is absolute, since
an absolute path is always considered a reference to a
Resource
, thus the following works:
...
@Path
("/content/mysite/${language}/search")
private SearchPage searchPage;
Collection
, List
, Set
and arrays of references are also supported. In this case, the corresponding
property ("pages" in the example below) must have the type String[].
...
@Reference
private List<Page> pages;
Note that upper bound generic types are not supported since the corresponding collection would be read-only. Thus, the following does not work:
...
@Reference
private List<? extends Page> pages;
However, lower bound generic types are supported. Thus, the following does work:
...
@Reference
private List<? super Page> pages;
In case you want to alter the reference prior to resolution, e.g. to obtain specific children of the referenced resource, you can modify the reference path(s) by providing a path segment that is appended to all reference paths, like so:
...
@Reference
(append = "jcr:content")
private List<PageContent> pageContents;
Thus, if the reference(s) point to pages, e.g. /content/page/a, /jcr:content would be appended to the reference path, resulting in /content/page/a/jcr:content to be resolved. The appended path is relative, thus appending a path of the form "../../xyz" is supported as well.
public abstract String append
Copyright © 2024. All rights reserved.