Search in sources :

Example 1 with CatchBlockCreator

use of io.quarkus.gizmo.CatchBlockCreator in project camel-quarkus by apache.

the class XalanNativeImageProcessor method installTransformerFactory.

@BuildStep
void installTransformerFactory(BuildProducer<GeneratedNativeImageClassBuildItem> nativeImageClass, BuildProducer<GeneratedResourceBuildItem> generatedResources) {
    final String serviceProviderFileContent = XalanTransformerFactory.class.getName() + "\n";
    /* This is primarily for the JVM mode */
    generatedResources.produce(new GeneratedResourceBuildItem(TRANSFORMER_FACTORY_SERVICE_FILE_PATH, serviceProviderFileContent.getBytes(StandardCharsets.UTF_8)));
    /* A low level way to embed only our service file in the native image.
         * There are at least two META-INF/services/javax.xml.transform.TransformerFactory files
         * in the class path: ours and the one from xalan.jar. As of GraalVM 19.3.1-java8, 19.3.1-java11,
         * 20.0.0-java8 and 20.0.0-java11, there is no way to ensure that ServiceProviderBuildItem
         * or NativeImageResourceBuildItem will pick the service file preferred by us.
         * We are thus forced to use this low level mechanism to ensure that.
         */
    final ClassCreator file = new ClassCreator(new ClassOutput() {

        @Override
        public void write(String s, byte[] bytes) {
            nativeImageClass.produce(new GeneratedNativeImageClassBuildItem(s, bytes));
        }
    }, getClass().getName() + "AutoFeature", null, Object.class.getName(), Feature.class.getName());
    file.addAnnotation("com.oracle.svm.core.annotate.AutomaticFeature");
    final MethodCreator beforeAn = file.getMethodCreator("beforeAnalysis", "V", Feature.BeforeAnalysisAccess.class.getName());
    final TryBlock overallCatch = beforeAn.tryBlock();
    overallCatch.invokeStaticMethod(ofMethod(ResourceUtils.class, "registerResources", void.class, String.class, String.class), overallCatch.load(TRANSFORMER_FACTORY_SERVICE_FILE_PATH), overallCatch.load(serviceProviderFileContent));
    final CatchBlockCreator print = overallCatch.addCatch(Throwable.class);
    print.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), print.getCaughtException());
    beforeAn.returnValue(null);
    file.close();
}
Also used : GeneratedResourceBuildItem(io.quarkus.deployment.builditem.GeneratedResourceBuildItem) GeneratedNativeImageClassBuildItem(io.quarkus.deployment.builditem.GeneratedNativeImageClassBuildItem) TryBlock(io.quarkus.gizmo.TryBlock) ClassCreator(io.quarkus.gizmo.ClassCreator) Feature(org.graalvm.nativeimage.hosted.Feature) MethodCreator(io.quarkus.gizmo.MethodCreator) ResourceUtils(org.apache.camel.quarkus.core.graal.ResourceUtils) ClassOutput(io.quarkus.gizmo.ClassOutput) XalanTransformerFactory(org.apache.camel.quarkus.support.xalan.XalanTransformerFactory) CatchBlockCreator(io.quarkus.gizmo.CatchBlockCreator) BuildStep(io.quarkus.deployment.annotations.BuildStep)

Example 2 with CatchBlockCreator

use of io.quarkus.gizmo.CatchBlockCreator in project quarkus-github-app by quarkiverse.

the class GitHubAppProcessor method generateDispatcher.

/**
 * The role of the dispatcher is to receive the CDI events emitted by the reactive route.
 * <p>
 * It parses the raw payload into the appropriate {@link GHEventPayload} and then emit
 * an async CDI event with a MultiplexedEvent containing the payload instance,
 * the GitHub instance and the DynamicGraphQLClient instance if needed.
 * <p>
 * It only generates code for the GitHub events actually listened to by the application.
 */
