use of io.smallrye.config.KeyMapBackedConfigSource in project quarkus by quarkusio.
the class ExtensionLoader method loadStepsFrom.
/**
* Load all the build steps from the given class loader.
*
* @param classLoader the class loader
* @param buildSystemProps the build system properties to use
* @param launchMode launch mode
* @param configCustomizer configuration customizer
* @return a consumer which adds the steps to the given chain builder
* @throws IOException if the class loader could not load a resource
* @throws ClassNotFoundException if a build step class is not found
*/
public static Consumer<BuildChainBuilder> loadStepsFrom(ClassLoader classLoader, Properties buildSystemProps, ApplicationModel appModel, LaunchMode launchMode, DevModeType devModeType) throws IOException, ClassNotFoundException {
// populate with all known types
List<Class<?>> roots = new ArrayList<>();
for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {
final ConfigRoot annotation = clazz.getAnnotation(ConfigRoot.class);
if (annotation == null) {
cfgLog.warnf("Ignoring configuration root %s because it has no annotation", clazz);
} else {
roots.add(clazz);
}
}
final BuildTimeConfigurationReader reader = new BuildTimeConfigurationReader(roots);
// now prepare & load the build configuration
final SmallRyeConfigBuilder builder = ConfigUtils.configBuilder(false, launchMode);
final DefaultValuesConfigurationSource ds1 = new DefaultValuesConfigurationSource(reader.getBuildTimePatternMap());
final DefaultValuesConfigurationSource ds2 = new DefaultValuesConfigurationSource(reader.getBuildTimeRunTimePatternMap());
final PropertiesConfigSource pcs = new PropertiesConfigSource(buildSystemProps, "Build system");
final Map<String, String> platformProperties = appModel.getPlatformProperties();
if (platformProperties.isEmpty()) {
builder.withSources(ds1, ds2, pcs);
} else {
final KeyMap<String> props = new KeyMap<>(platformProperties.size());
for (Map.Entry<String, String> prop : platformProperties.entrySet()) {
props.findOrAdd(new NameIterator(prop.getKey())).putRootValue(prop.getValue());
}
final KeyMapBackedConfigSource platformConfigSource = new KeyMapBackedConfigSource("Quarkus platform", // (see io.quarkus.deployment.configuration.DefaultValuesConfigurationSource)
Integer.MIN_VALUE + 1000, props);
builder.withSources(ds1, ds2, platformConfigSource, pcs);
}
for (ConfigClassWithPrefix mapping : reader.getBuildTimeVisibleMappings()) {
builder.withMapping(mapping.getKlass(), mapping.getPrefix());
}
final SmallRyeConfig src = builder.build();
// install globally
QuarkusConfigFactory.setConfig(src);
final ConfigProviderResolver cpr = ConfigProviderResolver.instance();
try {
cpr.releaseConfig(cpr.getConfig());
} catch (IllegalStateException ignored) {
// just means no config was installed, which is fine
}
final BuildTimeConfigurationReader.ReadResult readResult = reader.readConfiguration(src);
final BooleanSupplierFactoryBuildItem bsf = new BooleanSupplierFactoryBuildItem(readResult, launchMode, devModeType);
Consumer<BuildChainBuilder> result = Functions.discardingConsumer();
// BooleanSupplier factory
result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
bc.produce(bsf);
}).produces(BooleanSupplierFactoryBuildItem.class).build());
// the proxy objects used for run time config in the recorders
Map<Class<?>, Object> proxies = new HashMap<>();
for (Class<?> clazz : ServiceUtil.classesNamedIn(classLoader, "META-INF/quarkus-build-steps.list")) {
try {
result = result.andThen(ExtensionLoader.loadStepsFromClass(clazz, readResult, proxies, bsf));
} catch (Throwable e) {
throw new RuntimeException("Failed to load steps from " + clazz, e);
}
}
// this has to be an identity hash map else the recorder will get angry
Map<Object, FieldDescriptor> rootFields = new IdentityHashMap<>();
Map<Object, ConfigClassWithPrefix> mappingClasses = new IdentityHashMap<>();
for (Map.Entry<Class<?>, Object> entry : proxies.entrySet()) {
// ConfigRoot
RootDefinition root = readResult.getAllRootsByClass().get(entry.getKey());
if (root != null) {
rootFields.put(entry.getValue(), root.getDescriptor());
continue;
}
// ConfigMapping
ConfigClassWithPrefix mapping = readResult.getAllMappings().get(entry.getKey());
if (mapping != null) {
mappingClasses.put(entry.getValue(), mapping);
continue;
}
throw new IllegalStateException("No config found for " + entry.getKey());
}
result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
bc.produce(new ConfigurationBuildItem(readResult));
bc.produce(new RunTimeConfigurationProxyBuildItem(proxies));
ObjectLoader rootLoader = new ObjectLoader() {
public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
return body.readStaticField(rootFields.get(obj));
}
public boolean canHandleObject(final Object obj, final boolean staticInit) {
return rootFields.containsKey(obj);
}
};
ObjectLoader mappingLoader = new ObjectLoader() {
@Override
public ResultHandle load(final BytecodeCreator body, final Object obj, final boolean staticInit) {
ConfigClassWithPrefix mapping = mappingClasses.get(obj);
MethodDescriptor getConfig = MethodDescriptor.ofMethod(ConfigProvider.class, "getConfig", Config.class);
ResultHandle config = body.invokeStaticMethod(getConfig);
MethodDescriptor getMapping = MethodDescriptor.ofMethod(SmallRyeConfig.class, "getConfigMapping", Object.class, Class.class, String.class);
return body.invokeVirtualMethod(getMapping, config, body.loadClass(mapping.getKlass()), body.load(mapping.getPrefix()));
}
@Override
public boolean canHandleObject(final Object obj, final boolean staticInit) {
return mappingClasses.containsKey(obj);
}
};
bc.produce(new BytecodeRecorderObjectLoaderBuildItem(rootLoader));
bc.produce(new BytecodeRecorderObjectLoaderBuildItem(mappingLoader));
}).produces(ConfigurationBuildItem.class).produces(RunTimeConfigurationProxyBuildItem.class).produces(BytecodeRecorderObjectLoaderBuildItem.class).build());
return result;
}
Aggregations