diff --git a/common/src/main/java/org/keycloak/common/Profile.java b/common/src/main/java/org/keycloak/common/Profile.java index e805836f77..a07c56668c 100755 --- a/common/src/main/java/org/keycloak/common/Profile.java +++ b/common/src/main/java/org/keycloak/common/Profile.java @@ -215,7 +215,7 @@ public class Profile { private static final Logger logger = Logger.getLogger(Profile.class); - private static Profile CURRENT; + private static volatile Profile CURRENT; private final ProfileName profileName; diff --git a/docs/guides/templates/guide.adoc b/docs/guides/templates/guide.adoc index 10481797d9..24c8663c10 100644 --- a/docs/guides/templates/guide.adoc +++ b/docs/guides/templates/guide.adoc @@ -1,6 +1,6 @@ <#import "/templates/options.adoc" as opts> -<#macro guide title summary priority=999 includedOptions="" preview="" tileVisible="true" previewDiscussionLink=""> +<#macro guide title summary priority=999 deniedCategories="" includedOptions="" preview="" tileVisible="true" previewDiscussionLink=""> :guide-id: ${id} :guide-title: ${title} :guide-summary: ${summary} @@ -28,6 +28,6 @@ endif::[] <#if includedOptions?has_content> == Relevant options -<@opts.list options=ctx.options.getOptions(includedOptions) anchor=false> +<@opts.list options=ctx.options.getOptions(includedOptions, deniedCategories) anchor=false> \ No newline at end of file diff --git a/docs/guides/templates/options.adoc b/docs/guides/templates/options.adoc index 9dd410df50..75f8db69c0 100644 --- a/docs/guides/templates/options.adoc +++ b/docs/guides/templates/options.adoc @@ -23,6 +23,10 @@ *Env:* `${option.keyEnv}` -- +<#if option.enabledWhen?has_content> +${option.enabledWhen!} + + <#if option.deprecated?has_content> <#-- Either mark the whole option as deprecated, or just selected values --> <#if !option.deprecated.deprecatedValues?has_content> diff --git a/docs/maven-plugin/src/main/java/org/keycloak/guides/maven/Options.java b/docs/maven-plugin/src/main/java/org/keycloak/guides/maven/Options.java index d8ad1b3287..63c88d58d6 100644 --- a/docs/maven-plugin/src/main/java/org/keycloak/guides/maven/Options.java +++ b/docs/maven-plugin/src/main/java/org/keycloak/guides/maven/Options.java @@ -15,40 +15,54 @@ import org.keycloak.provider.Spi; import org.keycloak.quarkus.runtime.Providers; import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers; +import org.keycloak.utils.StringUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class Options { - private final Map options; + private final Map> options; private final Map>> providerOptions = new LinkedHashMap<>(); - @SuppressWarnings("unchecked") public Options() { - options = PropertyMappers.getMappers().stream() + this.options = new EnumMap<>(OptionCategory.class); + PropertyMappers.getMappers().stream() .filter(m -> !m.isHidden()) .filter(propertyMapper -> Objects.nonNull(propertyMapper.getDescription())) - .map(m -> new Option(m.getFrom(), m.getCategory(), m.isBuildTime(), null, m.getDescription(), (String) m.getDefaultValue().map(Object::toString).orElse(null), m.getExpectedValues(), (DeprecatedMetadata) m.getDeprecatedMetadata().orElse(null))) - .sorted(Comparator.comparing(Option::getKey)) - .collect(Collectors.toMap(Option::getKey, o -> o, (o1, o2) -> o1, LinkedHashMap::new)); // Need to ignore duplicate keys?? + .map(m -> new Option(m.getFrom(), + m.getCategory(), + m.isBuildTime(), + null, + m.getDescription(), + m.getDefaultValue().map(Object::toString).orElse(null), + m.getExpectedValues(), + m.getEnabledWhen().orElse(""), + m.getDeprecatedMetadata().orElse(null))) + .forEach(o -> options.computeIfAbsent(o.category, k -> new TreeSet<>(Comparator.comparing(Option::getKey))).add(o)); + ProviderManager providerManager = Providers.getProviderManager(Thread.currentThread().getContextClassLoader()); - options.forEach((s, option) -> { - option.description = option.description.replaceAll("'([^ ]*)'", "`$1`"); - }); + options.values() + .stream() + .flatMap(Collection::stream) + .forEach(option -> option.description = option.description.replaceAll("'([^ ]*)'", "`$1`")); - for (Spi loadSpi : providerManager.loadSpis().stream().sorted(Comparator.comparing(Spi::getName)).collect(Collectors.toList())) { - for (ProviderFactory providerFactory : providerManager.load(loadSpi).stream().sorted(Comparator.comparing(ProviderFactory::getId)).collect(Collectors.toList())) { + for (Spi loadSpi : providerManager.loadSpis().stream().sorted(Comparator.comparing(Spi::getName)).toList()) { + for (ProviderFactory providerFactory : providerManager.load(loadSpi).stream().sorted(Comparator.comparing(ProviderFactory::getId)).toList()) { List configMetadata = providerFactory.getConfigMetadata(); if (configMetadata == null) { @@ -62,6 +76,7 @@ public class Options { m.getHelpText(), m.getDefaultValue() == null ? null : m.getDefaultValue().toString(), m.getOptions() == null ? Collections.emptyList() : m.getOptions(), + "", null)) .sorted(Comparator.comparing(Option::getKey)).collect(Collectors.toList()); @@ -88,39 +103,84 @@ public class Options { .collect(Collectors.toList()); } - public Collection