private static void generateDispatcher(ClassOutput beanClassOutput, CombinedIndexBuildItem combinedIndex, LaunchModeBuildItem launchMode, DispatchingConfiguration dispatchingConfiguration, BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
    String dispatcherClassName = GitHubEvent.class.getName() + "DispatcherImpl";
    reflectiveClasses.produce(new ReflectiveClassBuildItem(true, true, dispatcherClassName));
    ClassCreator dispatcherClassCreator = ClassCreator.builder().classOutput(beanClassOutput).className(dispatcherClassName).build();
    dispatcherClassCreator.addAnnotation(Singleton.class);
    FieldCreator eventFieldCreator = dispatcherClassCreator.getFieldCreator(EVENT_EMITTER_FIELD, Event.class);
    eventFieldCreator.addAnnotation(Inject.class);
    eventFieldCreator.setModifiers(Modifier.PROTECTED);
    FieldCreator gitHubServiceFieldCreator = dispatcherClassCreator.getFieldCreator(GITHUB_SERVICE_FIELD, GitHubService.class);
    gitHubServiceFieldCreator.addAnnotation(Inject.class);
    gitHubServiceFieldCreator.setModifiers(Modifier.PROTECTED);
    MethodCreator dispatchMethodCreator = dispatcherClassCreator.getMethodCreator("dispatch", void.class, GitHubEvent.class);
    dispatchMethodCreator.setModifiers(Modifier.PUBLIC);
    dispatchMethodCreator.getParameterAnnotations(0).addAnnotation(DotNames.OBSERVES.toString());
    ResultHandle gitHubEventRh = dispatchMethodCreator.getMethodParam(0);
    ResultHandle installationIdRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getInstallationId", Long.class), gitHubEventRh);
    ResultHandle dispatchedEventRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getEvent", String.class), gitHubEventRh);
    ResultHandle dispatchedActionRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getAction", String.class), gitHubEventRh);
    ResultHandle dispatchedPayloadRh = dispatchMethodCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubEvent.class, "getPayload", String.class), gitHubEventRh);
    TryBlock tryBlock = dispatchMethodCreator.tryBlock();
    ResultHandle gitHubRh = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubService.class, "getInstallationClient", GitHub.class, Long.class), tryBlock.readInstanceField(FieldDescriptor.of(dispatcherClassCreator.getClassName(), GITHUB_SERVICE_FIELD, GitHubService.class), tryBlock.getThis()), installationIdRh);
    ResultHandle gitHubGraphQLClientRh = tryBlock.loadNull();
    if (dispatchingConfiguration.requiresGraphQLClient()) {
        gitHubGraphQLClientRh = tryBlock.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHubService.class, "getInstallationGraphQLClient", DynamicGraphQLClient.class, Long.class), tryBlock.readInstanceField(FieldDescriptor.of(dispatcherClassCreator.getClassName(), GITHUB_SERVICE_FIELD, GitHubService.class), tryBlock.getThis()), installationIdRh);
    }
    for (EventDispatchingConfiguration eventDispatchingConfiguration : dispatchingConfiguration.getEventConfigurations().values()) {
        ResultHandle eventRh = tryBlock.load(eventDispatchingConfiguration.getEvent());
        String payloadType = eventDispatchingConfiguration.getPayloadType();
        BytecodeCreator eventMatchesCreator = tryBlock.ifTrue(tryBlock.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, eventRh, dispatchedEventRh)).trueBranch();
        ResultHandle payloadInstanceRh = eventMatchesCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(GitHub.class, "parseEventPayload", GHEventPayload.class, Reader.class, Class.class), gitHubRh, eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(StringReader.class, String.class), dispatchedPayloadRh), eventMatchesCreator.loadClass(payloadType));
        ResultHandle multiplexedEventRh = eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(MultiplexedEvent.class, GHEventPayload.class, GitHub.class, DynamicGraphQLClient.class), payloadInstanceRh, gitHubRh, gitHubGraphQLClientRh);
        for (Entry<String, EventAnnotation> eventAnnotationEntry : eventDispatchingConfiguration.getEventAnnotations().entrySet()) {
            String action = eventAnnotationEntry.getKey();
            EventAnnotation eventAnnotation = eventAnnotationEntry.getValue();
            Class<?>[] literalParameterTypes = new Class<?>[eventAnnotation.getValues().size()];
            Arrays.fill(literalParameterTypes, String.class);
            List<ResultHandle> literalParameters = new ArrayList<>();
            ResultHandle annotationLiteralRh = eventMatchesCreator.newInstance(MethodDescriptor.ofConstructor(getLiteralClassName(eventAnnotation.getName()), (Object[]) literalParameterTypes), literalParameters.toArray(ResultHandle[]::new));
            ResultHandle annotationLiteralArrayRh = eventMatchesCreator.newArray(Annotation.class, 1);
            eventMatchesCreator.writeArrayValue(annotationLiteralArrayRh, 0, annotationLiteralRh);
            if (Actions.ALL.equals(action)) {
                fireAsyncAction(eventMatchesCreator, launchMode.getLaunchMode(), dispatcherClassCreator.getClassName(), gitHubEventRh, multiplexedEventRh, annotationLiteralArrayRh);
            } else {
                BytecodeCreator actionMatchesCreator = eventMatchesCreator.ifTrue(eventMatchesCreator.invokeVirtualMethod(MethodDescriptors.OBJECT_EQUALS, eventMatchesCreator.load(action), dispatchedActionRh)).trueBranch();
                fireAsyncAction(actionMatchesCreator, launchMode.getLaunchMode(), dispatcherClassCreator.getClassName(), gitHubEventRh, multiplexedEventRh, annotationLiteralArrayRh);
            }
        }
    }
    CatchBlockCreator catchBlockCreator = tryBlock.addCatch(Throwable.class);
    catchBlockCreator.invokeVirtualMethod(MethodDescriptor.ofMethod(ErrorHandlerBridgeFunction.class, "apply", Void.class, Throwable.class), catchBlockCreator.newInstance(MethodDescriptor.ofConstructor(ErrorHandlerBridgeFunction.class, GitHubEvent.class), gitHubEventRh), catchBlockCreator.getCaughtException());
    dispatchMethodCreator.returnValue(null);
    dispatcherClassCreator.close();
}
Also used : GitHub(org.kohsuke.github.GitHub) FieldCreator(io.quarkus.gizmo.FieldCreator) ArrayList(java.util.ArrayList) Reader(java.io.Reader) ConfigFileReader(io.quarkiverse.githubapp.runtime.ConfigFileReader) StringReader(java.io.StringReader) TryBlock(io.quarkus.gizmo.TryBlock) ClassCreator(io.quarkus.gizmo.ClassCreator) ErrorHandlerBridgeFunction(io.quarkiverse.githubapp.runtime.error.ErrorHandlerBridgeFunction) ResultHandle(io.quarkus.gizmo.ResultHandle) GitHubService(io.quarkiverse.githubapp.runtime.github.GitHubService) BytecodeCreator(io.quarkus.gizmo.BytecodeCreator) GitHubEvent(io.quarkiverse.githubapp.GitHubEvent) EventAnnotation(io.quarkiverse.githubapp.deployment.DispatchingConfiguration.EventAnnotation) GHEventPayload(org.kohsuke.github.GHEventPayload) MethodCreator(io.quarkus.gizmo.MethodCreator) EventDispatchingConfiguration(io.quarkiverse.githubapp.deployment.DispatchingConfiguration.EventDispatchingConfiguration) MultiplexedEvent(io.quarkiverse.githubapp.runtime.MultiplexedEvent) CatchBlockCreator(io.quarkus.gizmo.CatchBlockCreator) DynamicGraphQLClient(io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient) ReflectiveClassBuildItem(io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem)

