FELIX-1056 : Add annoations for Sling servlet components. Apply patch from Stefan Seifert.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@776199 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr-annotations/src/main/java/org/apache/felix/scr/annotations/Property.java b/scr-annotations/src/main/java/org/apache/felix/scr/annotations/Property.java
index c4a7910..62630ad 100644
--- a/scr-annotations/src/main/java/org/apache/felix/scr/annotations/Property.java
+++ b/scr-annotations/src/main/java/org/apache/felix/scr/annotations/Property.java
@@ -63,63 +63,63 @@
* This attribute should not be used in combination with any of the other
* value attributes.
*/
- String[] value() default "";
+ String[] value() default {};
/**
* The long value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- long[] longValue() default 0;
+ long[] longValue() default {};
/**
* The double value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes.
*/
- double[] doubleValue() default 0.0;
+ double[] doubleValue() default {};
/**
* The float value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- float[] floatValue() default 0;
+ float[] floatValue() default {};
/**
* The int value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- int[] intValue() default 0;
+ int[] intValue() default {};
/**
* The byte value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- byte[] byteValue() default 0;
+ byte[] byteValue() default {};
/**
* The char value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- char[] charValue() default '\0';
+ char[] charValue() default {};
/**
* The bool value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- boolean[] boolValue() default false;
+ boolean[] boolValue() default {};
/**
* The short value(s) of the property.
* This attribute should not be used in combination with any of the other
* value attributes or the type attribute.
*/
- short[] shortValue() default 0;
+ short[] shortValue() default {};
/**
* Defines the cardinality of the property and its collection type. If the
diff --git a/scr-annotations/src/main/java/org/apache/felix/scr/annotations/sling/SlingServlet.java b/scr-annotations/src/main/java/org/apache/felix/scr/annotations/sling/SlingServlet.java
new file mode 100644
index 0000000..67f7de0
--- /dev/null
+++ b/scr-annotations/src/main/java/org/apache/felix/scr/annotations/sling/SlingServlet.java
@@ -0,0 +1,112 @@
+/*
+ * 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.felix.scr.annotations.sling;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks servlet classes as felix SCR component, and allows to configure sling
+ * resource resolving mapping.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+@Documented
+public @interface SlingServlet {
+
+ /**
+ * Whether to generate a default SCR component tag with "immediate=true". If
+ * set to false, a {@link org.apache.felix.scr.annotations.Component}
+ * annotation can be added manually with defined whatever configuration
+ * needed.
+ */
+ boolean generateComponent() default true;
+
+ /**
+ * Whether to generate a default SCR service tag with with
+ * "interface=javax.servlet.Servlet". If set to false, a
+ * {@link org.apache.felix.scr.annotations.Service} annotation can be added
+ * manually with defined whatever configuration needed.
+ */
+ boolean generateService() default true;
+
+ /**
+ * The name of the service registration property of a Servlet registered as
+ * a service providing the absolute paths under which the servlet is
+ * accessible as a Resource (value is "sling.servlet.paths")
+ * <p>
+ * The type of this property is a String or String[] (array of strings)
+ * denoting the resource types.
+ */
+ String[] paths() default {};
+
+ /**
+ * The name of the service registration property of a Servlet registered as
+ * a service containing the resource type(s) supported by the servlet (value
+ * is "sling.servlet.resourceTypes").
+ * <p>
+ * The type of this property is a String or String[] (array of strings)
+ * denoting the resource types. This property is ignored if the
+ * {@link #paths} property is set. Otherwise this property must be set or
+ * the servlet is ignored.
+ */
+ String[] resourceTypes() default {};
+
+ /**
+ * The name of the service registration property of a Servlet registered as
+ * a service containing the request URL selectors supported by the servlet
+ * (value is "sling.servlet.selectors"). The selectors must be configured as
+ * they would be specified in the URL that is as a list of dot-separated
+ * strings such as <em>print.a4</em>.
+ * <p>
+ * The type of this property is a String or String[] (array of strings)
+ * denoting the resource types. This property is ignored if the
+ * {@link #paths} property is set. Otherwise this property is optional and
+ * ignored if not set.
+ */
+ String[] selectors() default {};
+
+ /**
+ * The name of the service registration property of a Servlet registered as
+ * a service containing the request URL extensions supported by the servlet
+ * for GET requests (value is "sling.servlet.extensions").
+ * <p>
+ * The type of this property is a String or String[] (array of strings)
+ * denoting the resource types. This property is ignored if the
+ * {@link #paths} property is set. Otherwise this property or the
+ * {@link #methods} is optional and ignored if not set.
+ */
+ String[] extensions() default {};
+
+ /**
+ * The name of the service registration property of a Servlet registered as
+ * a service containing the request methods supported by the servlet (value
+ * is "sling.servlet.methods").
+ * <p>
+ * The type of this property is a String or String[] (array of strings)
+ * denoting the resource types. This property is ignored if the
+ * {@link #paths} property is set. Otherwise this property or the
+ * {@link #extensions} is optional and ignored if not set.
+ */
+ String[] methods() default {};
+
+}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
index 6e88d51..d9068f0 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
@@ -24,6 +24,7 @@
import org.apache.felix.scrplugin.tags.JavaField;
import org.apache.felix.scrplugin.tags.JavaTag;
import org.apache.felix.scrplugin.tags.annotation.defaulttag.DefaultAnnotationTagProvider;
+import org.apache.felix.scrplugin.tags.annotation.sling.SlingAnnotationTagProvider;
import org.apache.maven.plugin.MojoFailureException;
import com.thoughtworks.qdox.model.Annotation;
@@ -52,6 +53,7 @@
// always add provider supporting built-in SCR default properties
annotationTagProviders.add(new DefaultAnnotationTagProvider());
+ annotationTagProviders.add(new SlingAnnotationTagProvider());
// add custom providers defined in pom
for (int i = 0; i < annotationTagProviderClasses.length; i++) {
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingAnnotationTagProvider.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingAnnotationTagProvider.java
new file mode 100644
index 0000000..6ecc1fa
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingAnnotationTagProvider.java
@@ -0,0 +1,90 @@
+/*
+ * 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.felix.scrplugin.tags.annotation.sling;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.scr.annotations.sling.SlingServlet;
+import org.apache.felix.scrplugin.tags.JavaField;
+import org.apache.felix.scrplugin.tags.JavaTag;
+import org.apache.felix.scrplugin.tags.annotation.AnnotationJavaClassDescription;
+import org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider;
+import org.apache.felix.scrplugin.tags.annotation.defaulttag.Util;
+
+/**
+ * Annotation tag provider for sling-specific SCR annotations.
+ */
+public class SlingAnnotationTagProvider implements AnnotationTagProvider {
+
+ public List<JavaTag> getTags(com.thoughtworks.qdox.model.Annotation annotation,
+ AnnotationJavaClassDescription description, JavaField field) {
+ List<JavaTag> tags = new ArrayList<JavaTag>();
+
+ if (annotation.getType().getJavaClass().getFullyQualifiedName().equals(SlingServlet.class.getName())) {
+
+ // generate @Component tag if required
+ boolean generateComponent = Util.getBooleanValue(annotation, "generateComponent", SlingServlet.class);
+ if (generateComponent) {
+ tags.add(new SlingServletComponentTag(description));
+ }
+
+ // generate @Service tag if required
+ boolean generateService = Util.getBooleanValue(annotation, "generateService", SlingServlet.class);
+ if (generateService) {
+ tags.add(new SlingServletServiceTag(description));
+ }
+
+ // generate @Property tags
+ // {@see org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_PATHS}
+ String[] paths = Util.getStringValues(annotation, description, "paths");
+ if (paths != null && paths.length != 0) {
+ tags.add(new SlingServletPropertyTag("sling.servlet.paths", paths, description));
+ }
+
+ // {@see org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES}
+ String[] resourceTypes = Util.getStringValues(annotation, description, "resourceTypes");
+ if (resourceTypes != null && resourceTypes.length != 0) {
+ tags.add(new SlingServletPropertyTag("sling.servlet.resourceTypes", resourceTypes, description));
+ }
+
+ // {@see org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_SELECTORS}
+ String[] selectors = Util.getStringValues(annotation, description, "selectors");
+ if (selectors != null && selectors.length != 0) {
+ tags.add(new SlingServletPropertyTag("sling.servlet.selectors", selectors, description));
+ }
+
+ // {@see org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_EXTENSIONS}
+ String[] extensions = Util.getStringValues(annotation, description, "extensions");
+ if (extensions != null && extensions.length != 0) {
+ tags.add(new SlingServletPropertyTag("sling.servlet.extensions", extensions, description));
+ }
+
+ // {@see org.apache.sling.servlets.resolver.internal.ServletResolverConstants.SLING_SERVLET_METHODS}
+ String[] methods = Util.getStringValues(annotation, description, "methods");
+ if (methods != null && methods.length != 0) {
+ tags.add(new SlingServletPropertyTag("sling.servlet.methods", methods, description));
+ }
+
+ }
+
+ return tags;
+ }
+
+}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletComponentTag.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletComponentTag.java
new file mode 100644
index 0000000..e002f0c
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletComponentTag.java
@@ -0,0 +1,54 @@
+/*
+ * 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.felix.scrplugin.tags.annotation.sling;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.scrplugin.Constants;
+import org.apache.felix.scrplugin.tags.JavaClassDescription;
+import org.apache.felix.scrplugin.tags.annotation.defaulttag.AbstractTag;
+
+/**
+ * Description of a java tag for components.
+ */
+public class SlingServletComponentTag extends AbstractTag {
+
+ /**
+ * @param desc Description
+ */
+ public SlingServletComponentTag(JavaClassDescription desc) {
+ super(desc, null);
+ }
+
+ @Override
+ public String getName() {
+ return Constants.COMPONENT;
+ }
+
+ @Override
+ public Map<String, String> getNamedParameterMap() {
+ final Map<String, String> map = new HashMap<String, String>();
+
+ map.put(Constants.COMPONENT_IMMEDIATE, String.valueOf(true));
+
+ return map;
+ }
+
+}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletPropertyTag.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletPropertyTag.java
new file mode 100644
index 0000000..ea97083
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletPropertyTag.java
@@ -0,0 +1,75 @@
+/*
+ * 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.felix.scrplugin.tags.annotation.sling;
+
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.felix.scrplugin.Constants;
+import org.apache.felix.scrplugin.tags.JavaClassDescription;
+import org.apache.felix.scrplugin.tags.annotation.defaulttag.AbstractTag;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Description of a java tag for components.
+ */
+public class SlingServletPropertyTag extends AbstractTag {
+
+ protected final String name;
+ protected final String[] values;
+
+ /**
+ * @param name Property name
+ * @param values Property values
+ * @param desc Description
+ */
+ public SlingServletPropertyTag(String name, String[] values, JavaClassDescription desc) {
+ super(desc, null);
+ this.name = name;
+ this.values = values;
+ }
+
+ @Override
+ public String getName() {
+ return Constants.PROPERTY;
+ }
+
+ @Override
+ public Map<String, String> getNamedParameterMap() {
+ final SortedMap<String, String> map = new TreeMap<String, String>();
+
+ map.put(Constants.PROPERTY_NAME, this.name);
+
+ if (this.values == null || this.values.length == 0) {
+ map.put(Constants.PROPERTY_VALUE, "");
+ } else if (this.values.length == 1) {
+ map.put(Constants.PROPERTY_VALUE, this.values[0]);
+ } else {
+ for (int i = 0; i < this.values.length; i++) {
+ // generate index number with trailing zeros to ensure correct sort order in map
+ String index = StringUtils.leftPad(Integer.toString(i), 10, "0");
+ map.put(Constants.PROPERTY_MULTIVALUE_PREFIX + '.' + index, this.values[i]);
+ }
+ }
+
+ return map;
+ }
+
+}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletServiceTag.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletServiceTag.java
new file mode 100644
index 0000000..bf71dc4
--- /dev/null
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/tags/annotation/sling/SlingServletServiceTag.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.felix.scrplugin.tags.annotation.sling;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+
+import org.apache.felix.scrplugin.Constants;
+import org.apache.felix.scrplugin.tags.JavaClassDescription;
+import org.apache.felix.scrplugin.tags.annotation.defaulttag.AbstractTag;
+
+/**
+ * Description of a java tag for components.
+ */
+public class SlingServletServiceTag extends AbstractTag {
+
+ /**
+ * @param desc Description
+ */
+ public SlingServletServiceTag(JavaClassDescription desc) {
+ super(desc, null);
+ }
+
+ @Override
+ public String getName() {
+ return Constants.SERVICE;
+ }
+
+ @Override
+ public Map<String, String> getNamedParameterMap() {
+ final Map<String, String> map = new HashMap<String, String>();
+
+ map.put(Constants.SERVICE_INTERFACE, Servlet.class.getName());
+
+ return map;
+ }
+
+}