Skip to main content

@ExternalizedValueMapValue

Interface

@Target({FIELD})
@Retention(RUNTIME)
@InjectAnnotation
@Source(ExternalizedValueMapValue.ANNOTATION_NAME)
public @interface ExternalizedValueMapValue {

String ANNOTATION_NAME = "externalized";

/**
* Represents the name
*
* @return
*/
String name() default StringUtils.EMPTY;

@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;
}

Implementation

package com.jti.cep.inject.impl;

import com.jti.cep.externalizer.ExternalizerService;
import com.jti.cep.inject.annotations.ExternalizedValueMapValue;
import com.jti.cep.inject.util.InjectorUtil;
import com.jti.cep.inject.util.ReflectionUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
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.AbstractInjectAnnotationProcessor2;
import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor2;
import org.apache.sling.models.spi.injectorspecific.StaticInjectAnnotationProcessorFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Type;
import java.util.Optional;

/**
* ExternalizedValueMapValueInjector
* <p>
* Externalizes properties in the sling model
* </p>
*
* @author raaijmak@adobe.com
* @since 2019-09-19
*/
@Component(immediate = true, service = {Injector.class, StaticInjectAnnotationProcessorFactory.class})
public class ExternalizedValueMapValueInjector implements Injector, StaticInjectAnnotationProcessorFactory {

@Reference
private ExternalizerService externalizerService;

@Override
public String getName() {
return ExternalizedValueMapValue.ANNOTATION_NAME;
}

@Override
public Object getValue(Object adaptable, String name, Type type, AnnotatedElement annotatedElement, DisposalCallbackRegistry disposalCallbackRegistry) {

if (
ReflectionUtil.isAssignableFrom(type, String.class) &&
annotatedElement.isAnnotationPresent(ExternalizedValueMapValue.class) &&
adaptable instanceof SlingHttpServletRequest
) {
SlingHttpServletRequest request = (SlingHttpServletRequest) adaptable;
ExternalizedValueMapValue annotation = annotatedElement.getAnnotation(ExternalizedValueMapValue.class);

String key = StringUtils.defaultIfBlank(annotation.name(), name);

Resource resource = InjectorUtil.getResourceFromAdaptable(adaptable);
String rawValue = resource.getValueMap().get(key, String.class);

if (StringUtils.isNotBlank(rawValue)) {
return externalizerService.externalizeForSPARouter(request, rawValue);
}
}

return null;
}

@Override
public InjectAnnotationProcessor2 createAnnotationProcessor(AnnotatedElement annotatedElement) {
return Optional.ofNullable(annotatedElement.getAnnotation(ExternalizedValueMapValue.class)).map(ExternalizedValueMapValueInjectorProcessor::new).orElse(null);
}

private static class ExternalizedValueMapValueInjectorProcessor extends AbstractInjectAnnotationProcessor2 {

private final ExternalizedValueMapValue annotation;

public ExternalizedValueMapValueInjectorProcessor(ExternalizedValueMapValue annotation) {
this.annotation = annotation;
}

@Override
public InjectionStrategy getInjectionStrategy() {
return annotation.injectionStrategy();
}

@Override
public Boolean isOptional() {
return annotation.optional();
}
}
}

ExternalizerService.externalize

@Override
public String externalize(SlingHttpServletRequest request, String path) {
if (StringUtils.isBlank(path)) {
return null;
}
return request.getResourceResolver().map(path);
}