Aggregations

CatchBlockCreator (io.quarkus.gizmo.CatchBlockCreator)2 ClassCreator (io.quarkus.gizmo.ClassCreator)2 MethodCreator (io.quarkus.gizmo.MethodCreator)2 TryBlock (io.quarkus.gizmo.TryBlock)2 GitHubEvent (io.quarkiverse.githubapp.GitHubEvent)1 EventAnnotation (io.quarkiverse.githubapp.deployment.DispatchingConfiguration.EventAnnotation)1 EventDispatchingConfiguration (io.quarkiverse.githubapp.deployment.DispatchingConfiguration.EventDispatchingConfiguration)1 ConfigFileReader (io.quarkiverse.githubapp.runtime.ConfigFileReader)1 MultiplexedEvent (io.quarkiverse.githubapp.runtime.MultiplexedEvent)1 ErrorHandlerBridgeFunction (io.quarkiverse.githubapp.runtime.error.ErrorHandlerBridgeFunction)1 GitHubService (io.quarkiverse.githubapp.runtime.github.GitHubService)1 BuildStep (io.quarkus.deployment.annotations.BuildStep)1 GeneratedNativeImageClassBuildItem (io.quarkus.deployment.builditem.GeneratedNativeImageClassBuildItem)1 GeneratedResourceBuildItem (io.quarkus.deployment.builditem.GeneratedResourceBuildItem)1 ReflectiveClassBuildItem (io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem)1 BytecodeCreator (io.quarkus.gizmo.BytecodeCreator)1 ClassOutput (io.quarkus.gizmo.ClassOutput)1 FieldCreator (io.quarkus.gizmo.FieldCreator)1 ResultHandle (io.quarkus.gizmo.ResultHandle)1 DynamicGraphQLClient (io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient)1