kwin commented on code in PR #106:
URL: https://github.com/apache/sling-site/pull/106#discussion_r1061127843


##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -179,92 +150,121 @@ 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

Review Comment:
   The first column is now a label and no longer the name. The name should 
still be documented as it must be used with annotation `@Source`



##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -89,40 +83,13 @@ Constructor injection is also supported (as of Sling Models 
1.1.0):
 
 Because the name of a constructor argument parameter cannot be detected via 
the Java Reflection API a `@Named` annotation is mandatory for injectors that 
require a name for resolving the injection.
 
-Constructors may use any visibility modifier (as of [Sling Models 
1.5.0](https://issues.apache.org/jira/browse/SLING-8069)):
+Constructors may use any visibility modifier (as of [Sling Models 
1.5.0](https://issues.apache.org/jira/browse/SLING-8069)).
 
-    ::java
-    @Model(adaptables=Resource.class)
-    public class PublicConstructorModel {    
-        @Inject
-        public PublicConstructorModel() {
-          // constructor code
-        }
-    }
+## @Model and adaptable types
 
-    @Model(adaptables=Resource.class)
-    public class ProtectedConstructorModel {    
-        @Inject
-        protected ProtectedConstructorModel() {
-          // constructor code
-        }
-    }
+While technically it is possible to provide any class implementing the 
`Adaptable` interface as the `adaptable` parameter to the `@Model` annotation, 
the Sling Model Framework and the default injectors is mostly built under the 
assumption that the adaption is done from a Sling Resource. All injectors also 
support adaption from a `SlingHttpServletRequest` object, but normally this is 
then converted into a adaption of the resource of the request. The only 
exception on the default injectors is the "Request Attribute" injector, which 
requires that the model is adapted from a SlingHttpServletRequest.

Review Comment:
   More prominent examples requiring request: script bindings and sling object



##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -660,86 +612,78 @@ If you want to generate a bundle header compliant with 
Sling Models < 1.3.4 (i.e
         </instructions>
     </configuration>
 
-# Caching
 
-By default, Sling Models do not do any caching of the adaptation result and 
every request for a model class will
-result in a new instance of the model class. However, there are two notable 
cases when the adaptation result can be cached. The first case is when the 
adaptable extends the `SlingAdaptable` base class. Most significantly, this is 
the case for many `Resource` adaptables as `AbstractResource` extends 
`SlingAdaptable`.  `SlingAdaptable` implements a caching mechanism such that 
multiple invocations of `adaptTo()` will return the same object. For example:
 
-    ::java
-    // assume that resource is an instance of some subclass of AbstractResource
-    ModelClass object1 = resource.adaptTo(ModelClass.class); // creates new 
instance of ModelClass
-    ModelClass object2 = resource.adaptTo(ModelClass.class); // SlingAdaptable 
returns the cached instance
-    assert object1 == object2;
 
-While this is true for `AbstractResource` subclasses, it is notably **not** 
the case for `SlingHttpServletRequest` as this class does not extend 
`SlingAdaptable`. So:
 
-    ::java
-    // assume that request is some SlingHttpServletRequest object
-    ModelClass object1 = request.adaptTo(ModelClass.class); // creates new 
instance of ModelClass
-    ModelClass object2 = request.adaptTo(ModelClass.class); // creates another 
new instance of ModelClass
-    assert object1 != object2;
+# Discouraged annotations
 
-Since API version 1.3.4, Sling Models *can* cache an adaptation result, 
regardless of the adaptable by specifying `cache = true` on the `@Model` 
annotation.
+In earlier versions of Sling Models the use of the annotation `@Inject` was 
suggested and documented; but over time it turned out that it had 2 major 
issues:
 
+* This injection iterated through all available injectors and injected the 
first non-null value provided by an injector. This lead to unpredictable 
behavior, although the order is well-defined. The addition of the `@Source` 
annotation did not really help.

Review Comment:
   Although @Source would have helped it was rarely used.



##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -660,86 +612,78 @@ If you want to generate a bundle header compliant with 
Sling Models < 1.3.4 (i.e
         </instructions>
     </configuration>
 
-# Caching
 
-By default, Sling Models do not do any caching of the adaptation result and 
every request for a model class will
-result in a new instance of the model class. However, there are two notable 
cases when the adaptation result can be cached. The first case is when the 
adaptable extends the `SlingAdaptable` base class. Most significantly, this is 
the case for many `Resource` adaptables as `AbstractResource` extends 
`SlingAdaptable`.  `SlingAdaptable` implements a caching mechanism such that 
multiple invocations of `adaptTo()` will return the same object. For example:
 
-    ::java
-    // assume that resource is an instance of some subclass of AbstractResource
-    ModelClass object1 = resource.adaptTo(ModelClass.class); // creates new 
instance of ModelClass
-    ModelClass object2 = resource.adaptTo(ModelClass.class); // SlingAdaptable 
returns the cached instance
-    assert object1 == object2;
 
-While this is true for `AbstractResource` subclasses, it is notably **not** 
the case for `SlingHttpServletRequest` as this class does not extend 
`SlingAdaptable`. So:
 
-    ::java
-    // assume that request is some SlingHttpServletRequest object
-    ModelClass object1 = request.adaptTo(ModelClass.class); // creates new 
instance of ModelClass
-    ModelClass object2 = request.adaptTo(ModelClass.class); // creates another 
new instance of ModelClass
-    assert object1 != object2;
+# Discouraged annotations
 
-Since API version 1.3.4, Sling Models *can* cache an adaptation result, 
regardless of the adaptable by specifying `cache = true` on the `@Model` 
annotation.
+In earlier versions of Sling Models the use of the annotation `@Inject` was 
suggested and documented; but over time it turned out that it had 2 major 
issues:
 
+* This injection iterated through all available injectors and injected the 
first non-null value provided by an injector. This lead to unpredictable 
behavior, although the order is well-defined. The addition of the `@Source` 
annotation did not really help.
+* This iteration turned out to the performance bottleneck, especially if 
(optional) injections were not succesful, and then all other injectors have to 
be tried.

Review Comment:
   turned out to be a performance bottleneck



##########
src/main/jbake/content/documentation/bundles/models.md:
##########
@@ -179,92 +150,121 @@ 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`   | Injects a 
`ValueMap` value taken from the adapted resource (either taking from the 
adapted resource or the resource of the adapted 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`   | Injects 
a child resource by name (taken from the adapted resource (either taking from 
the adapted resource or the resource of the adapted 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`    | 
Injects a request attribute by name, it requires the the adaptable is a 
`SlingHttpServletRequest` . 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:
+
+* 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.

Review Comment:
   that even injections marked as



-- 
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: dev-unsubscr...@sling.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to