RequestHeaderConfigurationOverrideProvider.java

  1. /*
  2.  * #%L
  3.  * wcm.io
  4.  * %%
  5.  * Copyright (C) 2016 wcm.io
  6.  * %%
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *      http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  * #L%
  19.  */
  20. package io.wcm.caconfig.extensions.override.impl;

  21. import java.util.ArrayList;
  22. import java.util.Collection;
  23. import java.util.Collections;
  24. import java.util.Enumeration;
  25. import java.util.List;

  26. import org.apache.sling.api.SlingHttpServletRequest;
  27. import org.apache.sling.caconfig.spi.ConfigurationOverrideProvider;
  28. import org.jetbrains.annotations.NotNull;
  29. import org.osgi.service.component.annotations.Activate;
  30. import org.osgi.service.component.annotations.Component;
  31. import org.osgi.service.component.annotations.Reference;
  32. import org.osgi.service.metatype.annotations.AttributeDefinition;
  33. import org.osgi.service.metatype.annotations.Designate;
  34. import org.osgi.service.metatype.annotations.ObjectClassDefinition;
  35. import org.slf4j.Logger;
  36. import org.slf4j.LoggerFactory;

  37. import io.wcm.sling.commons.request.RequestContext;

  38. /**
  39.  * Provides configuration override strings from current request header.
  40.  */
  41. @Component(immediate = true, service = ConfigurationOverrideProvider.class)
  42. @Designate(ocd = RequestHeaderConfigurationOverrideProvider.Config.class)
  43. public final class RequestHeaderConfigurationOverrideProvider implements ConfigurationOverrideProvider {

  44.   @ObjectClassDefinition(name = "wcm.io Context-Aware Configuration Override Provider: Request Header",
  45.       description = "Allows to define configuration property default values or overrides from inconming request headers.")
  46.   @interface Config {

  47.     @AttributeDefinition(name = "Enabled",
  48.         description = "Enable this override provider.")
  49.     boolean enabled() default false;

  50.     @AttributeDefinition(name = "Header Name",
  51.         description = "Name of the request header to get override strings from. Can be present multiple times.")
  52.     String headerName() default "wcmio.caconfig.override";

  53.     @AttributeDefinition(name = "Service Ranking",
  54.         description = "Priority of configuration override providers (higher = higher priority).")
  55.     int service_ranking() default 300;

  56.   }

  57.   private static final Logger log = LoggerFactory.getLogger(RequestHeaderConfigurationOverrideProvider.class);

  58.   private Config config;

  59.   @Reference
  60.   private RequestContext requestContext;

  61.   @Override
  62.   public @NotNull Collection<String> getOverrideStrings() {
  63.     if (config.enabled()) {
  64.       if (requestContext != null) {
  65.         SlingHttpServletRequest request = requestContext.getThreadRequest();
  66.         if (request != null) {
  67.           return buildMapFromHeaders(request);
  68.         }
  69.       }
  70.       else {
  71.         log.warn("RequestContext service not running - unable to inspect current request.");
  72.       }
  73.     }
  74.     return Collections.emptyList();
  75.   }

  76.   private Collection<String> buildMapFromHeaders(SlingHttpServletRequest request) {
  77.     List<String> result = new ArrayList<>();
  78.     Enumeration<String> headerValues = request.getHeaders(config.headerName());
  79.     while (headerValues.hasMoreElements()) {
  80.       result.add(headerValues.nextElement());
  81.     }
  82.     return result;
  83.   }

  84.   @Activate
  85.   void activate(Config value) {
  86.     this.config = value;
  87.   }

  88. }