void compileCSimpleExpressions()

in extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleProcessor.java [108:190]


    void compileCSimpleExpressions(
            BuildSystemTargetBuildItem buildSystemTargetBuildItem,
            List<CSimpleExpressionSourceBuildItem> expressionSources,
            BuildProducer<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpression,
            BuildProducer<GeneratedClassBuildItem> generatedClasses) throws IOException {

        if (!expressionSources.isEmpty()) {
            final Set<String> imports = new TreeSet<>();
            final Map<String, String> aliases = new LinkedHashMap<>();
            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
            if (!(loader instanceof QuarkusClassLoader)) {
                throw new IllegalStateException(
                        QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
            }
            final QuarkusClassLoader quarkusClassLoader = (QuarkusClassLoader) loader;
            readConfig(imports, aliases, loader);
            final CSimpleCodeGenerator generator = new CSimpleCodeGenerator();
            generator.setAliases(aliases);
            generator.setImports(imports);

            final Path projectDir = Paths.get(".").toAbsolutePath().normalize();
            final Path outputDirectory = buildSystemTargetBuildItem.getOutputDirectory();
            final Path csimpleGeneratedSourceDir = outputDirectory.resolve("generated/csimple");
            Files.createDirectories(csimpleGeneratedSourceDir);

            final Set<File> filesToCompile = new LinkedHashSet<>();

            /* We do not want to compile the same source twice, so we store here what we have compiled already */
            final Map<Boolean, Set<String>> compiledExpressions = new HashMap<>();
            compiledExpressions.put(true, new HashSet<>());
            compiledExpressions.put(false, new HashSet<>());

            /* Generate Java classes for the language expressions */
            for (CSimpleExpressionSourceBuildItem expr : expressionSources) {
                final boolean predicate = expr.isPredicate();
                final String script = expr.getSourceCode();
                if (!compiledExpressions.get(predicate).contains(script)) {
                    final CSimpleGeneratedCode code = predicate
                            ? generator.generatePredicate(expr.getClassNameBase(), script)
                            : generator.generateExpression(expr.getClassNameBase(), script);

                    compiledCSimpleExpression
                            .produce(new CompiledCSimpleExpressionBuildItem(code.getCode(), predicate, code.getFqn()));

                    final Path javaCsimpleFile = csimpleGeneratedSourceDir
                            .resolve(code.getFqn().replace('.', '/') + ".java");
                    Files.createDirectories(javaCsimpleFile.getParent());
                    Files.write(javaCsimpleFile, code.getCode().getBytes(StandardCharsets.UTF_8));
                    filesToCompile.add(javaCsimpleFile.toFile());
                    compiledExpressions.get(predicate).add(script);
                }
            }

            final Path csimpleClassesDir = outputDirectory.resolve("csimple-classes");
            Files.createDirectories(csimpleClassesDir);

            /* Compile the generated sources */
            try (JavaCompilationProvider compiler = new JavaCompilationProvider()) {
                final Context context = compilationContext(projectDir, csimpleClassesDir, quarkusClassLoader);
                compiler.compile(filesToCompile, context);
            }

            /* Register the compiled classes via Quarkus GeneratedClassBuildItem */
            try (Stream<Path> classFiles = Files.walk(csimpleClassesDir)) {
                classFiles
                        .filter(Files::isRegularFile)
                        .filter(p -> p.getFileName().toString().endsWith(CLASS_EXT))
                        .forEach(p -> {
                            final Path relPath = csimpleClassesDir.relativize(p);
                            String className = FileUtils.nixifyPath(relPath.toString());
                            className = className.substring(0, className.length() - CLASS_EXT.length());
                            try {
                                final GeneratedClassBuildItem item = new GeneratedClassBuildItem(true, className,
                                        Files.readAllBytes(p));
                                generatedClasses.produce(item);
                            } catch (IOException e) {
                                throw new RuntimeException("Could not read " + p);
                            }
                        });
            }

        }
    }