You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2014/11/20 11:18:09 UTC

svn commit: r1640710 [1/2] - in /sling/trunk/bundles/extensions/models: api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ api/src/main/java/org/apache/sling/models/spi/injectorspecific/ impl/src/main/java/org/apache/sling/models/i...

Author: kwin
Date: Thu Nov 20 10:18:08 2014
New Revision: 1640710

URL: http://svn.apache.org/r1640710
Log:
SLING-4155, consider default injection strategy also for injector-specific annotations

by that deprecate isOptional on all injector-specific annotations and introduce the new injectionStrategy attribute as a replacement.

Added:
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/InjectionStrategy.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor2.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor2.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory2.java
Modified:
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ResourcePath.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/Self.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/SlingObject.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/AbstractInjectableElement.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/injectors/SelfInjectorTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/testmodels/classes/ResourceModelWithRequiredFieldOptionalStrategy.java

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java Thu Nov 20 10:18:08 2014
@@ -46,10 +46,20 @@ public @interface ChildResource {
      * If set to true, the model can be instantiated even if there is no child resource
      * with that name available.
      * Default = false.
+     * @deprecated Use {@link injectionStrategy} instead.
      */
+    @Deprecated
     public boolean optional() default false;
 
     /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
+
+    /**
      * If set, then the child resource can be obtained via a projection of the given
      * property of the adaptable.
      */

Added: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/InjectionStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/InjectionStrategy.java?rev=1640710&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/InjectionStrategy.java (added)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/InjectionStrategy.java Thu Nov 20 10:18:08 2014
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.annotations.injectorspecific;
+
+public enum InjectionStrategy {
+    DEFAULT,
+    OPTIONAL,
+    REQUIRED
+}

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java Thu Nov 20 10:18:08 2014
@@ -47,6 +47,16 @@ public @interface OSGiService {
     /**
      * If set to true, the model can be instantiated even if there is no OSGi service implementation available. Default
      * = false.
+     * @deprecated Use {@link InjectionStrategy} instead.
      */
+    @Deprecated
     public boolean optional() default false;
+
+    /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java Thu Nov 20 10:18:08 2014
@@ -48,6 +48,16 @@ public @interface RequestAttribute {
      * If set to true, the model can be instantiated even if there is no request attribute
      * with the given name found.
      * Default = false.
+     * @deprecated Use {@link InjectionStrategy} instead.
      */
+    @Deprecated
     public boolean optional() default false;
+
+    /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectonStrategy() default InjectionStrategy.DEFAULT;
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ResourcePath.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ResourcePath.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ResourcePath.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ResourcePath.java Thu Nov 20 10:18:08 2014
@@ -52,7 +52,17 @@ public @interface ResourcePath {
      * If set to true, the model can be instantiated even if there is no request attribute
      * with the given name found.
      * Default = false.
+     * @deprecated Use {@link InjectionStrategy} instead.
      */
+    @Deprecated
     public boolean optional() default false;
 
+    /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
+
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java Thu Nov 20 10:18:08 2014
@@ -47,6 +47,16 @@ public @interface ScriptVariable {
      * If set to true, the model can be instantiated even if there is no
      * scripting value with the specified name.
      * Default = false.
+     * @deprecated Use {@link InjectionStrategy} instead.
      */
+    @Deprecated
     public boolean optional() default false;
+
+    /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/Self.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/Self.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/Self.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/Self.java Thu Nov 20 10:18:08 2014
@@ -40,7 +40,17 @@ public @interface Self {
     /**
      * If set to true, the model can be instantiated even if there is no object that can be adapted from the adaptable itself. 
      * Default = false.
+     * @deprecated Use {@link injectionStrategy} instead
      */
+    @Deprecated
     public boolean optional() default false;
+    
+    /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
 
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/SlingObject.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/SlingObject.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/SlingObject.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/SlingObject.java Thu Nov 20 10:18:08 2014
@@ -84,11 +84,21 @@ import org.apache.sling.models.spi.injec
 @Source("sling-object")
 public @interface SlingObject {
 
-  /**
-   * If set to true, the model can be instantiated even if there is no request attribute
-   * with the given name found.
-   * Default = false.
-   */
-  boolean optional() default false;
+    /**
+     * If set to true, the model can be instantiated even if there is no request attribute
+     * with the given name found.
+     * Default = false.
+     * @deprecated Use {@link injectionStrategy} instead
+     */
+    @Deprecated
+    boolean optional() default false;
+    
+    /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    public InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
 
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java Thu Nov 20 10:18:08 2014
@@ -47,10 +47,20 @@ public @interface ValueMapValue {
      * If set to true, the model can be instantiated even if that value is missing.
      * Only considered if default is not set, because any default value implicitly
      * sets optional to true
+     * @deprecated Use {@link injectionStrategy} instead
      */
+    @Deprecated
     boolean optional() default false;
 
     /**
+     * if set to REQUIRED injection is mandatory, if set to OPTIONAL injection is optional, in case of DEFAULT 
+     * the standard annotations ({@link org.apache.sling.models.annotations.Optional}, {@link org.apache.sling.models.annotations.Required}) are used.
+     * If even those are not available the default injection strategy defined on the {@link org.apache.sling.models.annotations.Model} applies.
+     * Default value = DEFAULT.
+     */
+    InjectionStrategy injectionStrategy() default InjectionStrategy.DEFAULT;
+
+    /**
      * If set, then the child resource can be obtained via a projection of the given
      * property of the adaptable.
      */

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java Thu Nov 20 10:18:08 2014
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.0.2")
+@Version("1.1.0")
 package org.apache.sling.models.annotations.injectorspecific;
 
-import aQute.bnd.annotation.Version;
\ No newline at end of file
+import aQute.bnd.annotation.Version;

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java Thu Nov 20 10:18:08 2014
@@ -16,9 +16,12 @@
  */
 package org.apache.sling.models.spi.injectorspecific;
 
+
 /**
  * Default implementation of {@link InjectAnnotationProcessor}.
+ * @deprecated Use {@link AbstractInjectAnnotationProcessor2} instead
  */
+@Deprecated
 public class AbstractInjectAnnotationProcessor implements InjectAnnotationProcessor {
 
     public String getName() {

Added: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor2.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor2.java?rev=1640710&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor2.java (added)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor2.java Thu Nov 20 10:18:08 2014
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.spi.injectorspecific;
+
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
+
+/**
+ * Default implementation of {@link InjectAnnotationProcessor2}.
+ *
+ */
+public class AbstractInjectAnnotationProcessor2 extends AbstractInjectAnnotationProcessor implements InjectAnnotationProcessor2 {
+
+    public InjectionStrategy getInjectionStrategy() {
+        return InjectionStrategy.DEFAULT;
+    }
+
+}

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java Thu Nov 20 10:18:08 2014
@@ -18,7 +18,9 @@ package org.apache.sling.models.spi.inje
 
 /**
  * Processor for injector-specific annotations.
+ * @deprecated Use {@link InjectAnntoationProcessor2} instead
  */
+@Deprecated
 public interface InjectAnnotationProcessor {
 
     /**
@@ -56,7 +58,10 @@ public interface InjectAnnotationProcess
      * 
      * @return the value to be used for the default or null, in
      *         which case the standard annotation should be used.
+     * @deprecated use {@link InjectAnntoationProcessor2.getInjectionStrategy} instead
      */
     Boolean isOptional();
 
+   
+
 }

Added: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor2.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor2.java?rev=1640710&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor2.java (added)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor2.java Thu Nov 20 10:18:08 2014
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.spi.injectorspecific;
+
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
+
+/**
+ * Processor for injector-specific annotations.
+ */
+@SuppressWarnings("deprecation")
+public interface InjectAnnotationProcessor2 extends InjectAnnotationProcessor{
+
+    /**
+     * Tries to get the name value from the annotation.
+     * 
+     * @return the value to be used for the name or null, in which case 
+     *         the standard annotation or name derived from method/field
+     *         should be used
+     */
+    String getName();
+
+    /**
+     * Tries to get the via value from the annotation.
+     * 
+     * @return the value to be used for the via or null, in
+     *         which case the standard annotation should be used
+     */
+    String getVia();
+
+    /**
+     * 
+     * @return true, if a default value is set
+     */
+    boolean hasDefault();
+
+    /**
+     * Tries to get the default value from the annotation. Only used if {@link #hasDefault()} is set to true.
+     * 
+     * @return the value to be used if nothing can be injected
+     */
+    Object getDefault();
+    
+    
+    /**
+     * Tries to get the information whether the injection is optional.
+     * 
+     * @return {@code REQUIRED} if injection is mandatory, {@code OPTIONAL} if injection is optional or {@code DEFAULT} in
+     *         which case the standard annotation/injection strategy should be used.
+     */
+    InjectionStrategy getInjectionStrategy();
+
+}

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java Thu Nov 20 10:18:08 2014
@@ -21,6 +21,7 @@ import java.lang.reflect.AnnotatedElemen
 /**
  * Factory for {@link InjectAnnotationProcessor} that is evaluated at runtime for each
  * sling model adaption and may depend on the adaptable. 
+ * Use {@link StaticInjectAnnotationProcessorFactory} preferably
  */
 public interface InjectAnnotationProcessorFactory {
 
@@ -30,7 +31,7 @@ public interface InjectAnnotationProcess
      * @param element the field or method which is annotated
      * @return a ModelAnnotationProcessor in case there is a known
      *         injector-specific annotation on the given element found otherwise
-     *         null
+     *         null. This method should return a {@link InjectAnnotationProcessor2} preferably.
      */
     InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element);
 

Added: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory2.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory2.java?rev=1640710&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory2.java (added)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory2.java Thu Nov 20 10:18:08 2014
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.models.spi.injectorspecific;
+
+import java.lang.reflect.AnnotatedElement;
+
+/**
+ * Factory for {@link InjectAnnotationProcessor2} that is evaluated at runtime for each
+ * sling model adaption and may depend on the adaptable. 
+ */
+
+public interface InjectAnnotationProcessorFactory2 {
+    /**
+     * 
+     * @param adaptable the object from which this model is adapted
+     * @param element the field or method which is annotated
+     * @return a ModelAnnotationProcessor in case there is a known
+     *         injector-specific annotation on the given element found otherwise
+     *         null
+     */
+    InjectAnnotationProcessor2 createAnnotationProcessor(Object adaptable, AnnotatedElement element);
+}

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/StaticInjectAnnotationProcessorFactory.java Thu Nov 20 10:18:08 2014
@@ -32,6 +32,6 @@ public interface StaticInjectAnnotationP
      *         injector-specific annotation on the given element found otherwise
      *         null
      */
-    InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element);
+    InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement element);
 
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java Thu Nov 20 10:18:08 2014
@@ -17,4 +17,4 @@
 @Version("1.1.0")
 package org.apache.sling.models.spi.injectorspecific;
 
-import aQute.bnd.annotation.Version;
\ No newline at end of file
+import aQute.bnd.annotation.Version;

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java Thu Nov 20 10:18:08 2014
@@ -57,7 +57,6 @@ import org.apache.sling.api.adapter.Adap
 import org.apache.sling.api.adapter.AdapterFactory;
 import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.apache.sling.commons.osgi.ServiceUtil;
-import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.factory.InvalidAdaptableException;
 import org.apache.sling.models.factory.InvalidModelException;
@@ -77,6 +76,7 @@ import org.apache.sling.models.spi.Imple
 import org.apache.sling.models.spi.Injector;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -143,6 +143,12 @@ public class ModelAdapterFactory impleme
     private final Map<Object, InjectAnnotationProcessorFactory> injectAnnotationProcessorFactories = new TreeMap<Object, InjectAnnotationProcessorFactory>();
 
     private volatile InjectAnnotationProcessorFactory[] sortedInjectAnnotationProcessorFactories = new InjectAnnotationProcessorFactory[0];
+    
+    @Reference(name = "injectAnnotationProcessorFactory2", referenceInterface = InjectAnnotationProcessorFactory.class,
+            cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
+    private final Map<Object, InjectAnnotationProcessorFactory2> injectAnnotationProcessorFactories2 = new TreeMap<Object, InjectAnnotationProcessorFactory2>();
+
+    private volatile InjectAnnotationProcessorFactory2[] sortedInjectAnnotationProcessorFactories2 = new InjectAnnotationProcessorFactory2[0];
 
     @Reference(name = "staticInjectAnnotationProcessorFactory", referenceInterface = StaticInjectAnnotationProcessorFactory.class,
             cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
@@ -338,12 +344,20 @@ public class ModelAdapterFactory impleme
         boolean wasInjectionSuccessful = false;
 
         // find an appropriate annotation processor
-        for (InjectAnnotationProcessorFactory factory : sortedInjectAnnotationProcessorFactories) {
+        for (InjectAnnotationProcessorFactory2 factory : sortedInjectAnnotationProcessorFactories2) {
             annotationProcessor = factory.createAnnotationProcessor(adaptable, element.getAnnotatedElement());
             if (annotationProcessor != null) {
                 break;
             }
         }
+        if (annotationProcessor == null) {
+            for (InjectAnnotationProcessorFactory factory : sortedInjectAnnotationProcessorFactories) {
+                annotationProcessor = factory.createAnnotationProcessor(adaptable, element.getAnnotatedElement());
+                if (annotationProcessor != null) {
+                    break;
+                }
+            }
+        }
 
         String name = getName(element, annotationProcessor);
         Object injectionAdaptable = getAdaptable(adaptable, element, annotationProcessor);
@@ -369,7 +383,7 @@ public class ModelAdapterFactory impleme
 
         // if default is not set, check if mandatory
         if (!wasInjectionSuccessful) {
-            if (isOptional(element, modelAnnotation, annotationProcessor)) {
+            if (element.isOptional(annotationProcessor)) {
                 if (element.isPrimitive()) {
                     injectPrimitiveInitialValue(element, callback, result);
                 }
@@ -528,21 +542,6 @@ public class ModelAdapterFactory impleme
         return constructor.getConstructor().newInstance(paramValues.toArray(new Object[paramValues.size()]));
     }
 
-    private boolean isOptional(InjectableElement point, Model modelAnnotation, InjectAnnotationProcessor annotationProcessor) {
-        if (annotationProcessor != null) {
-            Boolean isOptional = annotationProcessor.isOptional();
-            if (isOptional != null) {
-                return isOptional.booleanValue();
-            }
-        }
-        if (modelAnnotation.defaultInjectionStrategy() == DefaultInjectionStrategy.REQUIRED) {
-            return (point.isOptional());
-        } else {
-            return (!point.isRequired());
-        }
-        
-    }
-
     private boolean injectDefaultValue(InjectableElement point, InjectAnnotationProcessor processor,
             InjectCallback callback, Result<?> result) {
 
@@ -881,6 +880,19 @@ public class ModelAdapterFactory impleme
             sortedInjectAnnotationProcessorFactories = injectAnnotationProcessorFactories.values().toArray(new InjectAnnotationProcessorFactory[injectAnnotationProcessorFactories.size()]);
         }
     }
+    protected void bindInjectAnnotationProcessorFactory2(final InjectAnnotationProcessorFactory2 factory, final Map<String, Object> props) {
+        synchronized (injectAnnotationProcessorFactories2) {
+            injectAnnotationProcessorFactories2.put(ServiceUtil.getComparableForServiceRanking(props), factory);
+            sortedInjectAnnotationProcessorFactories2 = injectAnnotationProcessorFactories2.values().toArray(new InjectAnnotationProcessorFactory2[injectAnnotationProcessorFactories.size()]);
+        }
+    }
+
+    protected void unbindInjectAnnotationProcessorFactory2(final InjectAnnotationProcessorFactory2 factory, final Map<String, Object> props) {
+        synchronized (injectAnnotationProcessorFactories2) {
+            injectAnnotationProcessorFactories2.remove(ServiceUtil.getComparableForServiceRanking(props));
+            sortedInjectAnnotationProcessorFactories2 = injectAnnotationProcessorFactories2.values().toArray(new InjectAnnotationProcessorFactory2[injectAnnotationProcessorFactories.size()]);
+        }
+    }
 
     protected void bindStaticInjectAnnotationProcessorFactory(final StaticInjectAnnotationProcessorFactory factory, final Map<String, Object> props) {
         synchronized (staticInjectAnnotationProcessorFactories) {

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/BindingsInjector.java Thu Nov 20 10:18:08 2014
@@ -25,12 +25,13 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.ScriptVariable;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.osgi.framework.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -63,7 +64,6 @@ public class BindingsInjector implements
             log.debug("BindingsInjector doesn't support non-class type {}", type);
             return null;
         }
-
     }
 
     private SlingBindings getBindings(Object adaptable) {
@@ -76,7 +76,7 @@ public class BindingsInjector implements
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         ScriptVariable annotation = element.getAnnotation(ScriptVariable.class);
         if (annotation != null) {
@@ -85,7 +85,7 @@ public class BindingsInjector implements
         return null;
     }
 
-    private static class ScriptVariableAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class ScriptVariableAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final ScriptVariable annotation;
 
@@ -94,6 +94,11 @@ public class BindingsInjector implements
         }
 
         @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
+        
+        @Override
         public Boolean isOptional() {
             return annotation.optional();
         }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ChildResourceInjector.java Thu Nov 20 10:18:08 2014
@@ -31,17 +31,18 @@ import org.apache.felix.scr.annotations.
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.injectorspecific.ChildResource;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory2;
 import org.osgi.framework.Constants;
 
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 3000)
-public class ChildResourceInjector implements Injector, InjectAnnotationProcessorFactory {
+public class ChildResourceInjector implements Injector, InjectAnnotationProcessorFactory2 {
 
     @Override
     public String getName() {
@@ -102,7 +103,7 @@ public class ChildResourceInjector imple
    }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(Object adaptable, AnnotatedElement element) {
         // check if the element has the expected annotation
         ChildResource annotation = element.getAnnotation(ChildResource.class);
         if (annotation != null) {
@@ -111,7 +112,7 @@ public class ChildResourceInjector imple
         return null;
     }
 
-    private static class ChildResourceAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class ChildResourceAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final ChildResource annotation;
         private final Object adaptable;
@@ -132,6 +133,11 @@ public class ChildResourceInjector imple
         }
 
         @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
+
+        @Override
         public Boolean isOptional() {
             return annotation.optional();
         }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/OSGiServiceInjector.java Thu Nov 20 10:18:08 2014
@@ -35,13 +35,14 @@ import org.apache.felix.scr.annotations.
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScriptHelper;
 import org.apache.sling.models.annotations.Filter;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.OSGiService;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallback;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -217,7 +218,7 @@ public class OSGiServiceInjector impleme
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         OSGiService annotation = element.getAnnotation(OSGiService.class);
         if (annotation != null) {
@@ -226,7 +227,7 @@ public class OSGiServiceInjector impleme
         return null;
     }
 
-    private static class OSGiServiceAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class OSGiServiceAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final OSGiService annotation;
 
@@ -235,6 +236,11 @@ public class OSGiServiceInjector impleme
         }
 
         @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
+        
+        @Override
         public Boolean isOptional() {
             return annotation.optional();
         }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/RequestAttributeInjector.java Thu Nov 20 10:18:08 2014
@@ -24,11 +24,12 @@ import javax.servlet.ServletRequest;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.RequestAttribute;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
@@ -53,7 +54,7 @@ public class RequestAttributeInjector im
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         RequestAttribute annotation = element.getAnnotation(RequestAttribute.class);
         if (annotation != null) {
@@ -62,7 +63,7 @@ public class RequestAttributeInjector im
         return null;
     }
 
-    private static class RequestAttributeAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class RequestAttributeAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final RequestAttribute annotation;
 
@@ -71,6 +72,11 @@ public class RequestAttributeInjector im
         }
 
         @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectonStrategy();
+        }
+        
+        @Override
         public Boolean isOptional() {
             return annotation.optional();
         }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java Thu Nov 20 10:18:08 2014
@@ -27,12 +27,13 @@ import org.apache.felix.scr.annotations.
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.models.annotations.Path;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.ResourcePath;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
@@ -83,7 +84,7 @@ public class ResourcePathInjector extend
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         ResourcePath annotation = element.getAnnotation(ResourcePath.class);
         if (annotation != null) {
@@ -92,7 +93,7 @@ public class ResourcePathInjector extend
         return null;
     }
 
-    private static class ResourcePathAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class ResourcePathAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final ResourcePath annotation;
 
@@ -114,6 +115,11 @@ public class ResourcePathInjector extend
         public Boolean isOptional() {
             return annotation.optional();
         }
+
+        @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
     }
 
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SelfInjector.java Thu Nov 20 10:18:08 2014
@@ -22,13 +22,14 @@ import java.lang.reflect.Type;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.Self;
 import org.apache.sling.models.impl.model.ConstructorParameter;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
@@ -64,7 +65,7 @@ public class SelfInjector implements Inj
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement element) {
         // check if the element has the expected annotation
         Self annotation = element.getAnnotation(Self.class);
         if (annotation != null) {
@@ -73,7 +74,7 @@ public class SelfInjector implements Inj
         return null;
     }
 
-    private static class SelfAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class SelfAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final Self annotation;
 
@@ -82,6 +83,11 @@ public class SelfInjector implements Inj
         }
 
         @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
+        
+        @Override
         public Boolean isOptional() {
             return annotation.optional();
         }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java Thu Nov 20 10:18:08 2014
@@ -31,12 +31,13 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.SlingObject;
 import org.apache.sling.models.spi.AcceptsNullName;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
-import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
 
@@ -124,7 +125,7 @@ public final class SlingObjectInjector i
     }
 
     @Override
-    public InjectAnnotationProcessor createAnnotationProcessor(final AnnotatedElement element) {
+    public InjectAnnotationProcessor2 createAnnotationProcessor(final AnnotatedElement element) {
         // check if the element has the expected annotation
         SlingObject annotation = element.getAnnotation(SlingObject.class);
         if (annotation != null) {
@@ -133,7 +134,7 @@ public final class SlingObjectInjector i
         return null;
     }
 
-    private static class SlingObjectAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class SlingObjectAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final SlingObject annotation;
 
@@ -142,9 +143,13 @@ public final class SlingObjectInjector i
         }
 
         @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
+        
+        @Override
         public Boolean isOptional() {
-            return this.annotation.optional();
+            return annotation.optional();
         }
     }
-
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java Thu Nov 20 10:18:08 2014
@@ -31,10 +31,11 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
-import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor2;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.osgi.framework.Constants;
@@ -139,7 +140,7 @@ public class ValueMapInjector extends Ab
         return null;
     }
 
-    private static class ValueAnnotationProcessor extends AbstractInjectAnnotationProcessor {
+    private static class ValueAnnotationProcessor extends AbstractInjectAnnotationProcessor2 {
 
         private final ValueMapValue annotation;
 
@@ -172,10 +173,15 @@ public class ValueMapInjector extends Ab
                 return null;
             }
         }
-
+        
         @Override
         public Boolean isOptional() {
             return annotation.optional();
         }
+
+        @Override
+        public InjectionStrategy getInjectionStrategy() {
+            return annotation.injectionStrategy();
+        }
     }
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/AbstractInjectableElement.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/AbstractInjectableElement.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/AbstractInjectableElement.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/AbstractInjectableElement.java Thu Nov 20 10:18:08 2014
@@ -25,13 +25,18 @@ import javax.inject.Named;
 
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.sling.models.annotations.Default;
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
+import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.annotations.Optional;
 import org.apache.sling.models.annotations.Required;
 import org.apache.sling.models.annotations.Source;
 import org.apache.sling.models.annotations.Via;
+import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy;
 import org.apache.sling.models.impl.ModelAdapterFactory;
 import org.apache.sling.models.impl.ReflectionUtil;
 import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,14 +52,16 @@ abstract class AbstractInjectableElement
     private final Object defaultValue;
     private final boolean isOptional;
     private final boolean isRequired;
+    private final DefaultInjectionStrategy injectionStrategy;
+    private final DefaultInjectionStrategy defaultInjectionStrategy;
     
     private static final Logger log = LoggerFactory.getLogger(ModelAdapterFactory.class);
     
     public AbstractInjectableElement(AnnotatedElement element, Type type, String defaultName,
-            StaticInjectAnnotationProcessorFactory[] processorFactories) {
+            StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
         this.element = element;
         this.type = type;
-        InjectAnnotationProcessor annotationProcessor = getAnnotationProcessor(element, processorFactories);
+        InjectAnnotationProcessor2 annotationProcessor = getAnnotationProcessor(element, processorFactories);
         this.name = getName(element, defaultName, annotationProcessor);
         this.source = getSource(element);
         this.via = getVia(element, annotationProcessor);
@@ -62,11 +69,13 @@ abstract class AbstractInjectableElement
         this.defaultValue = getDefaultValue(element, type, annotationProcessor);
         this.isOptional = getOptional(element, annotationProcessor);
         this.isRequired = getRequired(element, annotationProcessor);
+        this.injectionStrategy = getInjectionStrategy(element, annotationProcessor, defaultInjectionStrategy);
+        this.defaultInjectionStrategy = defaultInjectionStrategy;
     }
     
-    private static InjectAnnotationProcessor getAnnotationProcessor(AnnotatedElement element, StaticInjectAnnotationProcessorFactory[] processorFactories) {
+    private static InjectAnnotationProcessor2 getAnnotationProcessor(AnnotatedElement element, StaticInjectAnnotationProcessorFactory[] processorFactories) {
         for (StaticInjectAnnotationProcessorFactory processorFactory : processorFactories) {
-            InjectAnnotationProcessor annotationProcessor = processorFactory.createAnnotationProcessor(element);
+            InjectAnnotationProcessor2 annotationProcessor = processorFactory.createAnnotationProcessor(element);
             if (annotationProcessor != null) {
                 return annotationProcessor;
             }
@@ -74,7 +83,7 @@ abstract class AbstractInjectableElement
         return null;
     }
     
-    private static String getName(AnnotatedElement element, String defaultName, InjectAnnotationProcessor annotationProcessor) {
+    private static String getName(AnnotatedElement element, String defaultName, InjectAnnotationProcessor2 annotationProcessor) {
         String name = null;
         if (annotationProcessor != null) {
             name = annotationProcessor.getName();
@@ -99,7 +108,7 @@ abstract class AbstractInjectableElement
         return null;
     }
     
-    private static String getVia(AnnotatedElement element, InjectAnnotationProcessor annotationProcessor) {
+    private static String getVia(AnnotatedElement element, InjectAnnotationProcessor2 annotationProcessor) {
         String via = null;
         if (annotationProcessor != null) {
             via = annotationProcessor.getVia();
@@ -113,14 +122,14 @@ abstract class AbstractInjectableElement
         return via;
     }
 
-    private static boolean getHasDefaultValue(AnnotatedElement element, InjectAnnotationProcessor annotationProcessor) {
+    private static boolean getHasDefaultValue(AnnotatedElement element, InjectAnnotationProcessor2 annotationProcessor) {
         if (annotationProcessor != null) {
             return annotationProcessor.hasDefault();
         }
         return element.isAnnotationPresent(Default.class);
     }
 
-    private static Object getDefaultValue(AnnotatedElement element, Type type, InjectAnnotationProcessor annotationProcessor) {
+    private static Object getDefaultValue(AnnotatedElement element, Type type, InjectAnnotationProcessor2 annotationProcessor) {
         if (annotationProcessor != null && annotationProcessor.hasDefault()) {
             return annotationProcessor.getDefault();
         }
@@ -199,15 +208,27 @@ abstract class AbstractInjectableElement
         }
         return element.isAnnotationPresent(Optional.class);
     }
-
+    
     private static boolean getRequired(AnnotatedElement element, InjectAnnotationProcessor annotationProcessor) {
+        // do not evaluate the injector-specific annotation (those are only considered for optional)
+        // even setting optional=false will not make an attribute mandatory
+        return element.isAnnotationPresent(Required.class);
+    }
+    
+    private static DefaultInjectionStrategy getInjectionStrategy(AnnotatedElement element, InjectAnnotationProcessor annotationProcessor, DefaultInjectionStrategy defaultInjectionStrategy) {
         if (annotationProcessor != null) {
-            Boolean optional = annotationProcessor.isOptional();
-            if (optional != null) {
-                return !optional.booleanValue();
+            if (annotationProcessor instanceof InjectAnnotationProcessor2) {
+                switch (((InjectAnnotationProcessor2)annotationProcessor).getInjectionStrategy()) {
+                    case OPTIONAL:
+                        return DefaultInjectionStrategy.OPTIONAL;
+                    case REQUIRED:
+                        return DefaultInjectionStrategy.REQUIRED;
+                    case DEFAULT:
+                        break;
+                }
             }
         }
-        return element.isAnnotationPresent(Required.class);
+        return defaultInjectionStrategy;
     }
     
     @Override
@@ -246,13 +267,22 @@ abstract class AbstractInjectableElement
     }
 
     @Override
-    public boolean isOptional() {
-        return this.isOptional;
+    public boolean isOptional(InjectAnnotationProcessor annotationProcessor) {
+        DefaultInjectionStrategy injectionStrategy = this.injectionStrategy;
+        boolean isOptional = this.isOptional;
+        boolean isRequired = this.isRequired;
+        
+        // evaluate annotationProcessor (which depends on the adapter) 
+        if (annotationProcessor != null) {
+            isOptional = getOptional(getAnnotatedElement(), annotationProcessor);
+            isRequired = getRequired(getAnnotatedElement(), annotationProcessor);
+            injectionStrategy = getInjectionStrategy(element, annotationProcessor, defaultInjectionStrategy);
+        }
+        if (injectionStrategy == DefaultInjectionStrategy.REQUIRED) {
+            return isOptional;
+        } else {
+            return !isRequired;
+        }
     }
 
-    @Override
-    public boolean isRequired() {
-        return this.isRequired;
-    }
-    
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ConstructorParameter.java Thu Nov 20 10:18:08 2014
@@ -21,7 +21,9 @@ package org.apache.sling.models.impl.mod
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Type;
+import java.util.Arrays;
 
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 
 /**
@@ -37,8 +39,8 @@ public class ConstructorParameter extend
     private final int parameterIndex;
 
     public ConstructorParameter(Annotation[] annotations, Type parameterType, Type genericType, boolean isPrimitive,
-            int parameterIndex, StaticInjectAnnotationProcessorFactory[] processorFactories) {
-        super(new FakeAnnotatedElement(annotations, parameterIndex), genericType, null, processorFactories);
+            int parameterIndex, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
+        super(new FakeAnnotatedElement(annotations, parameterIndex), genericType, null, processorFactories, defaultInjectionStrategy);
         this.parameterType = parameterType;
         this.genericType = genericType;
         this.isPrimitive = isPrimitive;
@@ -106,6 +108,12 @@ public class ConstructorParameter extend
             return this.parameterIndex;
         }
 
+        @Override
+        public String toString() {
+            return "FakeAnnotatedElement [annotations=" + Arrays.toString(annotations) + ", parameterIndex="
+                    + parameterIndex + "]";
+        }
+
     }
    
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableElement.java Thu Nov 20 10:18:08 2014
@@ -21,6 +21,9 @@ package org.apache.sling.models.impl.mod
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Type;
 
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+
 public interface InjectableElement {
     
     /**
@@ -64,13 +67,8 @@ public interface InjectableElement {
     Object getDefaultValue();
     
     /**
-     * @return @Optional annotation is present
+     * @return {@code true} if the element is optional otherwise {@code false}
      */
-    boolean isOptional();
+    boolean isOptional(InjectAnnotationProcessor annotationProcessor);
 
-    /**
-     * @return @Required annotation is present
-     */
-    boolean isRequired();
-    
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableField.java Thu Nov 20 10:18:08 2014
@@ -20,6 +20,7 @@ package org.apache.sling.models.impl.mod
 
 import java.lang.reflect.Field;
 
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.impl.ReflectionUtil;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 
@@ -27,8 +28,8 @@ public class InjectableField extends Abs
     
     private final Field field;
     
-    public InjectableField(Field field, StaticInjectAnnotationProcessorFactory[] processorFactories) {
-        super(field, ReflectionUtil.mapPrimitiveClasses(field.getGenericType()), field.getName(), processorFactories);
+    public InjectableField(Field field, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
+        super(field, ReflectionUtil.mapPrimitiveClasses(field.getGenericType()), field.getName(), processorFactories, defaultInjectionStrategy);
         this.field = field;
     }
     

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/InjectableMethod.java Thu Nov 20 10:18:08 2014
@@ -21,6 +21,7 @@ package org.apache.sling.models.impl.mod
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.impl.ReflectionUtil;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 
@@ -29,8 +30,8 @@ public class InjectableMethod extends Ab
     private final Method method;
     private final Type genericReturnType;
 
-    public InjectableMethod(Method method, StaticInjectAnnotationProcessorFactory[] processorFactories) {
-        super(method, ReflectionUtil.mapPrimitiveClasses(method.getGenericReturnType()), getDefaultName(method), processorFactories);
+    public InjectableMethod(Method method, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
+        super(method, ReflectionUtil.mapPrimitiveClasses(method.getGenericReturnType()), getDefaultName(method), processorFactories, defaultInjectionStrategy);
         this.method = method;
         this.genericReturnType = method.getGenericReturnType();
     }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClass.java Thu Nov 20 10:18:08 2014
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.impl.ReflectionUtil;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
@@ -39,13 +40,19 @@ public class ModelClass<ModelType> {
     public ModelClass(Class<ModelType> type, StaticInjectAnnotationProcessorFactory[] processorFactories) {
         this.type = type;
         this.modelAnnotation = type.getAnnotation(Model.class);
-        this.constructors = getConstructors(type, processorFactories);
-        this.injectableFields = getInjectableFields(type, processorFactories);
-        this.injectableMethods = getInjectableMethods(type, processorFactories);
+        final DefaultInjectionStrategy defaultInjectionStrategy;
+        if (modelAnnotation == null) {
+            defaultInjectionStrategy = DefaultInjectionStrategy.REQUIRED;
+        } else {
+            defaultInjectionStrategy = modelAnnotation.defaultInjectionStrategy();
+        }
+        this.constructors = getConstructors(type, processorFactories, defaultInjectionStrategy);
+        this.injectableFields = getInjectableFields(type, processorFactories, defaultInjectionStrategy);
+        this.injectableMethods = getInjectableMethods(type, processorFactories, defaultInjectionStrategy);
     }
     
     @SuppressWarnings("unchecked")
-    private static ModelClassConstructor[] getConstructors(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories) {
+    private static ModelClassConstructor[] getConstructors(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
         if (type.isInterface()) {
             return new ModelClassConstructor[0];
         }
@@ -56,31 +63,31 @@ public class ModelClass<ModelType> {
 
         ModelClassConstructor[] array = new ModelClassConstructor[constructors.length];
         for (int i=0; i<array.length; i++) {
-            array[i] = new ModelClassConstructor(constructors[i], processorFactories);
+            array[i] = new ModelClassConstructor(constructors[i], processorFactories, defaultInjectionStrategy);
         }
         return array;
     }
 
-    private static InjectableField[] getInjectableFields(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories) {
+    private static InjectableField[] getInjectableFields(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
         if (type.isInterface()) {
             return new InjectableField[0];
         }
         List<Field> injectableFields = ReflectionUtil.collectInjectableFields(type);
         InjectableField[] array = new InjectableField[injectableFields.size()];
         for (int i=0; i<array.length; i++) {
-            array[i] = new InjectableField(injectableFields.get(i), processorFactories);
+            array[i] = new InjectableField(injectableFields.get(i), processorFactories, defaultInjectionStrategy);
         }
         return array;
     }
 
-    private static InjectableMethod[] getInjectableMethods(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories) {
+    private static InjectableMethod[] getInjectableMethods(Class<?> type, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
         if (!type.isInterface()) {
             return new InjectableMethod[0];
         }
         List<Method> injectableMethods = ReflectionUtil.collectInjectableMethods(type);
         InjectableMethod[] array = new InjectableMethod[injectableMethods.size()];
         for (int i=0; i<array.length; i++) {
-            array[i] = new InjectableMethod(injectableMethods.get(i), processorFactories);
+            array[i] = new InjectableMethod(injectableMethods.get(i), processorFactories, defaultInjectionStrategy);
         }
         return array;
     }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/model/ModelClassConstructor.java Thu Nov 20 10:18:08 2014
@@ -23,6 +23,8 @@ import java.lang.reflect.Type;
 
 import javax.inject.Inject;
 
+import org.apache.sling.models.annotations.DefaultInjectionStrategy;
+import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.impl.ReflectionUtil;
 import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
 
@@ -32,7 +34,7 @@ public class ModelClassConstructor<Model
     private final boolean hasInjectAnnotation;
     private final ConstructorParameter[] constructorParametersArray;
 
-    public ModelClassConstructor(Constructor<ModelType> constructor, StaticInjectAnnotationProcessorFactory[] processorFactories) {
+    public ModelClassConstructor(Constructor<ModelType> constructor, StaticInjectAnnotationProcessorFactory[] processorFactories, DefaultInjectionStrategy defaultInjectionStrategy) {
         this.constructor = constructor;
         this.hasInjectAnnotation = constructor.isAnnotationPresent(Inject.class);
 
@@ -44,7 +46,7 @@ public class ModelClassConstructor<Model
             boolean isPrimitive = (parameterTypes[i] != genericType);
             this.constructorParametersArray[i] = new ConstructorParameter(
                     constructor.getParameterAnnotations()[i], constructor.getParameterTypes()[i], genericType, isPrimitive, i,
-                    processorFactories);
+                    processorFactories, defaultInjectionStrategy);
         }
     }
 

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java?rev=1640710&r1=1640709&r2=1640710&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/InjectorSpecificAnnotationTest.java Thu Nov 20 10:18:08 2014
@@ -99,7 +99,7 @@ public class InjectorSpecificAnnotationT
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 1L));
         factory.bindInjectAnnotationProcessorFactory(valueMapInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 2L));
-        factory.bindInjectAnnotationProcessorFactory(childResourceInjector,
+        factory.bindInjectAnnotationProcessorFactory2(childResourceInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 3L));
         factory.bindStaticInjectAnnotationProcessorFactory(requestAttributeInjector,
                 Collections.<String, Object> singletonMap(Constants.SERVICE_ID, 4L));