use of io.micronaut.aot.core.AOTContext in project micronaut-aot by micronaut-projects.
the class AbstractStaticServiceLoaderSourceGenerator method generate.
@Override
public void generate(@NonNull AOTContext context) {
this.context = context;
if (serviceNames == null) {
serviceNames = context.getConfiguration().stringList(findOption(this.getClass(), SERVICE_TYPES).key());
}
if (substitutions == null) {
Set<String> resourceNames = new LinkedHashSet<>();
resourceNames.add("application");
context.getAnalyzer().getEnvironmentNames().stream().map(env -> "application-" + env).forEach(resourceNames::add);
context.getConfiguration().stringList(Environments.POSSIBLE_ENVIRONMENTS_NAMES).stream().filter(env -> !"default".equals(env)).map(env -> "application-" + env).forEach(resourceNames::add);
substitutions = new HashMap<>();
if (context.getConfiguration().isFeatureEnabled(YamlPropertySourceGenerator.ID)) {
YamlPropertySourceGenerator yaml = new YamlPropertySourceGenerator(resourceNames);
yaml.generate(context);
if (MetadataUtils.isEnabledOn(context.getRuntime(), yaml)) {
LOGGER.debug("Substituting {} with {}", PropertySourceLoader.class.getName(), yaml.getClass().getName());
substitutions.put(YamlPropertySourceLoader.class.getName(), yaml);
}
}
}
if (metadataProviderPredicate == null) {
metadataProviderPredicate = context.getAnalyzer().getAnnotationMetadataPredicate();
}
if (rejectedClasses == null) {
List<String> strings = context.getConfiguration().stringList(findOption(this.getClass(), REJECTED_CLASSES).key());
Set<String> rejected = strings.isEmpty() ? Collections.emptySet() : new HashSet<>(strings);
rejectedClasses = rejected::contains;
}
if (forceInclude == null) {
forceInclude = new HashSet<>(context.getConfiguration().stringList(findOption(this.getClass(), FORCE_INCLUDE).key()));
}
for (String serviceName : serviceNames) {
LOGGER.debug("Processing service type {}", serviceName);
collectServiceImplementations(serviceName);
}
context.put(Substitutes.class, substitutes);
for (BeanConfiguration beanConfiguration : disabledConfigurations) {
for (List<Class<?>> classList : serviceClasses.values()) {
for (Class<?> clazz : classList) {
if (beanConfiguration.isWithin(clazz)) {
context.addDiagnostics(SERVICE_LOADING_CATEGORY, "Disabling " + clazz.getName() + " because it belongs to " + beanConfiguration.getName() + " which is disabled (" + beanConfiguration.getClass() + ")");
disabledServices.add(clazz);
}
}
}
}
generateServiceLoader();
LOGGER.debug("Generated static service loader classes: {}", staticServiceClasses.keySet());
LOGGER.debug("Generated static {} service loader substitutions", substitutes.values().size());
staticServiceClasses.values().stream().map(context::javaFile).forEach(context::registerGeneratedSourceFile);
context.registerStaticOptimization("StaticServicesLoader", SoftServiceLoader.Optimizations.class, this::buildOptimization);
}
use of io.micronaut.aot.core.AOTContext in project micronaut-aot by micronaut-projects.
the class EnvironmentPropertiesSourceGenerator method generate.
@Override
public void generate(@NonNull AOTContext context) {
context.registerStaticOptimization("EnvironmentPropertiesOptimizationLoader", EnvironmentProperties.class, initializer -> {
EnvironmentProperties props = EnvironmentProperties.empty();
env.keySet().forEach(props::findPropertyNamesForEnvironmentVariable);
initializer.addStatement("$T env = new $T()", ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class), ParameterizedTypeName.get(List.class, String.class)), ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(String.class), ParameterizedTypeName.get(List.class, String.class)));
for (Map.Entry<String, List<String>> entry : props.asMap().entrySet()) {
String values = entry.getValue().stream().map(e -> "\"" + e + "\"").collect(Collectors.joining(", "));
initializer.addStatement("env.put($S, $T.asList($L))", entry.getKey(), Arrays.class, values);
}
initializer.addStatement("return $T.of(env)", EnvironmentProperties.class);
});
}
use of io.micronaut.aot.core.AOTContext in project micronaut-aot by micronaut-projects.
the class AbstractStaticServiceLoaderSourceGenerator method collectServiceImplementations.
private void collectServiceImplementations(String serviceName) {
context.addDiagnostics(SERVICE_LOADING_CATEGORY, "Starting service discovery for type " + serviceName);
ClassLoader cl = this.getClass().getClassLoader();
Set<String> seen = Collections.synchronizedSet(new HashSet<>());
SoftServiceLoader.ServiceCollector<Class<?>> availableClasses = SoftServiceLoader.newCollector(serviceName, s -> !s.isEmpty(), cl, className -> {
if (rejectedClasses.test(className) || !seen.add(className)) {
return null;
}
AbstractCodeGenerator substitution = substitutions.get(className);
if (substitution != null) {
List<JavaFile> javaFiles = new ArrayList<>();
AOTContext tracker = new DelegatingSourceGenerationContext(context) {
@Override
public void registerGeneratedSourceFile(@NonNull JavaFile javaFile) {
super.registerGeneratedSourceFile(javaFile);
javaFiles.add(javaFile);
}
};
substitution.generate(tracker);
javaFiles.forEach(substitute -> substitutes.computeIfAbsent(serviceName, k -> new ArrayList<>()).add(substitute));
if (!javaFiles.isEmpty()) {
return null;
}
}
Class<?> clazz;
try {
clazz = cl.loadClass(className);
DeepAnalyzer deepAnalyzer = deepAnalyzerFor(clazz, serviceName);
boolean available = deepAnalyzer.isAvailable(clazz);
if (!available && forceInclude.contains(className)) {
context.addDiagnostics(SERVICE_LOADING_CATEGORY, "Forcing inclusion of " + clazz + " despite it not matching bean requirements");
available = true;
}
if (!available) {
if (BeanConfiguration.class.isAssignableFrom(clazz)) {
disabledConfigurations.add((BeanConfiguration) clazz.getConstructor().newInstance());
}
context.addDiagnostics(SERVICE_LOADING_CATEGORY, "Skipping " + clazz + " because it doesn't match bean requirements");
return null;
}
} catch (ClassNotFoundException | NoClassDefFoundError | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
context.addDiagnostics(SERVICE_LOADING_CATEGORY, "Skipping service " + serviceName + " implementation " + className + " because of missing dependencies: " + e.getMessage());
return null;
}
return clazz;
});
List<Class<?>> serviceClasses = new ArrayList<>();
availableClasses.collect(serviceClasses::add);
this.serviceClasses.put(serviceName, serviceClasses);
}
use of io.micronaut.aot.core.AOTContext in project micronaut-aot by micronaut-projects.
the class ConstantPropertySourcesSourceGenerator method generate.
@Override
public void generate(@NonNull AOTContext context) {
Optional<AbstractStaticServiceLoaderSourceGenerator.Substitutes> maybeSubstitutes = context.get(AbstractStaticServiceLoaderSourceGenerator.Substitutes.class);
List<String> substitutes = maybeSubstitutes.map(s -> s.findSubstitutesFor("io.micronaut.context.env.PropertySourceLoader")).orElse(Collections.emptyList()).stream().map(javaFile -> javaFile.packageName + "." + javaFile.typeSpec.name).collect(Collectors.toList());
context.registerStaticOptimization("AotConstantPropertySources", ConstantPropertySources.class, initializer -> {
EnvironmentProperties env = EnvironmentProperties.empty();
CachedEnvironment.getenv().keySet().forEach(env::findPropertyNamesForEnvironmentVariable);
initializer.addStatement("$T propertySources = new $T()", ParameterizedTypeName.get(ClassName.get(List.class), ClassName.get(PropertySource.class)), ParameterizedTypeName.get(ClassName.get(ArrayList.class), ClassName.get(PropertySource.class)));
for (String substitute : substitutes) {
initializer.addStatement("propertySources.add(new $T())", ClassName.bestGuess(substitute));
}
initializer.addStatement("return new $T(propertySources)", ConstantPropertySources.class);
});
}
Aggregations