From 7e98ba4aa3af339ce7ba286417568021cfb153e6 Mon Sep 17 00:00:00 2001 From: Roy Teeuwen Date: Fri, 13 Oct 2017 20:52:57 +0200 Subject: [PATCH] Added request attribute annotation. Can be used together with data-sly-use=${'com.cognifide.slice.TestModel' @ myAttribute='aValue'} to read out the attribute --- .../mapper/annotation/RequestAttribute.java | 56 +++++++++++++++++++ .../slice/mapper/annotation/package-info.java | 2 +- .../cognifide/slice/mapper/MapperBuilder.java | 12 ++-- .../processor/RequestAttributeProcessor.java | 55 ++++++++++++++++++ .../impl/AnnotatedFieldMapperStrategy.java | 10 ++-- 5 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 slice-mapper-api/src/main/java/com/cognifide/slice/mapper/annotation/RequestAttribute.java create mode 100644 slice-mapper/src/main/java/com/cognifide/slice/mapper/impl/processor/RequestAttributeProcessor.java 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..9300d06c --- /dev/null +++ b/slice-mapper/src/main/java/com/cognifide/slice/mapper/impl/processor/RequestAttributeProcessor.java @@ -0,0 +1,55 @@ +/*- + * #%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.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.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ValueMap; + +import java.lang.reflect.Field; + +public class RequestAttributeProcessor implements FieldProcessor { + + @Inject + private SlingHttpServletRequest slingRequest; + + @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) { + String attributeName = getAttributeName(field); + return slingRequest.getAttribute(attributeName); + } + + 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)); } }