SLING-3499 - adding support for custom annotation per injector (thanks Konrad Windszus for the patch!)

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1600469 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java b/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java
new file mode 100644
index 0000000..bce2cc2
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/annotations/injectorspecific/ChildResource.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.sling.models.annotations.Source;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
+
+/**
+ * Annotation to be used on either methods or fields to let Sling Models inject a child resource
+ *
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+@InjectAnnotation
+@Source("child-resources")
+public @interface ChildResource {
+    /**
+     * Specifies the name of the child resource.
+     * If empty or not set, then the name is derived from the method or field.
+     */
+    public String name() default "";
+
+    /**
+     * If set to true, the model can be instantiated even if there is no child resource
+     * with that name available.
+     * Default = false.
+     */
+    public boolean optional() default false;
+
+    /**
+     * If set, then the child resource can be obtained via a projection of the given
+     * property of the adaptable.
+     */
+    public String via() default "";
+}
diff --git a/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java b/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java
new file mode 100644
index 0000000..92b31bd
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/annotations/injectorspecific/OSGiService.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.sling.models.annotations.Source;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
+
+/**
+ * Annotation to be used on either methods or fields to let Sling Models inject an OSGi service
+ *
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+@InjectAnnotation
+@Source("osgi-services")
+public @interface OSGiService {
+    /**
+     * specifies the RFC 1960-based filter string, which is evaluated when retrieving the service. If empty string or left out, then no filtering is being performed.
+     * 
+     * @see "Core Specification, section 5.5, for a description of the filter string
+     * @see <a href="http://www.ietf.org/rfc/rfc1960.txt">RFC 1960</a>
+     */
+    public String filter() default "";
+
+    /**
+     * If set to true, the model can be instantiated even if there is no OSGi service implementation available. Default
+     * = false.
+     */
+    public boolean optional() default false;
+}
diff --git a/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java b/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java
new file mode 100644
index 0000000..6b4d1a6
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/annotations/injectorspecific/RequestAttribute.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.sling.models.annotations.Source;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
+
+/**
+ * Annotation to be used on either methods or fields to let Sling Models inject a
+ * request attribute.
+ *
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+@InjectAnnotation
+@Source("request-attributes")
+public @interface RequestAttribute {
+
+    /**
+     * Specifies the name of the request attribute. If empty or not set, then the name
+     * is derived from the method or field.
+     */
+    public String name() default "";
+
+    /**
+     * If set to true, the model can be instantiated even if there is no request attribute
+     * with the given name found.
+     * Default = false.
+     */
+    public boolean optional() default false;
+}
diff --git a/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java b/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java
new file mode 100644
index 0000000..b08cece
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/annotations/injectorspecific/ScriptVariable.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.sling.models.annotations.Source;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
+
+/**
+ * Annotation to be used on either methods or fields to let Sling Models inject a
+ * script variable (from the {@link org.apache.sling.api.scripting.SlingBindings})
+ *
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+@InjectAnnotation
+@Source("script-bindings")
+public @interface ScriptVariable {
+    /**
+     * Specifies the name of the script variable.
+     * If empty or not set, then the name is derived from the method or field.
+     */
+    public String name() default "";
+
+    /**
+     * If set to true, the model can be instantiated even if there is no
+     * scripting value with the specified name.
+     * Default = false.
+     */
+    public boolean optional() default false;
+}
diff --git a/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java b/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java
new file mode 100644
index 0000000..bbdaf80
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/annotations/injectorspecific/ValueMapValue.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.apache.sling.models.annotations.Source;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotation;
+
+/**
+ * Annotation to be used on either methods or fields to let Sling Models inject a value from the ValueMap of the current resource.
+ *
+ */
+@Target({ METHOD, FIELD })
+@Retention(RUNTIME)
+@InjectAnnotation
+@Source("valuemap")
+public @interface ValueMapValue {
+    /**
+     * Specifies the name of the value from the value map to take.
+     * If empty, then the name is derived from the method or field.
+     */
+    String name() default "";
+
+    /**
+     * 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
+     */
+    boolean optional() default false;
+
+    /**
+     * If set, then the child resource can be obtained via a projection of the given
+     * property of the adaptable.
+     */
+    String via() default "";
+}
diff --git a/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java b/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java
new file mode 100644
index 0000000..da4fcdb
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/annotations/injectorspecific/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@Version("1.0.0")
+package org.apache.sling.models.annotations.injectorspecific;
+
+import aQute.bnd.annotation.Version;
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java b/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java
new file mode 100644
index 0000000..9354463
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/spi/injectorspecific/AbstractInjectAnnotationProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Default implementation of ModelAnnotationProcessor.
+ *
+ */
+public class AbstractInjectAnnotationProcessor implements InjectAnnotationProcessor {
+
+    public String getName() {
+        return null;
+    }
+
+    public String getVia() {
+        return null;
+    }
+
+    public boolean hasDefault() {
+        return false;
+    }
+
+    public Object getDefault() {
+        return null;
+    }
+
+    public Boolean isOptional() {
+        return null;
+    }
+}
diff --git a/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotation.java b/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotation.java
new file mode 100644
index 0000000..8f7564c
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotation.java
@@ -0,0 +1,34 @@
+/*
+ * 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 static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Declares an annotation as a custom inject annotation.
+ */
+@Target({ ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Documented
+public @interface InjectAnnotation {
+
+}
diff --git a/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java b/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java
new file mode 100644
index 0000000..c133f38
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessor.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+/**
+ * Processor for injector-specific annotations.
+ */
+public interface 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 hasDefaultValue()} 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 the value to be used for the default or null, in
+     *         which case the standard annotation should be used.
+     */
+    Boolean isOptional();
+
+}
diff --git a/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java b/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java
new file mode 100644
index 0000000..d7ef954
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/spi/injectorspecific/InjectAnnotationProcessorFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import org.apache.sling.models.spi.Injector;
+
+public interface InjectAnnotationProcessorFactory extends Injector {
+    /**
+     * 
+     * @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
+     */
+    InjectAnnotationProcessor createAnnotationProcessor(Object adaptable, AnnotatedElement element);
+}
diff --git a/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java b/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java
new file mode 100644
index 0000000..e9d341c
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/spi/injectorspecific/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+@Version("1.0.0")
+package org.apache.sling.models.spi.injectorspecific;
+
+import aQute.bnd.annotation.Version;
\ No newline at end of file