stefanseifert commented on code in PR #106:
URL: https://github.com/apache/sling-site/pull/106#discussion_r1054120663
##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -179,86 +144,141 @@ Since Sling Models 1.2.0 there is another way of
instantiating models. The OSGi
// See the javadoc of the ModelFactory for which Exception can be
expected here
}
-In addition `ModelFactory` provides methods for checking whether a given class
is a model at all (having the model annotation) or whether a class can be
adapted from a given adaptable.
+In addition `ModelFactory` provides methods for checking whether a given class
is a model at all (having the model annotation) or whether a class can be
adapted from a given adaptable.
## Usage in HTL
-[Sling Models Use
Provider](/documentation/bundles/scripting/scripting-htl.html#java-use-provider-1)
(internally uses the `ModelFactory` from above).
+Please see [Sling Models Use
Provider](/documentation/bundles/scripting/scripting-htl.html#java-use-provider-1);
internally it uses the `ModelFactory` from above.
-# Other Options
-## Names
-If the field or method name doesn't exactly match the property name, `@Named`
can be used:
- ::java
- @Model(adaptables=Resource.class)
- public class MyModel {
-
- @Inject @Named("secondPropertyName")
- private String otherName;
- }
-
+# Available injectors
+
+In the above cases just the `@ValueMapValue` annotation was used, but there
other available injectors. For each injector there is a specialized annotation
available. For the optional parameters see the next section.
+
+Injector Name | Annotation | Supported Optional Elements |
Description | Array Support | Parametrized Type Support
+----- | ----------------- | ------------------------------
|------------------------- | --------------- | ---------------------------
+Scripting Bindings|`@ScriptVariable` | `injectionStrategy` and `name`
| Injects the script variable defined via [Sling
Bindings](https://cwiki.apache.org/confluence/display/SLING/Scripting+variables).
If `name` is not set the name is derived from the method/field name. | no
conversion is done | If a parameterized type is passed, the bindings value
must be of a compatible type of the parameterized type.
+ValueMap | `@ValueMapValue` | `injectionStrategy`, `name` and `via` |
Injects a `ValueMap` value. If `via` is not set, it will automatically take
`resource` if the adaptable is the `SlingHttpServletRequest`. If `name` is not
set the name is derived from the method/field name. | Primitive arrays
wrapped/unwrapped as necessary. Wrapper object arrays are unwrapped/wrapped as
necessary. | Parameterized `List` and `Collection` injection points are
injected by getting an array of the component type and creating an unmodifiable
`List` from the array.
+Child Resource | `@ChildResource` | `injectionStrategy`, `name` and `via`
| Injects a child resource by name. If `via` is not set, it will automatically
take `resource` if the adaptable is the `SlingHttpServletRequest`. If `name` is
not set the name is derived from the method/field name. | none | if a
parameterized type `List` or `Collection` is passed, a `List<Resource>` is
returned (the contents of which may be adapted to the target type) filled with
all child resources of the resource looked up by the given name.
+Request Attribute | `@RequestAttribute` | `injectionStrategy`, `name` and
`via` | Injects a request attribute by name. If `name` is not set the name is
derived from the method/field name. | no conversion is done | If a
parameterized type is passed, the request attribute must be of a compatible
type of the parameterized type.
+Resource path | `@ResourcePath` | `injectionStrategy`, `path`, and `name`
|Injects a resource either by path or by reading a property with the given
name. | yes | none
+OSGi service | `@OSGiService` | `injectionStrategy`, `filter` |
Injects an OSGi service by type (and the optional filter) | yes | Parameterized
`List` and `Collection` injection points are injected by getting an array of
the services and creating an unmodifiable `List` from the array.
+Context-Aware Configuration | `@ContextAwareConfiguration` |
`injectionStrategy`, `name` | Lookup context-aware configuration. See
[Context-Aware Configuration](#context-aware-configuration) below. | yes | If a
parameterized type `List` or `Collection` is used, a configuration collection
is looked up.
+Self | `@Self` | `injectionStrategy` |
Injects the adaptable itself. If the field type does not match with the
adaptable it is tried to adapt the adaptable to the requested type. | none |
none
+Sling Object | `@SlingObject` | `injectionStrategy` |
Injects commonly used sling objects if the field matches with the class:
request, response, resource resolver, current resource, SlingScriptHelper |
none | none
+
+# Parameters to the Injectors
+
+Injectors can support optional parameters as listed in the above table
+
## Optional and Required
-`@Inject`ed fields/methods are assumed to be required. To mark them as
optional, use `@Optional`:
- ::java
- @Model(adaptables=Resource.class)
- public class MyModel {
-
- @Inject @Optional
- private String otherName;
- }
+Injected fields/methods are assumed to be required. To mark them as optional,
there are 2 options:
-If a majority of `@Inject`ed fields/methods are optional, it is possible
(since Sling Models API 1.0.2/Impl 1.0.6) to change the default injection
-strategy by using adding `defaultInjectionStrategy =
DefaultInjectionStrategy.OPTIONAL` to the `@Model` annotation:
+* add the parameter `injectionStrategy=InjectionStrategy.OPTIONAL` to the
annotation
+* or wrap the type into an `Optional`
+
+It is recommended to use the approach using the `Optional` type, because then
this "optionality" is also expressed in the type system.
+
+ ::java
+ import java.util.Optional;
+
+ @Model(adaptables=Resource.class)
+ public class MyModel {
+
+ @ValueMapValue(injectionStrategy=InjectionStrategy.OPTIONAL)
+ private String optionalProperty;
+
+ @ValueMapValue
+ private Optional<String> anotherOptionalProperty;
+ }
+Please note, that also injections marked as optional are always tried. It is
just that any failure to inject a value does not lead to the termination of the
creation of the SlingModel, but instead it continues, leaving the field
value/return value at the default value of the used type.
+
+If a majority of injected fields/methods are optional, it is possible (since
Sling Models API 1.0.2/Impl 1.0.6) to change the default injection strategy by
using adding `defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` to
the `@Model` annotation:
::java
@Model(adaptables=Resource.class,
defaultInjectionStrategy=DefaultInjectionStrategy.OPTIONAL)
public class MyModel {
- @Inject
- private String otherName;
+ @ValueMapValue
+ private String optionalProperty;
}
-To still mark some fields/methods as being mandatory while relying on
`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` for all other
fields, the annotation `@Required` can be used.
+To still mark some fields/methods as being mandatory while relying on
`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` for all other
fields, the parameter `injectionStrategy=InjectionStrategy.REQUIRED` can be
used.
-`@Optional` annotations are only evaluated when using the
`defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED` (which is the
default), `@Required` annotations only if using `defaultInjectionStrategy =
DefaultInjectionStrategy.OPTIONAL`.
+`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` parameters are
only evaluated when using the `defaultInjectionStrategy =
DefaultInjectionStrategy.REQUIRED` (which is the default),
`injectionStrategy=InjectionStrategy.REQUIRED` parameters only if using
`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL`.
-## Defaults
-A default value can be provided (for Strings & primitives):
+## Via
+In some cases, a different object should be used as the adaptable instead of
the original adaptable. This can be done
+using the `via` parameter. By default, this can be done using a JavaBean
property of the adaptable:
::java
- @Model(adaptables=Resource.class)
- public class MyModel {
+ @Model(adaptables=SlingHttpServletRequest.class)
+ public interface MyModel {
- @Inject @Default(values="defaultValue")
- private String name;
- }
+ // will return
request.getResource().getValueMap().get("propertyName", String.class)
+ @ValueMapValue(via="resource")
+ String getPropertyName();
+ }
-Defaults can also be arrays:
+
+A different strategy can be used to define the adaptable by specifying a
`type` attribute:
+
+ ::java
+ @Model(adaptables=Resource.class)
+ public interface MyModel {
+
+ // will return
resource.getChild("jcr:content").getValueMap().get("propertyName", String.class)
+ @Inject @Via(value = "jcr:content", type = ChildResource.class)
+ String getPropertyName();
+
+ }
+
+See the [Via Types](#via-types-since-api-134implementation-140) section below
for details on the included types for `@Via`.
+
+
+## Names
+If the field or method name doesn't exactly match the property name, the
parameter `name` can be used:
::java
@Model(adaptables=Resource.class)
public class MyModel {
- @Inject @Default(intValues={1,2,3,4})
- private int[] integers;
- }
+ @ValueMapValue(name="secondPropertyName")
+ private String otherName;
+ }
+
+In this case the value of the property named `secondPropertyName` would be
taken from the ValueMap.
+
+## Path
+The `@ResourcePath` injector supports the parameter `path` to inject a
resource with the given parameter:
-OSGi services can be injected:
+ ::java
+ @Model(adaptables=Resource.class) {
+
+ @ResourcePath(path="/libs")
+ Resource libs;
+ }
+
+## OSGi Service Filters
+OSGi injection can be filtered:
::java
- @Model(adaptables=Resource.class)
+ @Model(adaptables=SlingHttpServletRequest.class)
public class MyModel {
- @Inject
- private ResourceResolverFactory resourceResolverFactory;
- }
-
-
-In this case, the name is not used -- only the class name.
+ @OSGiInjector
Review Comment:
correct: @OSGiService
##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -274,7 +294,7 @@ List injection for *child resources* works by injecting
grand child resources (s
@Model(adaptables=Resource.class)
public class MyModel {
- @Inject
+ @@ChildResource
Review Comment:
correct: @ChildResource
##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -179,86 +144,141 @@ Since Sling Models 1.2.0 there is another way of
instantiating models. The OSGi
// See the javadoc of the ModelFactory for which Exception can be
expected here
}
-In addition `ModelFactory` provides methods for checking whether a given class
is a model at all (having the model annotation) or whether a class can be
adapted from a given adaptable.
+In addition `ModelFactory` provides methods for checking whether a given class
is a model at all (having the model annotation) or whether a class can be
adapted from a given adaptable.
## Usage in HTL
-[Sling Models Use
Provider](/documentation/bundles/scripting/scripting-htl.html#java-use-provider-1)
(internally uses the `ModelFactory` from above).
+Please see [Sling Models Use
Provider](/documentation/bundles/scripting/scripting-htl.html#java-use-provider-1);
internally it uses the `ModelFactory` from above.
-# Other Options
-## Names
-If the field or method name doesn't exactly match the property name, `@Named`
can be used:
- ::java
- @Model(adaptables=Resource.class)
- public class MyModel {
-
- @Inject @Named("secondPropertyName")
- private String otherName;
- }
-
+# Available injectors
+
+In the above cases just the `@ValueMapValue` annotation was used, but there
other available injectors. For each injector there is a specialized annotation
available. For the optional parameters see the next section.
+
+Injector Name | Annotation | Supported Optional Elements |
Description | Array Support | Parametrized Type Support
+----- | ----------------- | ------------------------------
|------------------------- | --------------- | ---------------------------
+Scripting Bindings|`@ScriptVariable` | `injectionStrategy` and `name`
| Injects the script variable defined via [Sling
Bindings](https://cwiki.apache.org/confluence/display/SLING/Scripting+variables).
If `name` is not set the name is derived from the method/field name. | no
conversion is done | If a parameterized type is passed, the bindings value
must be of a compatible type of the parameterized type.
+ValueMap | `@ValueMapValue` | `injectionStrategy`, `name` and `via` |
Injects a `ValueMap` value. If `via` is not set, it will automatically take
`resource` if the adaptable is the `SlingHttpServletRequest`. If `name` is not
set the name is derived from the method/field name. | Primitive arrays
wrapped/unwrapped as necessary. Wrapper object arrays are unwrapped/wrapped as
necessary. | Parameterized `List` and `Collection` injection points are
injected by getting an array of the component type and creating an unmodifiable
`List` from the array.
+Child Resource | `@ChildResource` | `injectionStrategy`, `name` and `via`
| Injects a child resource by name. If `via` is not set, it will automatically
take `resource` if the adaptable is the `SlingHttpServletRequest`. If `name` is
not set the name is derived from the method/field name. | none | if a
parameterized type `List` or `Collection` is passed, a `List<Resource>` is
returned (the contents of which may be adapted to the target type) filled with
all child resources of the resource looked up by the given name.
+Request Attribute | `@RequestAttribute` | `injectionStrategy`, `name` and
`via` | Injects a request attribute by name. If `name` is not set the name is
derived from the method/field name. | no conversion is done | If a
parameterized type is passed, the request attribute must be of a compatible
type of the parameterized type.
+Resource path | `@ResourcePath` | `injectionStrategy`, `path`, and `name`
|Injects a resource either by path or by reading a property with the given
name. | yes | none
+OSGi service | `@OSGiService` | `injectionStrategy`, `filter` |
Injects an OSGi service by type (and the optional filter) | yes | Parameterized
`List` and `Collection` injection points are injected by getting an array of
the services and creating an unmodifiable `List` from the array.
+Context-Aware Configuration | `@ContextAwareConfiguration` |
`injectionStrategy`, `name` | Lookup context-aware configuration. See
[Context-Aware Configuration](#context-aware-configuration) below. | yes | If a
parameterized type `List` or `Collection` is used, a configuration collection
is looked up.
+Self | `@Self` | `injectionStrategy` |
Injects the adaptable itself. If the field type does not match with the
adaptable it is tried to adapt the adaptable to the requested type. | none |
none
+Sling Object | `@SlingObject` | `injectionStrategy` |
Injects commonly used sling objects if the field matches with the class:
request, response, resource resolver, current resource, SlingScriptHelper |
none | none
+
+# Parameters to the Injectors
+
+Injectors can support optional parameters as listed in the above table
+
## Optional and Required
-`@Inject`ed fields/methods are assumed to be required. To mark them as
optional, use `@Optional`:
- ::java
- @Model(adaptables=Resource.class)
- public class MyModel {
-
- @Inject @Optional
- private String otherName;
- }
+Injected fields/methods are assumed to be required. To mark them as optional,
there are 2 options:
-If a majority of `@Inject`ed fields/methods are optional, it is possible
(since Sling Models API 1.0.2/Impl 1.0.6) to change the default injection
-strategy by using adding `defaultInjectionStrategy =
DefaultInjectionStrategy.OPTIONAL` to the `@Model` annotation:
+* add the parameter `injectionStrategy=InjectionStrategy.OPTIONAL` to the
annotation
+* or wrap the type into an `Optional`
+
+It is recommended to use the approach using the `Optional` type, because then
this "optionality" is also expressed in the type system.
+
+ ::java
+ import java.util.Optional;
+
+ @Model(adaptables=Resource.class)
+ public class MyModel {
+
+ @ValueMapValue(injectionStrategy=InjectionStrategy.OPTIONAL)
+ private String optionalProperty;
+
+ @ValueMapValue
+ private Optional<String> anotherOptionalProperty;
+ }
+Please note, that also injections marked as optional are always tried. It is
just that any failure to inject a value does not lead to the termination of the
creation of the SlingModel, but instead it continues, leaving the field
value/return value at the default value of the used type.
+
+If a majority of injected fields/methods are optional, it is possible (since
Sling Models API 1.0.2/Impl 1.0.6) to change the default injection strategy by
using adding `defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` to
the `@Model` annotation:
::java
@Model(adaptables=Resource.class,
defaultInjectionStrategy=DefaultInjectionStrategy.OPTIONAL)
public class MyModel {
- @Inject
- private String otherName;
+ @ValueMapValue
+ private String optionalProperty;
}
-To still mark some fields/methods as being mandatory while relying on
`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` for all other
fields, the annotation `@Required` can be used.
+To still mark some fields/methods as being mandatory while relying on
`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` for all other
fields, the parameter `injectionStrategy=InjectionStrategy.REQUIRED` can be
used.
-`@Optional` annotations are only evaluated when using the
`defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED` (which is the
default), `@Required` annotations only if using `defaultInjectionStrategy =
DefaultInjectionStrategy.OPTIONAL`.
+`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL` parameters are
only evaluated when using the `defaultInjectionStrategy =
DefaultInjectionStrategy.REQUIRED` (which is the default),
`injectionStrategy=InjectionStrategy.REQUIRED` parameters only if using
`defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL`.
-## Defaults
-A default value can be provided (for Strings & primitives):
+## Via
+In some cases, a different object should be used as the adaptable instead of
the original adaptable. This can be done
+using the `via` parameter. By default, this can be done using a JavaBean
property of the adaptable:
::java
- @Model(adaptables=Resource.class)
- public class MyModel {
+ @Model(adaptables=SlingHttpServletRequest.class)
+ public interface MyModel {
- @Inject @Default(values="defaultValue")
- private String name;
- }
+ // will return
request.getResource().getValueMap().get("propertyName", String.class)
+ @ValueMapValue(via="resource")
+ String getPropertyName();
+ }
-Defaults can also be arrays:
+
+A different strategy can be used to define the adaptable by specifying a
`type` attribute:
+
+ ::java
+ @Model(adaptables=Resource.class)
+ public interface MyModel {
+
+ // will return
resource.getChild("jcr:content").getValueMap().get("propertyName", String.class)
+ @Inject @Via(value = "jcr:content", type = ChildResource.class)
+ String getPropertyName();
+
+ }
+
+See the [Via Types](#via-types-since-api-134implementation-140) section below
for details on the included types for `@Via`.
+
+
+## Names
+If the field or method name doesn't exactly match the property name, the
parameter `name` can be used:
::java
@Model(adaptables=Resource.class)
public class MyModel {
- @Inject @Default(intValues={1,2,3,4})
- private int[] integers;
- }
+ @ValueMapValue(name="secondPropertyName")
+ private String otherName;
+ }
+
+In this case the value of the property named `secondPropertyName` would be
taken from the ValueMap.
+
+## Path
+The `@ResourcePath` injector supports the parameter `path` to inject a
resource with the given parameter:
-OSGi services can be injected:
+ ::java
+ @Model(adaptables=Resource.class) {
+
+ @ResourcePath(path="/libs")
+ Resource libs;
+ }
+
+## OSGi Service Filters
+OSGi injection can be filtered:
::java
- @Model(adaptables=Resource.class)
+ @Model(adaptables=SlingHttpServletRequest.class)
public class MyModel {
- @Inject
- private ResourceResolverFactory resourceResolverFactory;
- }
-
-
-In this case, the name is not used -- only the class name.
+ @OSGiInjector
+ private PrintWriter out;
+
+ @OSGiInjector(name="log")
+ private Logger logger;
+
+ @OsgiInjector(filter="paths=/bin/something")
+ private List<Servlet> servlets;
+ }
-## Collections
-Lists and arrays are supported by some injectors. For the details look at the
table given in [Available Injectors](#available-injectors):
+## Collection support
+Lists and arrays are supported by some injectors. For the details look at the
table given in [Available Injectors](#available-injectors-1):
::java
@Model(adaptables=Resource.class)
Review Comment:
should we switch to a non-@Inject sample here as well?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]