Search in sources :

Example 1 with AOTContext

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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Environments(io.micronaut.aot.core.Environments) AnnotationMetadataProvider(io.micronaut.core.annotation.AnnotationMetadataProvider) LoggerFactory(org.slf4j.LoggerFactory) ClassName(com.squareup.javapoet.ClassName) WildcardTypeName(com.squareup.javapoet.WildcardTypeName) HashMap(java.util.HashMap) DelegatingSourceGenerationContext(io.micronaut.aot.core.codegen.DelegatingSourceGenerationContext) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SoftServiceLoader(io.micronaut.core.io.service.SoftServiceLoader) Map(java.util.Map) MetadataUtils(io.micronaut.aot.core.config.MetadataUtils) CodeBlock(com.squareup.javapoet.CodeBlock) LinkedHashSet(java.util.LinkedHashSet) Logger(org.slf4j.Logger) PropertySourceLoader(io.micronaut.context.env.PropertySourceLoader) Predicate(java.util.function.Predicate) Collection(java.util.Collection) PUBLIC(javax.lang.model.element.Modifier.PUBLIC) Set(java.util.Set) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeSpec(com.squareup.javapoet.TypeSpec) AbstractCodeGenerator(io.micronaut.aot.core.codegen.AbstractCodeGenerator) BeanConfiguration(io.micronaut.inject.BeanConfiguration) MetadataUtils.findOption(io.micronaut.aot.core.config.MetadataUtils.findOption) InvocationTargetException(java.lang.reflect.InvocationTargetException) JavaFile(com.squareup.javapoet.JavaFile) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) Stream(java.util.stream.Stream) YamlPropertySourceLoader(io.micronaut.context.env.yaml.YamlPropertySourceLoader) Generated(io.micronaut.core.annotation.Generated) AOTContext(io.micronaut.aot.core.AOTContext) Collections(java.util.Collections) PropertySourceLoader(io.micronaut.context.env.PropertySourceLoader) YamlPropertySourceLoader(io.micronaut.context.env.yaml.YamlPropertySourceLoader) SoftServiceLoader(io.micronaut.core.io.service.SoftServiceLoader) YamlPropertySourceLoader(io.micronaut.context.env.yaml.YamlPropertySourceLoader) BeanConfiguration(io.micronaut.inject.BeanConfiguration)

Example 2 with AOTContext

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);
    });
}
Also used : CachedEnvironment(io.micronaut.context.env.CachedEnvironment) Arrays(java.util.Arrays) AOTModule(io.micronaut.aot.core.AOTModule) ClassName(com.squareup.javapoet.ClassName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) HashMap(java.util.HashMap) AbstractCodeGenerator(io.micronaut.aot.core.codegen.AbstractCodeGenerator) Collectors(java.util.stream.Collectors) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) EnvironmentProperties(io.micronaut.core.util.EnvironmentProperties) Map(java.util.Map) AOTContext(io.micronaut.aot.core.AOTContext) EnvironmentProperties(io.micronaut.core.util.EnvironmentProperties) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with AOTContext

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);
}
Also used : SoftServiceLoader(io.micronaut.core.io.service.SoftServiceLoader) ArrayList(java.util.ArrayList) NonNull(io.micronaut.core.annotation.NonNull) AbstractCodeGenerator(io.micronaut.aot.core.codegen.AbstractCodeGenerator) DelegatingSourceGenerationContext(io.micronaut.aot.core.codegen.DelegatingSourceGenerationContext) InvocationTargetException(java.lang.reflect.InvocationTargetException) JavaFile(com.squareup.javapoet.JavaFile) AOTContext(io.micronaut.aot.core.AOTContext)

Example 4 with AOTContext

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);
    });
}
Also used : CachedEnvironment(io.micronaut.context.env.CachedEnvironment) PropertySource(io.micronaut.context.env.PropertySource) AOTModule(io.micronaut.aot.core.AOTModule) ClassName(com.squareup.javapoet.ClassName) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) AbstractCodeGenerator(io.micronaut.aot.core.codegen.AbstractCodeGenerator) Collectors(java.util.stream.Collectors) ConstantPropertySources(io.micronaut.context.env.ConstantPropertySources) ArrayList(java.util.ArrayList) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) EnvironmentProperties(io.micronaut.core.util.EnvironmentProperties) Optional(java.util.Optional) AOTContext(io.micronaut.aot.core.AOTContext) Collections(java.util.Collections) EnvironmentProperties(io.micronaut.core.util.EnvironmentProperties)

Aggregations

AOTContext (io.micronaut.aot.core.AOTContext)4 AbstractCodeGenerator (io.micronaut.aot.core.codegen.AbstractCodeGenerator)4 NonNull (io.micronaut.core.annotation.NonNull)4 ClassName (com.squareup.javapoet.ClassName)3 ParameterizedTypeName (com.squareup.javapoet.ParameterizedTypeName)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 JavaFile (com.squareup.javapoet.JavaFile)2 AOTModule (io.micronaut.aot.core.AOTModule)2 DelegatingSourceGenerationContext (io.micronaut.aot.core.codegen.DelegatingSourceGenerationContext)2 CachedEnvironment (io.micronaut.context.env.CachedEnvironment)2 SoftServiceLoader (io.micronaut.core.io.service.SoftServiceLoader)2 EnvironmentProperties (io.micronaut.core.util.EnvironmentProperties)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Collectors (java.util.stream.Collectors)2 CodeBlock (com.squareup.javapoet.CodeBlock)1 TypeSpec (com.squareup.javapoet.TypeSpec)1