diff --git a/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/RequestAttribute.java b/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/RequestAttribute.java new file mode 100644 index 00000000..bd0110c0 --- /dev/null +++ b/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/RequestAttribute.java @@ -0,0 +1,56 @@ +/*- + * #%L + * Slice - Mapper API + * %% + * Copyright (C) 2012 Cognifide Limited + * %% + * Licensed 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. + * #L% + */ +package com.cognifide.slice.mapper.annotation; + +import java.lang.annotation.*; + +/** + * Indicates that a given field should be mapped from a request attribute . The + * name of the request attribute is indicated by the name of the field or value of {@link RequestAttribute} (if + * specified). + * Example: + * + *
+ * {@literal @}SliceResource
+ * public class ExampleModel {
+ *
+ * {@literal @}RequestAttribute
+ * private String myAttribute;
+ *
+ * {@literal @}RequestAttribute("second-attribute")
+ * private Boolean secondAttribute;
+ * }
+ *
+ *
+ * @author roy.teeuwen
+ *
+ */
+@Documented
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequestAttribute {
+
+ /**
+ * Custom request attribute name. If empty, property name is read from field's name.
+ *
+ * @return value
+ */
+ String value() default "";
+}
diff --git a/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/package-info.java b/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/package-info.java
index 786bb96b..40e27dec 100644
--- a/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/package-info.java
+++ b/slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/package-info.java
@@ -17,7 +17,7 @@
* limitations under the License.
* #L%
*/
-@Version("4.3.0")
+@Version("4.4.0")
package com.cognifide.slice.mapper.annotation;
import aQute.bnd.annotation.Version;
diff --git a/slice-mapper/src/main/java/com/cognifide/slice/mapper/MapperBuilder.java b/slice-mapper/src/main/java/com/cognifide/slice/mapper/MapperBuilder.java
index 503da0b2..ad77dc15 100644
--- a/slice-mapper/src/main/java/com/cognifide/slice/mapper/MapperBuilder.java
+++ b/slice-mapper/src/main/java/com/cognifide/slice/mapper/MapperBuilder.java
@@ -30,13 +30,7 @@
import com.cognifide.slice.mapper.api.processor.PriorityFieldProcessor;
import com.cognifide.slice.mapper.impl.CustomProcessorsCollector;
import com.cognifide.slice.mapper.impl.postprocessor.EscapeValuePostProcessor;
-import com.cognifide.slice.mapper.impl.processor.BooleanFieldProcessor;
-import com.cognifide.slice.mapper.impl.processor.ChildrenFieldProcessor;
-import com.cognifide.slice.mapper.impl.processor.DefaultFieldProcessor;
-import com.cognifide.slice.mapper.impl.processor.EnumFieldProcessor;
-import com.cognifide.slice.mapper.impl.processor.ListFieldProcessor;
-import com.cognifide.slice.mapper.impl.processor.SliceReferenceFieldProcessor;
-import com.cognifide.slice.mapper.impl.processor.SliceResourceFieldProcessor;
+import com.cognifide.slice.mapper.impl.processor.*;
import com.google.inject.Inject;
import com.google.inject.Module;
@@ -65,6 +59,9 @@ public final class MapperBuilder {
@Inject
private ChildrenFieldProcessor childrenFieldProcessor;
+ @Inject
+ private RequestAttributeProcessor requestAttributeProcessor;
+
@Inject
private CustomProcessorsCollector customProcessorsCollector;
@@ -120,6 +117,7 @@ public MapperBuilder addSliceProcessors() {
processors.add(sliceReferenceFieldProcessor); // @SliceReference
processors.add(sliceResourceFieldProcessor); // @SliceResource
processors.add(childrenFieldProcessor); // child models @Children
+ processors.add(requestAttributeProcessor); // @RequestAttribute
processors.add(new ListFieldProcessor()); // Subclasses of Collection> and arrays
processors.add(new BooleanFieldProcessor()); // booleans
processors.add(new EnumFieldProcessor()); // enums
diff --git a/slice-mapper/src/main/java/com/cognifide/slice/mapper/impl/processor/RequestAttributeProcessor.java b/slice-mapper/src/main/java/com/cognifide/slice/mapper/impl/processor/RequestAttributeProcessor.java
new file mode 100644
index 00000000..00e5c2ec
--- /dev/null
+++ b/slice-mapper/src/main/java/com/cognifide/slice/mapper/impl/processor/RequestAttributeProcessor.java
@@ -0,0 +1,60 @@
+/*-
+ * #%L
+ * Slice - Mapper
+ * %%
+ * Copyright (C) 2012 Cognifide Limited
+ * %%
+ * Licensed 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.
+ * #L%
+ */
+package com.cognifide.slice.mapper.impl.processor;
+
+import com.cognifide.slice.api.qualifier.Nullable;
+import com.cognifide.slice.mapper.annotation.RequestAttribute;
+import com.cognifide.slice.mapper.api.processor.FieldProcessor;
+import com.google.inject.Inject;
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+
+import javax.servlet.ServletRequest;
+import java.lang.reflect.Field;
+
+public class RequestAttributeProcessor implements FieldProcessor {
+
+ @Inject
+ @Nullable
+ private ServletRequest servletRequest;
+
+ @Override
+ public boolean accepts(final Resource resource, final Field field) {
+ return field.isAnnotationPresent(RequestAttribute.class);
+ }
+
+ @Override
+ public Object mapResourceToField(Resource resource, ValueMap valueMap, Field field, String propertyName) {
+ if (servletRequest != null) {
+ String attributeName = getAttributeName(field);
+ return servletRequest.getAttribute(attributeName);
+ }
+ return null;
+ }
+
+ private String getAttributeName(Field field) {
+ final RequestAttribute annotation = field.getAnnotation(RequestAttribute.class);
+ if ((annotation != null) && StringUtils.isNotBlank(annotation.value())) {
+ return annotation.value();
+ }
+ return field.getName();
+ }
+}
diff --git a/slice-mapper/src/main/java/com/cognifide/slice/mapper/strategy/impl/AnnotatedFieldMapperStrategy.java b/slice-mapper/src/main/java/com/cognifide/slice/mapper/strategy/impl/AnnotatedFieldMapperStrategy.java
index 54777e34..3fab787d 100644
--- a/slice-mapper/src/main/java/com/cognifide/slice/mapper/strategy/impl/AnnotatedFieldMapperStrategy.java
+++ b/slice-mapper/src/main/java/com/cognifide/slice/mapper/strategy/impl/AnnotatedFieldMapperStrategy.java
@@ -23,18 +23,20 @@
import java.lang.reflect.Field;
import com.cognifide.slice.mapper.annotation.JcrProperty;
+import com.cognifide.slice.mapper.annotation.RequestAttribute;
import com.cognifide.slice.mapper.strategy.MapperStrategy;
/**
- * AnnotatedFieldMapperStrategy defines a strategy where only fields annotated by {@link JcrProperty} are
- * mapped.
- *
+ * AnnotatedFieldMapperStrategy defines a strategy where only fields annotated by
+ * {@link JcrProperty}, {@link RequestAttribute} are mapped.
+ *
*/
public class AnnotatedFieldMapperStrategy implements MapperStrategy {
@Override
public boolean shouldFieldBeMapped(Field field) {
- return field.isAnnotationPresent(JcrProperty.class);
+ return (field.isAnnotationPresent(JcrProperty.class)
+ || field.isAnnotationPresent(RequestAttribute.class));
}
}